Skip to content

Commit 07f181e

Browse files
committed
Add support for restarting a instance
Signed-off-by: Ansuman Sahoo <[email protected]>
1 parent 710e900 commit 07f181e

File tree

3 files changed

+126
-0
lines changed

3 files changed

+126
-0
lines changed

cmd/limactl/main.go

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ func newApp() *cobra.Command {
159159
newUnprotectCommand(),
160160
newTunnelCommand(),
161161
newTemplateCommand(),
162+
newRestartCommand(),
162163
)
163164
if runtime.GOOS == "darwin" || runtime.GOOS == "linux" {
164165
rootCmd.AddCommand(startAtLoginCommand())

cmd/limactl/restart.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// SPDX-FileCopyrightText: Copyright The Lima Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package main
5+
6+
import (
7+
"github.com/lima-vm/lima/pkg/instance"
8+
"github.com/lima-vm/lima/pkg/store"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
func newRestartCommand() *cobra.Command {
13+
restartCmd := &cobra.Command{
14+
Use: "restart INSTANCE",
15+
Short: "Restart a running instance",
16+
RunE: restartAction,
17+
ValidArgsFunction: restartBashComplete,
18+
GroupID: basicCommand,
19+
}
20+
21+
restartCmd.Flags().BoolP("force", "f", false, "force stop and restart the instance")
22+
return restartCmd
23+
}
24+
25+
func restartAction(cmd *cobra.Command, args []string) error {
26+
instName := DefaultInstanceName
27+
if len(args) > 0 {
28+
instName = args[0]
29+
}
30+
31+
inst, err := store.Inspect(instName)
32+
if err != nil {
33+
return err
34+
}
35+
36+
force, err := cmd.Flags().GetBool("force")
37+
if err != nil {
38+
return err
39+
}
40+
41+
ctx := cmd.Context()
42+
if force {
43+
err = instance.RestartForcibly(ctx, inst)
44+
} else {
45+
err = instance.Restart(ctx, inst)
46+
}
47+
return err
48+
}
49+
50+
func restartBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
51+
return bashCompleteInstanceNames(cmd)
52+
}

pkg/instance/restart.go

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// SPDX-FileCopyrightText: Copyright The Lima Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package instance
5+
6+
import (
7+
"context"
8+
"errors"
9+
"time"
10+
11+
networks "github.com/lima-vm/lima/pkg/networks/reconcile"
12+
"github.com/lima-vm/lima/pkg/store"
13+
)
14+
15+
const launchHostAgentForeground = false
16+
17+
func Restart(ctx context.Context, inst *store.Instance) error {
18+
if err := StopGracefully(inst); err != nil {
19+
return err
20+
}
21+
22+
if err := waitForInstanceShutdown(ctx, inst); err != nil {
23+
return err
24+
}
25+
26+
if err := networks.Reconcile(ctx, inst.Name); err != nil {
27+
return err
28+
}
29+
30+
if err := Start(ctx, inst, "", launchHostAgentForeground); err != nil {
31+
return err
32+
}
33+
34+
return nil
35+
}
36+
37+
func RestartForcibly(ctx context.Context, inst *store.Instance) error {
38+
StopForcibly(inst)
39+
40+
if err := networks.Reconcile(ctx, inst.Name); err != nil {
41+
return err
42+
}
43+
44+
if err := Start(ctx, inst, "", launchHostAgentForeground); err != nil {
45+
return err
46+
}
47+
48+
return nil
49+
}
50+
51+
func waitForInstanceShutdown(ctx context.Context, inst *store.Instance) error {
52+
ctx2, cancel := context.WithTimeout(ctx, 3*time.Minute)
53+
defer cancel()
54+
55+
ticker := time.NewTicker(500 * time.Millisecond)
56+
defer ticker.Stop()
57+
58+
for {
59+
select {
60+
case <-ticker.C:
61+
updatedInst, err := store.Inspect(inst.Name)
62+
if err != nil {
63+
return errors.New("failed to inspect instance status: " + err.Error())
64+
}
65+
66+
if updatedInst.Status == store.StatusStopped {
67+
return nil
68+
}
69+
case <-ctx2.Done():
70+
return errors.New("timed out waiting for instance to stop")
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)