Skip to content

Commit 4633821

Browse files
committed
hostagent: Handle SIGTERM signal for better compatibility with macOS launchd
This commit modifies the hostagent to handle not only the SIGINT (Interrupt) signal, but also the SIGTERM signal. This allows the hostagent to gracefully shut down when it receives a SIGTERM signal, which is a common way to request a process to terminate. This change improves the compatibility with macOS launchd, which uses SIGTERM to stop services. The following are the steps to set up the Docker instance of Lima to start at login using launchd on macOS: ```bash # Create the docker instance limactl start template://docker --vm-type vz --rosetta --network vzNAT --tty=false # Stop the docker instance limactl stop docker # Create the launchd plist echo '<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>io.lima-vm.docker</string> <key>ProgramArguments</key> <array> <string>'"$(which limactl)"'</string> <string>hostagent</string> <string>--pidfile</string> <string>ha.pid</string> <string>--socket</string> <string>ha.sock</string> <string>docker</string> </array> <key>RunAtLoad</key> <true/> <key>StandardErrorPath</key> <string>ha.stderr.log</string> <key>StandardOutPath</key> <string>ha.stdout.log</string> <key>WorkingDirectory</key> <string>'"$(limactl list docker --format '{{.Dir}}')"'</string> </dict> </plist>' > ~/Library/LaunchAgents/io.lima-vm.docker.plist # Load the launchd plist and launchd will start the docker instance launchctl load ~/Library/LaunchAgents/io.lima-vm.docker.plist ``` Signed-off-by: Norio Nomura <[email protected]>
1 parent cfd5a90 commit 4633821

File tree

4 files changed

+32
-9
lines changed

4 files changed

+32
-9
lines changed

cmd/limactl/hostagent.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os/signal"
1111
"runtime"
1212
"strconv"
13+
"syscall"
1314

1415
"github.com/gorilla/mux"
1516
"github.com/lima-vm/lima/pkg/hostagent"
@@ -67,8 +68,8 @@ func hostagentAction(cmd *cobra.Command, args []string) error {
6768
defer runtime.UnlockOSThread()
6869
}
6970

70-
sigintCh := make(chan os.Signal, 1)
71-
signal.Notify(sigintCh, os.Interrupt)
71+
signalCh := make(chan os.Signal, 1)
72+
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
7273

7374
stdout := &syncWriter{w: cmd.OutOrStdout()}
7475
stderr := &syncWriter{w: cmd.ErrOrStderr()}
@@ -82,7 +83,7 @@ func hostagentAction(cmd *cobra.Command, args []string) error {
8283
if nerdctlArchive != "" {
8384
opts = append(opts, hostagent.WithNerdctlArchive(nerdctlArchive))
8485
}
85-
ha, err := hostagent.New(instName, stdout, sigintCh, opts...)
86+
ha, err := hostagent.New(instName, stdout, signalCh, opts...)
8687
if err != nil {
8788
return err
8889
}

pkg/hostagent/hostagent.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/lima-vm/lima/pkg/driver"
2020
"github.com/lima-vm/lima/pkg/driverutil"
2121
"github.com/lima-vm/lima/pkg/networks"
22+
"github.com/lima-vm/lima/pkg/osutil"
2223

2324
"github.com/lima-vm/lima/pkg/cidata"
2425
guestagentapi "github.com/lima-vm/lima/pkg/guestagent/api"
@@ -48,7 +49,7 @@ type HostAgent struct {
4849
onClose []func() error // LIFO
4950

5051
driver driver.Driver
51-
sigintCh chan os.Signal
52+
signalCh chan os.Signal
5253

5354
eventEnc *json.Encoder
5455
eventEncMu sync.Mutex
@@ -79,7 +80,7 @@ func WithNerdctlArchive(s string) Opt {
7980
// New creates the HostAgent.
8081
//
8182
// stdout is for emitting JSON lines of Events.
82-
func New(instName string, stdout io.Writer, sigintCh chan os.Signal, opts ...Opt) (*HostAgent, error) {
83+
func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt) (*HostAgent, error) {
8384
var o options
8485
for _, f := range opts {
8586
if err := f(&o); err != nil {
@@ -179,7 +180,7 @@ func New(instName string, stdout io.Writer, sigintCh chan os.Signal, opts ...Opt
179180
sshConfig: sshConfig,
180181
portForwarder: newPortForwarder(sshConfig, sshLocalPort, rules, inst.VMType),
181182
driver: limaDriver,
182-
sigintCh: sigintCh,
183+
signalCh: signalCh,
183184
eventEnc: json.NewEncoder(stdout),
184185
vSockPort: vSockPort,
185186
virtioPort: virtioPort,
@@ -418,8 +419,8 @@ func (a *HostAgent) startRoutinesAndWait(ctx context.Context, errCh chan error)
418419
}
419420
err := a.driver.Stop(ctx)
420421
return err
421-
case <-a.sigintCh:
422-
logrus.Info("Received SIGINT, shutting down the host agent")
422+
case sig := <-a.signalCh:
423+
logrus.Infof("Received %s, shutting down the host agent", osutil.SignalName(sig))
423424
cancelHA()
424425
if closeErr := a.close(); closeErr != nil {
425426
logrus.WithError(closeErr).Warn("an error during shutting down the host agent")

pkg/osutil/osutil_unix.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@
22

33
package osutil
44

5-
import "golang.org/x/sys/unix"
5+
import (
6+
"os"
7+
"syscall"
8+
9+
"golang.org/x/sys/unix"
10+
)
611

712
func Ftruncate(fd int, length int64) (err error) {
813
return unix.Ftruncate(fd, length)
914
}
15+
16+
func SignalName(sig os.Signal) string {
17+
return unix.SignalName(sig.(syscall.Signal))
18+
}

pkg/osutil/osutil_windows.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package osutil
33
import (
44
"fmt"
55
"io/fs"
6+
"os"
67
"syscall"
78

89
"golang.org/x/sys/windows"
@@ -36,3 +37,14 @@ func SysKill(pid int, _ Signal) error {
3637
func Ftruncate(_ int, _ int64) (err error) {
3738
return fmt.Errorf("unimplemented")
3839
}
40+
41+
func SignalName(sig os.Signal) string {
42+
switch sig {
43+
case syscall.SIGINT:
44+
return "SIGINT"
45+
case syscall.SIGTERM:
46+
return "SIGTERM"
47+
default:
48+
return fmt.Sprintf("Signal(%d)", sig)
49+
}
50+
}

0 commit comments

Comments
 (0)