Skip to content

Commit f2100aa

Browse files
authored
Merge pull request #3504 from AkihiroSuda/refactor-guestagent
guestagent refactoring
2 parents 34b0e40 + 008aca9 commit f2100aa

File tree

6 files changed

+119
-33
lines changed

6 files changed

+119
-33
lines changed

cmd/limactl/hostagent.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func newHostagentCommand() *cobra.Command {
3232
hostagentCommand.Flags().StringP("pidfile", "p", "", "Write PID to file")
3333
hostagentCommand.Flags().String("socket", "", "Path of hostagent socket")
3434
hostagentCommand.Flags().Bool("run-gui", false, "Run GUI synchronously within hostagent")
35+
hostagentCommand.Flags().String("guestagent", "", "Local file path (not URL) of lima-guestagent.OS-ARCH[.gz]")
3536
hostagentCommand.Flags().String("nerdctl-archive", "", "Local file path (not URL) of nerdctl-full-VERSION-GOOS-GOARCH.tar.gz")
3637
return hostagentCommand
3738
}
@@ -78,6 +79,13 @@ func hostagentAction(cmd *cobra.Command, args []string) error {
7879

7980
initLogrus(stderr)
8081
var opts []hostagent.Opt
82+
guestagentBinary, err := cmd.Flags().GetString("guestagent")
83+
if err != nil {
84+
return err
85+
}
86+
if guestagentBinary != "" {
87+
opts = append(opts, hostagent.WithGuestAgentBinary(guestagentBinary))
88+
}
8189
nerdctlArchive, err := cmd.Flags().GetString("nerdctl-archive")
8290
if err != nil {
8391
return err

pkg/cidata/cidata.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
"github.com/lima-vm/lima/pkg/osutil"
3131
"github.com/lima-vm/lima/pkg/sshutil"
3232
"github.com/lima-vm/lima/pkg/store/filenames"
33-
"github.com/lima-vm/lima/pkg/usrlocalsharelima"
3433
"github.com/sirupsen/logrus"
3534
)
3635

@@ -355,7 +354,7 @@ func GenerateCloudConfig(instDir, name string, instConfig *limayaml.LimaYAML) er
355354
return os.WriteFile(filepath.Join(instDir, filenames.CloudConfig), config, 0o444)
356355
}
357356

358-
func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string, vsockPort int, virtioPort string) error {
357+
func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, guestAgentBinary, nerdctlArchive string, vsockPort int, virtioPort string) error {
359358
args, err := templateArgs(true, instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, vsockPort, virtioPort)
360359
if err != nil {
361360
return err
@@ -391,31 +390,32 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS
391390
}
392391
}
393392

