diff --git a/cmd/lima-guestagent/daemon_linux.go b/cmd/lima-guestagent/daemon_linux.go index aebfdbf9999..1d3b489c6d7 100644 --- a/cmd/lima-guestagent/daemon_linux.go +++ b/cmd/lima-guestagent/daemon_linux.go @@ -5,7 +5,8 @@ import ( "net" "net/http" "os" - "path/filepath" + "os/user" + "strconv" "time" "github.com/AkihiroSuda/lima/pkg/guestagent" @@ -22,13 +23,11 @@ var daemonCommand = &cli.Command{ &cli.StringFlag{ Name: "socket", Usage: "socket", - Value: func() string { - if xrd := os.Getenv("XDG_RUNTIME_DIR"); xrd != "" { - return filepath.Join(xrd, "lima-guestagent.sock") - } - logrus.Warn("$XDG_RUNTIME_DIR is not set, cannot determine the socket name") - return "" - }(), + Value: "/run/lima-guestagent.sock", + }, + &cli.StringFlag{ + Name: "socket-owner", + Usage: "socket owner user", }, &cli.DurationFlag{ Name: "tick", @@ -48,9 +47,6 @@ func daemonAction(clicontext *cli.Context) error { if tick == 0 { return errors.New("tick must be specified") } - if os.Geteuid() == 0 { - return errors.New("must not run as the root") - } logrus.Infof("event tick: %v", tick) newTicker := func() (<-chan time.Time, func()) { @@ -76,6 +72,23 @@ func daemonAction(clicontext *cli.Context) error { if err != nil { return err } + if socketOwner := clicontext.String("socket-owner"); socketOwner != "" { + u, err := user.Lookup(socketOwner) + if err != nil { + return err + } + uid, err := strconv.Atoi(u.Uid) + if err != nil { + return err + } + gid, err := strconv.Atoi(u.Gid) + if err != nil { + return err + } + if err := os.Chown(socket, uid, gid); err != nil { + return err + } + } logrus.Infof("serving the guest agent on %q", socket) return srv.Serve(l) } diff --git a/cmd/lima-guestagent/install_systemd_linux.go b/cmd/lima-guestagent/install_systemd_linux.go deleted file mode 100644 index 0cc42f6345f..00000000000 --- a/cmd/lima-guestagent/install_systemd_linux.go +++ /dev/null @@ -1,81 +0,0 @@ -package main - -import ( - _ "embed" - "errors" - "os" - "os/exec" - "path/filepath" - "strings" - - "github.com/AkihiroSuda/lima/pkg/templateutil" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" -) - -var installSystemdCommand = &cli.Command{ - Name: "install-systemd", - Usage: "install a systemd unit (user)", - Action: installSystemdAction, -} - -func installSystemdAction(clicontext *cli.Context) error { - unit, err := generateSystemdUnit() - if err != nil { - return err - } - unitPath, err := systemdUnitPath() - if err != nil { - return err - } - if _, err := os.Stat(unitPath); !errors.Is(err, os.ErrNotExist) { - logrus.Infof("File %q already exists, overwriting", unitPath) - } else { - unitDir := filepath.Dir(unitPath) - if err := os.MkdirAll(unitDir, 0755); err != nil { - return err - } - } - if err := os.WriteFile(unitPath, unit, 0644); err != nil { - return err - } - logrus.Infof("Written file %q", unitPath) - argss := [][]string{ - {"daemon-reload"}, - {"enable", "--now", "lima-guestagent.service"}, - } - for _, args := range argss { - cmd := exec.Command("systemctl", append([]string{"--user"}, args...)...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - logrus.Infof("Executing: %s", strings.Join(cmd.Args, " ")) - if err := cmd.Run(); err != nil { - return err - } - } - logrus.Info("Done") - return nil -} - -func systemdUnitPath() (string, error) { - configDir, err := os.UserConfigDir() - if err != nil { - return "", err - } - unitPath := filepath.Join(configDir, "systemd/user/lima-guestagent.service") - return unitPath, nil -} - -//go:embed lima-guestagent.TEMPLATE.service -var systemdUnitTemplate string - -func generateSystemdUnit() ([]byte, error) { - selfExeAbs, err := os.Executable() - if err != nil { - return nil, err - } - m := map[string]string{ - "Binary": selfExeAbs, - } - return templateutil.Execute(systemdUnitTemplate, m) -} diff --git a/cmd/lima-guestagent/lima-guestagent.TEMPLATE.service b/cmd/lima-guestagent/lima-guestagent.TEMPLATE.service deleted file mode 100644 index e26225c1f61..00000000000 --- a/cmd/lima-guestagent/lima-guestagent.TEMPLATE.service +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=lima-guestagent - -[Service] -ExecStart={{.Binary}} daemon -Type=simple -Restart=on-failure - -[Install] -WantedBy=default.target diff --git a/cmd/lima-guestagent/main_linux.go b/cmd/lima-guestagent/main_linux.go index 592b1209e2e..f86753fd2a4 100644 --- a/cmd/lima-guestagent/main_linux.go +++ b/cmd/lima-guestagent/main_linux.go @@ -1,7 +1,6 @@ package main import ( - "errors" "os" "strings" @@ -31,14 +30,10 @@ func newApp() *cli.App { if clicontext.Bool("debug") { logrus.SetLevel(logrus.DebugLevel) } - if os.Geteuid() == 0 { - return errors.New("must not run as the root") - } return nil } app.Commands = []*cli.Command{ daemonCommand, - installSystemdCommand, } return app } diff --git a/docs/internal.md b/docs/internal.md index f488c1c4007..df7ad68f67d 100644 --- a/docs/internal.md +++ b/docs/internal.md @@ -33,7 +33,7 @@ SSH: - `ssh.sock`: SSH control master socket Guest agent: -- `ga.sock`: Forwarded to `/run/user/$UID/lima-guestagent.sock` in the guest, via SSH +- `ga.sock`: Forwarded to `/run/lima-guestagent.sock` in the guest, via SSH Host agent: - `ha.pid`: hostagent PID diff --git a/pkg/cidata/cidata.TEMPLATE.d/boot/25-guestagent-base.sh b/pkg/cidata/cidata.TEMPLATE.d/boot/25-guestagent-base.sh index 264c2b33cd2..6d094c758b9 100644 --- a/pkg/cidata/cidata.TEMPLATE.d/boot/25-guestagent-base.sh +++ b/pkg/cidata/cidata.TEMPLATE.d/boot/25-guestagent-base.sh @@ -15,10 +15,6 @@ install -m 755 "${LIMA_CIDATA_MNT}"/lima-guestagent /usr/local/bin/lima-guestage # Launch the guestagent service if [ -f /etc/alpine-release ]; then - # Create directory for the lima-guestagent socket (normally done by systemd) - mkdir -p /run/user/"${LIMA_CIDATA_UID}" - chown "${LIMA_CIDATA_USER}" /run/user/"${LIMA_CIDATA_UID}" - chmod 700 /run/user/"${LIMA_CIDATA_UID}" # Install the openrc lima-guestagent service script cat >/etc/init.d/lima-guestagent <<'EOF' #!/sbin/openrc-run @@ -27,18 +23,29 @@ supervisor=supervise-daemon name="lima-guestagent" description="Forward ports to the lima-hostagent" -export XDG_RUNTIME_DIR="/run/user/${LIMA_CIDATA_UID}" command=/usr/local/bin/lima-guestagent -command_args="daemon" +command_args="daemon --socket-owner=${LIMA_CIDATA_USER}" command_background=true -command_user="${LIMA_CIDATA_USER}:${LIMA_CIDATA_USER}" -pidfile="${XDG_RUNTIME_DIR}/lima-guestagent.pid" +pidfile="/run/lima-guestagent.pid" EOF chmod 755 /etc/init.d/lima-guestagent rc-update add lima-guestagent default rc-service lima-guestagent start else - until [ -e "/run/user/${LIMA_CIDATA_UID}/systemd/private" ]; do sleep 3; done - sudo -iu "${LIMA_CIDATA_USER}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" lima-guestagent install-systemd + mkdir -p /usr/local/lib/systemd/system + cat >/usr/local/lib/systemd/system/lima-guestagent.service <&2 "lima-guestagent is not installed yet" exit 1 fi `, - debugHint: `The guest agent (/run/user/$UID/lima-guestagent.sock) does not seem running. + debugHint: `The guest agent (/run/lima-guestagent.sock) does not seem running. Make sure that you are using an officially supported image. Also see "/var/log/cloud-init-output.log" in the guest. -A possible workaround is to run "lima-guestagent install-systemd" in the guest. `, }) return req