From 92913054221ec9721a5ec9b63cbedbfc5fda5695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Fri, 24 Nov 2023 08:00:29 +0100 Subject: [PATCH] Add command to install the guest components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will install the lima-guestagent in the instance. It will install nerdctl-full.tgz, if it has been enabled. Signed-off-by: Anders F Björklund --- cmd/limactl/guest_install.go | 106 +++++++++++++++++++++++++++++++++++ cmd/limactl/main.go | 1 + pkg/cacheutil/cacheutil.go | 13 +++++ 3 files changed, 120 insertions(+) create mode 100644 cmd/limactl/guest_install.go diff --git a/cmd/limactl/guest_install.go b/cmd/limactl/guest_install.go new file mode 100644 index 00000000000..f81b585a226 --- /dev/null +++ b/cmd/limactl/guest_install.go @@ -0,0 +1,106 @@ +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + + "github.com/lima-vm/lima/pkg/cacheutil" + "github.com/lima-vm/lima/pkg/store" + "github.com/lima-vm/lima/pkg/store/filenames" + "github.com/lima-vm/lima/pkg/usrlocalsharelima" + + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +func newGuestInstallCommand() *cobra.Command { + guestInstallCommand := &cobra.Command{ + Use: "guest-install INSTANCE", + Short: "Install guest components", + Args: WrapArgsError(cobra.MaximumNArgs(1)), + RunE: guestInstallAction, + ValidArgsFunction: cobra.NoFileCompletions, + Hidden: true, + } + return guestInstallCommand +} + +func runCmd(name string, flags []string, args ...string) error { + cmd := exec.Command(name, append(flags, args...)...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + logrus.Debugf("executing %v", cmd.Args) + return cmd.Run() +} + +func guestInstallAction(cmd *cobra.Command, args []string) error { + instName := DefaultInstanceName + if len(args) > 0 { + instName = args[0] + } + + inst, err := store.Inspect(instName) + if err != nil { + return err + } + if inst.Status == store.StatusStopped { + return fmt.Errorf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName) + } + + sshExe := "ssh" + sshConfig := filepath.Join(inst.Dir, filenames.SSHConfig) + sshFlags := []string{"-F", sshConfig} + + scpExe := "scp" + scpFlags := sshFlags + + y, err := inst.LoadYAML() + if err != nil { + return err + } + + hostname := fmt.Sprintf("lima-%s", inst.Name) + prefix := *y.GuestInstallPrefix + + // lima-guestagent + guestAgentBinary, err := usrlocalsharelima.GuestAgentBinary(*y.OS, *y.Arch) + if err != nil { + return err + } + tmp := "/tmp/lima-guestagent" + bin := prefix + "/bin/lima-guestagent" + logrus.Infof("Copying %q to %s", guestAgentBinary, hostname) + scpArgs := []string{guestAgentBinary, hostname + ":" + tmp} + if err := runCmd(scpExe, scpFlags, scpArgs...); err != nil { + return nil + } + logrus.Infof("Installing %s to %s", tmp, bin) + sshArgs := []string{hostname, "sudo", "install", "-m", "755", tmp, bin} + if err := runCmd(sshExe, sshFlags, sshArgs...); err != nil { + return nil + } + + // nerdctl-full.tgz + nerdctlFilename := cacheutil.NerdctlArchive(y) + if nerdctlFilename != "" { + nerdctlArchive, err := cacheutil.EnsureNerdctlArchiveCache(cmd.Context(), y, false) + if err != nil { + return err + } + tmp := "/tmp/nerdctl-full.tgz" + logrus.Infof("Copying %q to %s", nerdctlFilename, hostname) + scpArgs := []string{nerdctlArchive, hostname + ":" + tmp} + if err := runCmd(scpExe, scpFlags, scpArgs...); err != nil { + return nil + } + logrus.Infof("Installing %s in %s", tmp, prefix) + sshArgs := []string{hostname, "sudo", "tar", "Cxzf", prefix, tmp} + if err := runCmd(sshExe, sshFlags, sshArgs...); err != nil { + return nil + } + } + + return nil +} diff --git a/cmd/limactl/main.go b/cmd/limactl/main.go index 81d62eed4e5..c3c87405ca1 100644 --- a/cmd/limactl/main.go +++ b/cmd/limactl/main.go @@ -111,6 +111,7 @@ func newApp() *cobra.Command { newSudoersCommand(), newPruneCommand(), newHostagentCommand(), + newGuestInstallCommand(), newInfoCommand(), newShowSSHCommand(), newDebugCommand(), diff --git a/pkg/cacheutil/cacheutil.go b/pkg/cacheutil/cacheutil.go index b5e73b1c133..9b8ae8a073d 100644 --- a/pkg/cacheutil/cacheutil.go +++ b/pkg/cacheutil/cacheutil.go @@ -3,12 +3,25 @@ package cacheutil import ( "context" "fmt" + "path" "github.com/lima-vm/lima/pkg/downloader" "github.com/lima-vm/lima/pkg/fileutils" "github.com/lima-vm/lima/pkg/limayaml" ) +// NerdctlArchive returns the basename of the archive +func NerdctlArchive(y *limayaml.LimaYAML) string { + if *y.Containerd.System || *y.Containerd.User { + for _, f := range y.Containerd.Archives { + if f.Arch == *y.Arch { + return path.Base(f.Location) + } + } + } + return "" +} + // EnsureNerdctlArchiveCache prefetches the nerdctl-full-VERSION-GOOS-GOARCH.tar.gz archive // into the cache before launching the hostagent process, so that we can show the progress in tty. // https://github.com/lima-vm/lima/issues/326