11package main
22
33import (
4- "context"
5- "errors"
6- "fmt"
7- "os"
8- "path/filepath"
9- "strings"
10- "time"
11-
12- hostagentevents "github.com/lima-vm/lima/pkg/hostagent/events"
4+ "github.com/lima-vm/lima/pkg/instance"
135 networks "github.com/lima-vm/lima/pkg/networks/reconcile"
14- "github.com/lima-vm/lima/pkg/osutil"
156 "github.com/lima-vm/lima/pkg/store"
16- "github.com/lima-vm/lima/pkg/store/filenames"
17- "github.com/sirupsen/logrus"
187 "github.com/spf13/cobra"
198)
209
@@ -48,9 +37,9 @@ func stopAction(cmd *cobra.Command, args []string) error {
4837 return err
4938 }
5039 if force {
51- stopInstanceForcibly (inst )
40+ instance . StopForcibly (inst )
5241 } else {
53- err = stopInstanceGracefully (inst )
42+ err = instance . StopGracefully (inst )
5443 }
5544 // TODO: should we also reconcile networks if graceful stop returned an error?
5645 if err == nil {
@@ -59,102 +48,6 @@ func stopAction(cmd *cobra.Command, args []string) error {
5948 return err
6049}
6150
62- func stopInstanceGracefully (inst * store.Instance ) error {
63- if inst .Status != store .StatusRunning {
64- return fmt .Errorf ("expected status %q, got %q (maybe use `limactl stop -f`?)" , store .StatusRunning , inst .Status )
65- }
66-
67- begin := time .Now () // used for logrus propagation
68- logrus .Infof ("Sending SIGINT to hostagent process %d" , inst .HostAgentPID )
69- if err := osutil .SysKill (inst .HostAgentPID , osutil .SigInt ); err != nil {
70- logrus .Error (err )
71- }
72-
73- logrus .Info ("Waiting for the host agent and the driver processes to shut down" )
74- return waitForHostAgentTermination (context .TODO (), inst , begin )
75- }
76-
77- func waitForHostAgentTermination (ctx context.Context , inst * store.Instance , begin time.Time ) error {
78- ctx2 , cancel := context .WithTimeout (ctx , 3 * time .Minute + 10 * time .Second )
79- defer cancel ()
80-
81- var receivedExitingEvent bool
82- onEvent := func (ev hostagentevents.Event ) bool {
83- if len (ev .Status .Errors ) > 0 {
84- logrus .Errorf ("%+v" , ev .Status .Errors )
85- }
86- if ev .Status .Exiting {
87- receivedExitingEvent = true
88- return true
89- }
90- return false
91- }
92-
93- haStdoutPath := filepath .Join (inst .Dir , filenames .HostAgentStdoutLog )
94- haStderrPath := filepath .Join (inst .Dir , filenames .HostAgentStderrLog )
95-
96- if err := hostagentevents .Watch (ctx2 , haStdoutPath , haStderrPath , begin , onEvent ); err != nil {
97- return err
98- }
99-
100- if ! receivedExitingEvent {
101- return errors .New ("did not receive an event with the \" exiting\" status" )
102- }
103-
104- return nil
105- }
106-
107- func stopInstanceForcibly (inst * store.Instance ) {
108- if inst .DriverPID > 0 {
109- logrus .Infof ("Sending SIGKILL to the %s driver process %d" , inst .VMType , inst .DriverPID )
110- if err := osutil .SysKill (inst .DriverPID , osutil .SigKill ); err != nil {
111- logrus .Error (err )
112- }
113- } else {
114- logrus .Infof ("The %s driver process seems already stopped" , inst .VMType )
115- }
116-
117- for _ , d := range inst .AdditionalDisks {
118- diskName := d .Name
119- disk , err := store .InspectDisk (diskName )
120- if err != nil {
121- logrus .Warnf ("Disk %q does not exist" , diskName )
122- continue
123- }
124- if err := disk .Unlock (); err != nil {
125- logrus .Warnf ("Failed to unlock disk %q. To use, run `limactl disk unlock %v`" , diskName , diskName )
126- }
127- }
128-
129- if inst .HostAgentPID > 0 {
130- logrus .Infof ("Sending SIGKILL to the host agent process %d" , inst .HostAgentPID )
131- if err := osutil .SysKill (inst .HostAgentPID , osutil .SigKill ); err != nil {
132- logrus .Error (err )
133- }
134- } else {
135- logrus .Info ("The host agent process seems already stopped" )
136- }
137-
138- suffixesToBeRemoved := []string {".pid" , ".sock" , ".tmp" }
139- logrus .Infof ("Removing %s under %q" , inst .Dir , strings .ReplaceAll (strings .Join (suffixesToBeRemoved , " " ), "." , "*." ))
140- fi , err := os .ReadDir (inst .Dir )
141- if err != nil {
142- logrus .Error (err )
143- return
144- }
145- for _ , f := range fi {
146- path := filepath .Join (inst .Dir , f .Name ())
147- for _ , suffix := range suffixesToBeRemoved {
148- if strings .HasSuffix (path , suffix ) {
149- logrus .Infof ("Removing %q" , path )
150- if err := os .Remove (path ); err != nil {
151- logrus .Error (err )
152- }
153- }
154- }
155- }
156- }
157-
15851func stopBashComplete (cmd * cobra.Command , _ []string , _ string ) ([]string , cobra.ShellCompDirective ) {
15952 return bashCompleteInstanceNames (cmd )
16053}
0 commit comments