-
Notifications
You must be signed in to change notification settings - Fork 712
Minimize effects caused by restarting guestagent #4217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,14 @@ | |
package main | ||
|
||
import ( | ||
"bytes" | ||
_ "embed" | ||
"errors" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"slices" | ||
"strings" | ||
|
||
"github.com/sirupsen/logrus" | ||
|
@@ -24,13 +26,18 @@ func newInstallSystemdCommand() *cobra.Command { | |
Short: "Install a systemd unit (user)", | ||
RunE: installSystemdAction, | ||
} | ||
installSystemdCommand.Flags().Bool("guestagent-updated", false, "Indicate that the guest agent has been updated") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alternatively you can just compare mtime of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted to use the judgment result of "update guestagent" made in the boot script. |
||
installSystemdCommand.Flags().Int("vsock-port", 0, "Use vsock server on specified port") | ||
installSystemdCommand.Flags().String("virtio-port", "", "Use virtio server instead a UNIX socket") | ||
return installSystemdCommand | ||
} | ||
|
||
func installSystemdAction(cmd *cobra.Command, _ []string) error { | ||
ctx := cmd.Context() | ||
guestAgentUpdated, err := cmd.Flags().GetBool("guestagent-updated") | ||
if err != nil { | ||
return err | ||
} | ||
vsockPort, err := cmd.Flags().GetInt("vsock-port") | ||
if err != nil { | ||
return err | ||
|
@@ -48,24 +55,42 @@ func installSystemdAction(cmd *cobra.Command, _ []string) error { | |
return err | ||
} | ||
unitPath := "/etc/systemd/system/lima-guestagent.service" | ||
unitFileChanged := true | ||
if _, err := os.Stat(unitPath); !errors.Is(err, os.ErrNotExist) { | ||
logrus.Infof("File %q already exists, overwriting", unitPath) | ||
if existingUnit, err := os.ReadFile(unitPath); err == nil && bytes.Equal(unit, existingUnit) { | ||
logrus.Infof("File %q is up-to-date", unitPath) | ||
unitFileChanged = false | ||
} else { | ||
logrus.Infof("File %q needs update", unitPath) | ||
} | ||
} else { | ||
unitDir := filepath.Dir(unitPath) | ||
if err := os.MkdirAll(unitDir, 0o755); err != nil { | ||
return err | ||
} | ||
} | ||
if err := os.WriteFile(unitPath, unit, 0o644); err != nil { | ||
return err | ||
if unitFileChanged { | ||
if err := os.WriteFile(unitPath, unit, 0o644); err != nil { | ||
return err | ||
} | ||
logrus.Infof("Written file %q", unitPath) | ||
} else if !guestAgentUpdated { | ||
logrus.Info("lima-guestagent.service already up-to-date") | ||
return nil | ||
} | ||
logrus.Infof("Written file %q", unitPath) | ||
args := [][]string{ | ||
{"daemon-reload"}, | ||
{"enable", "lima-guestagent.service"}, | ||
{"start", "lima-guestagent.service"}, | ||
{"try-restart", "lima-guestagent.service"}, | ||
// unitFileChanged || guestAgentUpdated | ||
args := make([][]string, 0, 4) | ||
if unitFileChanged { | ||
args = append(args, []string{"daemon-reload"}) | ||
} | ||
args = slices.Concat( | ||
args, | ||
[][]string{ | ||
{"enable", "lima-guestagent.service"}, | ||
{"try-restart", "lima-guestagent.service"}, // try-restart: restart if running, otherwise do nothing | ||
{"start", "lima-guestagent.service"}, // start: start if not running, otherwise do nothing | ||
}, | ||
) | ||
for _, args := range args { | ||
cmd := exec.CommandContext(ctx, "systemctl", append([]string{"--system"}, args...)...) | ||
cmd.Stdout = os.Stdout | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
Description=lima-guestagent | ||
|
||
[Service] | ||
ExecStart={{.Binary}} daemon {{.Args}} | ||
ExecStart={{.Binary}} daemon {{.Args}} --runtime-dir="%t/%N" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
Type=simple | ||
Restart=on-failure | ||
OOMPolicy=continue | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
#!/bin/sh | ||
#!/bin/bash | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this work with Alpine? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It works with both "template:alpine" and "template:alpine-iso", and has already been used in other boot scripts. |
||
|
||
# SPDX-FileCopyrightText: Copyright The Lima Authors | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
@@ -19,46 +19,66 @@ fi | |
|
||
# Install or update the guestagent binary | ||
mkdir -p "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin | ||
install -m 755 "${LIMA_CIDATA_MNT}"/lima-guestagent "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent | ||
guestagent_updated=false | ||
if diff -q "${LIMA_CIDATA_MNT}"/lima-guestagent "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent 2>/dev/null; then | ||
echo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}/bin/lima-guestagent is up-to-date" | ||
else | ||
install -m 755 "${LIMA_CIDATA_MNT}"/lima-guestagent "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent | ||
guestagent_updated=true | ||
fi | ||
|
||
# Launch the guestagent service | ||
if [ -f /sbin/openrc-run ]; then | ||
# Convert .env to conf.d by wrapping values in double quotes. | ||
# Split the variable and value at the first "=" to handle cases where the value contains additional "=" characters. | ||
sed -E 's/^([^=]+)=(.*)/\1="\2"/' "${LIMA_CIDATA_MNT}/lima.env" >"/etc/conf.d/lima-guestagent" | ||
# Install the openrc lima-guestagent service script | ||
cat >/etc/init.d/lima-guestagent <<'EOF' | ||
#!/sbin/openrc-run | ||
supervisor=supervise-daemon | ||
print_config() { | ||
# Convert .env to conf.d by wrapping values in double quotes. | ||
# Split the variable and value at the first "=" to handle cases where the value contains additional "=" characters. | ||
sed -E 's/^([^=]+)=(.*)/\1="\2"/' "${LIMA_CIDATA_MNT}/lima.env" | ||
} | ||
print_script() { | ||
# the openrc lima-guestagent service script | ||
cat <<-'EOF' | ||
#!/sbin/openrc-run | ||
supervisor=supervise-daemon | ||
|
||
log_file="${log_file:-/var/log/${RC_SVCNAME}.log}" | ||
err_file="${err_file:-${log_file}}" | ||
log_mode="${log_mode:-0644}" | ||
log_owner="${log_owner:-root:root}" | ||
log_file="${log_file:-/var/log/${RC_SVCNAME}.log}" | ||
err_file="${err_file:-${log_file}}" | ||
log_mode="${log_mode:-0644}" | ||
log_owner="${log_owner:-root:root}" | ||
|
||
supervise_daemon_args="${supervise_daemon_opts:---stderr \"${err_file}\" --stdout \"${log_file}\"}" | ||
supervise_daemon_args="${supervise_daemon_opts:---stderr \"${err_file}\" --stdout \"${log_file}\"}" | ||
|
||
name="lima-guestagent" | ||
description="Forward ports to the lima-hostagent" | ||
name="lima-guestagent" | ||
description="Forward ports to the lima-hostagent" | ||
|
||
command=${LIMA_CIDATA_GUEST_INSTALL_PREFIX}/bin/lima-guestagent | ||
command_args="daemon --debug=${LIMA_CIDATA_DEBUG} --vsock-port \"${LIMA_CIDATA_VSOCK_PORT}\" --virtio-port \"${LIMA_CIDATA_VIRTIO_PORT}\"" | ||
command_background=true | ||
pidfile="/run/lima-guestagent.pid" | ||
EOF | ||
} | ||
if [ "${guestagent_updated}" = "false" ] && | ||
diff -q <(print_config) /etc/conf.d/lima-guestagent 2>/dev/null && | ||
diff -q <(print_script) /etc/init.d/lima-guestagent 2>/dev/null; then | ||
echo "lima-guestagent service already up-to-date" | ||
exit 0 | ||
fi | ||
|
||
command=${LIMA_CIDATA_GUEST_INSTALL_PREFIX}/bin/lima-guestagent | ||
command_args="daemon --debug=${LIMA_CIDATA_DEBUG} --vsock-port \"${LIMA_CIDATA_VSOCK_PORT}\" --virtio-port \"${LIMA_CIDATA_VIRTIO_PORT}\"" | ||
command_background=true | ||
pidfile="/run/lima-guestagent.pid" | ||
EOF | ||
print_config >/etc/conf.d/lima-guestagent | ||
print_script >/etc/init.d/lima-guestagent | ||
chmod 755 /etc/init.d/lima-guestagent | ||
|
||
rc-update add lima-guestagent default | ||
rc-service lima-guestagent start | ||
rc-service --ifstarted lima-guestagent restart # restart if running, otherwise do nothing | ||
rc-service --ifstopped lima-guestagent start # start if not running, otherwise do nothing | ||
else | ||
# Remove legacy systemd service | ||
rm -f "${LIMA_CIDATA_HOME}/.config/systemd/user/lima-guestagent.service" | ||
|
||
if [ "${LIMA_CIDATA_VSOCK_PORT}" != "0" ]; then | ||
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd --debug="${LIMA_CIDATA_DEBUG}" --vsock-port "${LIMA_CIDATA_VSOCK_PORT}" | ||
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd --debug="${LIMA_CIDATA_DEBUG}" --guestagent-updated="${guestagent_updated}" --vsock-port "${LIMA_CIDATA_VSOCK_PORT}" | ||
elif [ "${LIMA_CIDATA_VIRTIO_PORT}" != "" ]; then | ||
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd --debug="${LIMA_CIDATA_DEBUG}" --virtio-port "${LIMA_CIDATA_VIRTIO_PORT}" | ||
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd --debug="${LIMA_CIDATA_DEBUG}" --guestagent-updated="${guestagent_updated}" --virtio-port "${LIMA_CIDATA_VIRTIO_PORT}" | ||
else | ||
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd --debug="${LIMA_CIDATA_DEBUG}" | ||
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd --debug="${LIMA_CIDATA_DEBUG}" --guestagent-updated="${guestagent_updated}" | ||
fi | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to be customizable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for environment that does not want to use "/run/lima-guestagent"?
I don't know if there is such an environment. However, I can't think of a reason why it's better to hardcode this.