394-
guestAgentBinary, err := usrlocalsharelima.GuestAgentBinary(*instConfig.OS, *instConfig.Arch)
395-
if err != nil {
396-
return err
397-
}
398-
var guestAgent io.ReadCloser
399-
guestAgent, err = os.Open(guestAgentBinary)
400-
if err != nil {
401-
if !errors.Is(err, os.ErrNotExist) {
402-
return err
403-
}
404-
compressedGuestAgent, err := os.Open(guestAgentBinary + ".gz")
405-
if err != nil {
406-
return err
407-
}
408-
logrus.Debugf("Decompressing %s.gz", guestAgentBinary)
409-
guestAgent, err = gzip.NewReader(compressedGuestAgent)
410-
if err != nil {
411-
return err
393+
if guestAgentBinary != "" {
394+
var guestAgent io.ReadCloser
395+
if strings.HasSuffix(guestAgentBinary, ".gz") {
396+
logrus.Debugf("Decompressing %s", guestAgentBinary)
397+
guestAgentGz, err := os.Open(guestAgentBinary)
398+
if err != nil {
399+
return err
400+
}
401+
defer guestAgentGz.Close()
402+
guestAgent, err = gzip.NewReader(guestAgentGz)
403+
if err != nil {
404+
return err
405+
}
406+
} else {
407+
guestAgent, err = os.Open(guestAgentBinary)
408+
if err != nil {
409+
return err
410+
}
412411
}
412+
413+
defer guestAgent.Close()
414+
layout = append(layout, iso9660util.Entry{
415+
Path: "lima-guestagent",
416+
Reader: guestAgent,
417+
})
413418
}
414-
defer guestAgent.Close()
415-
layout = append(layout, iso9660util.Entry{
416-
Path: "lima-guestagent",
417-
Reader: guestAgent,
418-
})
419419

420420
if nerdctlArchive != "" {
421421
nftgz := args.Containerd.Archive

pkg/hostagent/hostagent.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,19 @@ type HostAgent struct {
7575
}
7676

7777
type options struct {
78-
nerdctlArchive string // local path, not URL
78+
guestAgentBinary string
79+
nerdctlArchive string // local path, not URL
7980
}
8081

8182
type Opt func(*options) error
8283

84+
func WithGuestAgentBinary(s string) Opt {
85+
return func(o *options) error {
86+
o.guestAgentBinary = s
87+
return nil
88+
}
89+
}
90+
8391
func WithNerdctlArchive(s string) Opt {
8492
return func(o *options) error {
8593
o.nerdctlArchive = s
@@ -134,7 +142,7 @@ func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt
134142
if err := cidata.GenerateCloudConfig(inst.Dir, instName, inst.Config); err != nil {
135143
return nil, err
136144
}
137-
if err := cidata.GenerateISO9660(inst.Dir, instName, inst.Config, udpDNSLocalPort, tcpDNSLocalPort, o.nerdctlArchive, vSockPort, virtioPort); err != nil {
145+
if err := cidata.GenerateISO9660(inst.Dir, instName, inst.Config, udpDNSLocalPort, tcpDNSLocalPort, o.guestAgentBinary, o.nerdctlArchive, vSockPort, virtioPort); err != nil {
138146
return nil, err
139147
}
140148

pkg/infoutil/infoutil.go

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,29 @@
44
package infoutil
55

66
import (
7+
"errors"
8+
"io/fs"
9+
710
"github.com/lima-vm/lima/pkg/driverutil"
811
"github.com/lima-vm/lima/pkg/limayaml"
912
"github.com/lima-vm/lima/pkg/store/dirnames"
1013
"github.com/lima-vm/lima/pkg/templatestore"
14+
"github.com/lima-vm/lima/pkg/usrlocalsharelima"
1115
"github.com/lima-vm/lima/pkg/version"
16+
"github.com/sirupsen/logrus"
1217
)
1318

1419
type Info struct {
15-
Version string `json:"version"`
16-
Templates []templatestore.Template `json:"templates"`
17-
DefaultTemplate *limayaml.LimaYAML `json:"defaultTemplate"`
18-
LimaHome string `json:"limaHome"`
19-
VMTypes []string `json:"vmTypes"` // since Lima v0.14.2
20+
Version string `json:"version"`
21+
Templates []templatestore.Template `json:"templates"`
22+
DefaultTemplate *limayaml.LimaYAML `json:"defaultTemplate"`
23+
LimaHome string `json:"limaHome"`
24+
VMTypes []string `json:"vmTypes"` // since Lima v0.14.2
25+
GuestAgents map[limayaml.Arch]GuestAgent `json:"guestAgents"` // since Lima v1.1.0
26+
}
27+
28+
type GuestAgent struct {
29+
Location string `json:"location"` // since Lima v1.1.0
2030
}
2131

2232
func GetInfo() (*Info, error) {
@@ -32,6 +42,7 @@ func GetInfo() (*Info, error) {
3242
Version: version.Version,
3343
DefaultTemplate: y,
3444
VMTypes: driverutil.Drivers(),
45+
GuestAgents: make(map[limayaml.Arch]GuestAgent),
3546
}
3647
info.Templates, err = templatestore.Templates()
3748
if err != nil {
@@ -41,5 +52,19 @@ func GetInfo() (*Info, error) {
4152
if err != nil {
4253
return nil, err
4354
}
55+
for _, arch := range limayaml.ArchTypes {
56+
bin, err := usrlocalsharelima.GuestAgentBinary(limayaml.LINUX, arch)
57+
if err != nil {
58+
if errors.Is(err, fs.ErrNotExist) {
59+
logrus.WithError(err).Debugf("Failed to resolve the guest agent binary for %q", arch)
60+
} else {
61+
logrus.WithError(err).Warnf("Failed to resolve the guest agent binary for %q", arch)
62+
}
63+
continue
64+
}
65+
info.GuestAgents[arch] = GuestAgent{
66+
Location: bin,
67+
}
68+
}
4469
return info, nil
4570
}

pkg/instance/start.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/lima-vm/lima/pkg/driverutil"
2121
"github.com/lima-vm/lima/pkg/executil"
2222
"github.com/lima-vm/lima/pkg/osutil"
23+
"github.com/lima-vm/lima/pkg/usrlocalsharelima"
2324
"github.com/mattn/go-isatty"
2425

2526
"github.com/lima-vm/lima/pkg/downloader"
@@ -72,11 +73,20 @@ func ensureNerdctlArchiveCache(ctx context.Context, y *limayaml.LimaYAML, create
7273

7374
type Prepared struct {
7475
Driver driver.Driver
76+
GuestAgent string
7577
NerdctlArchiveCache string
7678
}
7779

7880
// Prepare ensures the disk, the nerdctl archive, etc.
7981
func Prepare(ctx context.Context, inst *store.Instance) (*Prepared, error) {
82+
var guestAgent string
83+
if !*inst.Config.Plain {
84+
var err error
85+
guestAgent, err = usrlocalsharelima.GuestAgentBinary(*inst.Config.OS, *inst.Config.Arch)
86+
if err != nil {
87+
return nil, err
88+
}
89+
}
8090
limaDriver := driverutil.CreateTargetDriverInstance(&driver.BaseDriver{
8191
Instance: inst,
8292
})
@@ -104,6 +114,7 @@ func Prepare(ctx context.Context, inst *store.Instance) (*Prepared, error) {
104114

105115
return &Prepared{
106116
Driver: limaDriver,
117+
GuestAgent: guestAgent,
107118
NerdctlArchiveCache: nerdctlArchiveCache,
108119
}, nil
109120
}
@@ -171,6 +182,9 @@ func Start(ctx context.Context, inst *store.Instance, limactl string, launchHost
171182
if prepared.Driver.CanRunGUI() {
172183
args = append(args, "--run-gui")
173184
}
185+
if prepared.GuestAgent != "" {
186+
args = append(args, "--guestagent", prepared.GuestAgent)
187+
}
174188
if prepared.NerdctlArchiveCache != "" {
175189
args = append(args, "--nerdctl-archive", prepared.NerdctlArchiveCache)
176190
}

pkg/usrlocalsharelima/usrlocalsharelima.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ func Dir() (string, error) {
8080
ostype, arch, self, gaCandidates)
8181
}
8282

83+
// GuestAgentBinary returns the guest agent binary, possibly with ".gz" suffix.
8384
func GuestAgentBinary(ostype limayaml.OS, arch limayaml.Arch) (string, error) {
8485
if ostype == "" {
8586
return "", errors.New("os must be set")
@@ -91,5 +92,35 @@ func GuestAgentBinary(ostype limayaml.OS, arch limayaml.Arch) (string, error) {
9192
if err != nil {
9293
return "", err
9394
}
94-
return filepath.Join(dir, "lima-guestagent."+ostype+"-"+arch), nil
95+
uncomp := filepath.Join(dir, "lima-guestagent."+ostype+"-"+arch)
96+
comp := uncomp + ".gz"
97+
res, err := chooseGABinary([]string{comp, uncomp})
98+
if err != nil {
99+
logrus.Debug(err)
100+
return "", fmt.Errorf("guest agent binary could not be found for %s-%s (Hint: try installing `lima-additional-guestagents` package)", ostype, arch)
101+
}
102+
return res, nil
103+
}
104+
105+
func chooseGABinary(candidates []string) (string, error) {
106+
var entries []string
107+
for _, f := range candidates {
108+
if _, err := os.Stat(f); err != nil {
109+
if !errors.Is(err, fs.ErrNotExist) {
110+
logrus.WithError(err).Warnf("failed to stat %q", f)
111+
}
112+
continue
113+
}
114+
entries = append(entries, f)
115+
}
116+
switch len(entries) {
117+
case 0:
118+
return "", fmt.Errorf("%w: attempted %v", fs.ErrNotExist, candidates)
119+
case 1:
120+
return entries[0], nil
121+
default:
122+
logrus.Warnf("multiple files found, choosing %q from %v; consider removing the other ones",
123+
entries[0], candidates)
124+
return entries[0], nil
125+
}
95126
}

0 commit comments

Comments
 (0)