Skip to content

Commit 9f99488

Browse files
committed
limactl shell: ask whether to start the instance if not running
Signed-off-by: Akihiro Suda <[email protected]>
1 parent b33c40b commit 9f99488

File tree

4 files changed

+83
-36
lines changed

4 files changed

+83
-36
lines changed

cmd/limactl/edit.go

+5-30
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@ import (
1010
"github.com/lima-vm/lima/cmd/limactl/editflags"
1111
"github.com/lima-vm/lima/cmd/limactl/guessarg"
1212
"github.com/lima-vm/lima/pkg/editutil"
13-
"github.com/lima-vm/lima/pkg/instance"
1413
"github.com/lima-vm/lima/pkg/limayaml"
15-
networks "github.com/lima-vm/lima/pkg/networks/reconcile"
1614
"github.com/lima-vm/lima/pkg/store"
1715
"github.com/lima-vm/lima/pkg/store/filenames"
18-
"github.com/lima-vm/lima/pkg/uiutil"
1916
"github.com/lima-vm/lima/pkg/yqutil"
2017
"github.com/sirupsen/logrus"
2118
"github.com/spf13/cobra"
@@ -132,34 +129,12 @@ func editAction(cmd *cobra.Command, args []string) error {
132129
}
133130
if inst != nil {
134131
logrus.Infof("Instance %q configuration edited", inst.Name)
132+
if _, err = startWithAsking(cmd, inst.Name, false, false); err != nil {
133+
return err
134+
}
135135
}
136-
137-
if !tty {
138-
// use "start" to start it
139-
return nil
140-
}
141-
if inst == nil {
142-
// edited a limayaml file directly
143-
return nil
144-
}
145-
startNow, err := askWhetherToStart()
146-
if err != nil {
147-
return err
148-
}
149-
if !startNow {
150-
return nil
151-
}
152-
ctx := cmd.Context()
153-
err = networks.Reconcile(ctx, inst.Name)
154-
if err != nil {
155-
return err
156-
}
157-
return instance.Start(ctx, inst, "", false)
158-
}
159-
160-
func askWhetherToStart() (bool, error) {
161-
message := "Do you want to start the instance now? "
162-
return uiutil.Confirm(message, true)
136+
// inst is nil if edited a limayaml file directly
137+
return nil
163138
}
164139

165140
func editBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {

cmd/limactl/shell.go

+16-3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func newShellCommand() *cobra.Command {
5151
}
5252

5353
func shellAction(cmd *cobra.Command, args []string) error {
54+
os.Setenv("_LIMACTL_SHELL_IN_ACTION", "")
5455
// simulate the behavior of double dash
5556
newArg := []string{}
5657
if len(args) >= 2 && args[1] == "--" {
@@ -71,12 +72,24 @@ func shellAction(cmd *cobra.Command, args []string) error {
7172
inst, err := store.Inspect(instName)
7273
if err != nil {
7374
if errors.Is(err, os.ErrNotExist) {
74-
return fmt.Errorf("instance %q does not exist, run `limactl create %s` to create a new instance", instName, instName)
75+
_, err = startWithAsking(cmd, instName, true, true)
76+
if err != nil {
77+
return err
78+
}
79+
inst, err = store.Inspect(instName)
80+
}
81+
if err != nil {
82+
return err
7583
}
76-
return err
7784
}
7885
if inst.Status == store.StatusStopped {
79-
return fmt.Errorf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName)
86+
if _, err = startWithAsking(cmd, instName, false, true); err != nil {
87+
return err
88+
}
89+
inst, err = store.Inspect(instName)
90+
if err != nil {
91+
return err
92+
}
8093
}
8194

8295
// When workDir is explicitly set, the shell MUST have workDir as the cwd, or exit with an error.

cmd/limactl/start.go

+52
Original file line numberDiff line numberDiff line change
@@ -529,3 +529,55 @@ func startBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobr
529529
compTmpl, _ := bashCompleteTemplateNames(cmd)
530530
return append(compInst, compTmpl...), cobra.ShellCompDirectiveDefault
531531
}
532+
533+
// startWithAsking starts the instance after a confirmation prompt.
534+
//
535+
// If newInst is set to true, this function creates the instance too.
536+
//
537+
// If mandatory is set to true, and the answer to the confirmation prompt is No,
538+
// the function returns an error that contains an instruction to start the instance manually.
539+
func startWithAsking(cmd *cobra.Command, instName string, newInst, mandatory bool) (bool, error) {
540+
flags := cmd.Flags()
541+
tty, err := flags.GetBool("tty")
542+
if err != nil {
543+
return false, err
544+
}
545+
errS := fmt.Sprintf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName)
546+
if newInst {
547+
errS = fmt.Sprintf("instance %q does not exist, run `limactl create %s` to create a new instance", instName, instName)
548+
}
549+
if !tty {
550+
if mandatory {
551+
return false, errors.New(errS)
552+
}
553+
return false, nil
554+
}
555+
logrus.Error(errS)
556+
557+
message := fmt.Sprintf("Do you want to start the instance %q now?", instName)
558+
if newInst {
559+
message = fmt.Sprintf("Do you want to create and start the instance %q using the default template now?", instName)
560+
}
561+
ans, err := uiutil.Confirm(message, true)
562+
if err != nil {
563+
return false, err
564+
}
565+
if !ans {
566+
if mandatory {
567+
return ans, errors.New(errS)
568+
}
569+
return ans, nil
570+
}
571+
if newInst {
572+
rootCmd := cmd.Root()
573+
// The create command shows the template chooser UI, etc.
574+
rootCmd.SetArgs([]string{"create", instName})
575+
if err := rootCmd.Execute(); err != nil {
576+
return ans, err
577+
}
578+
}
579+
rootCmd := cmd.Root()
580+
// The start command reconciliates the networks, etc.
581+
rootCmd.SetArgs([]string{"start", instName})
582+
return ans, rootCmd.Execute()
583+
}

pkg/instance/start.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,17 @@ func watchHostAgentEvents(ctx context.Context, inst *store.Instance, haStdoutPat
307307
err = xerr
308308
return true
309309
}
310-
if *inst.Config.Plain {
311-
logrus.Infof("READY. Run `ssh -F %q lima-%s` to open the shell.", inst.SSHConfigFile, inst.Name)
310+
// _LIMACTL_SHELL_IN_ACTION is set if `limactl shell` invoked `limactl start`.
311+
// In this case we shouldn't print "Run `lima` to open the shell",
312+
// because the user has already executed the `lima` command.
313+
if _, limactlShellInAction := os.LookupEnv("_LIMACTL_SHELL_IN_ACTION"); limactlShellInAction {
314+
logrus.Infof("READY.")
312315
} else {
313-
logrus.Infof("READY. Run `%s` to open the shell.", LimactlShellCmd(inst.Name))
316+
if *inst.Config.Plain {
317+
logrus.Infof("READY. Run `ssh -F %q lima-%s` to open the shell.", inst.SSHConfigFile, inst.Name)
318+
} else {
319+
logrus.Infof("READY. Run `%s` to open the shell.", LimactlShellCmd(inst.Name))
320+
}
314321
}
315322
_ = ShowMessage(inst)
316323
err = nil

0 commit comments

Comments
 (0)