diff --git a/cmd/limactl/edit.go b/cmd/limactl/edit.go index 70a54a858f6..e8742928ca1 100644 --- a/cmd/limactl/edit.go +++ b/cmd/limactl/edit.go @@ -10,12 +10,9 @@ import ( "github.com/lima-vm/lima/cmd/limactl/editflags" "github.com/lima-vm/lima/cmd/limactl/guessarg" "github.com/lima-vm/lima/pkg/editutil" - "github.com/lima-vm/lima/pkg/instance" "github.com/lima-vm/lima/pkg/limayaml" - networks "github.com/lima-vm/lima/pkg/networks/reconcile" "github.com/lima-vm/lima/pkg/store" "github.com/lima-vm/lima/pkg/store/filenames" - "github.com/lima-vm/lima/pkg/uiutil" "github.com/lima-vm/lima/pkg/yqutil" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -132,34 +129,12 @@ func editAction(cmd *cobra.Command, args []string) error { } if inst != nil { logrus.Infof("Instance %q configuration edited", inst.Name) + if _, err = startWithAsking(cmd, inst.Name, false, false); err != nil { + return err + } } - - if !tty { - // use "start" to start it - return nil - } - if inst == nil { - // edited a limayaml file directly - return nil - } - startNow, err := askWhetherToStart() - if err != nil { - return err - } - if !startNow { - return nil - } - ctx := cmd.Context() - err = networks.Reconcile(ctx, inst.Name) - if err != nil { - return err - } - return instance.Start(ctx, inst, "", false) -} - -func askWhetherToStart() (bool, error) { - message := "Do you want to start the instance now? " - return uiutil.Confirm(message, true) + // inst is nil if edited a limayaml file directly + return nil } func editBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { diff --git a/cmd/limactl/shell.go b/cmd/limactl/shell.go index 694413923d8..6fc5fa78e05 100644 --- a/cmd/limactl/shell.go +++ b/cmd/limactl/shell.go @@ -71,12 +71,20 @@ func shellAction(cmd *cobra.Command, args []string) error { inst, err := store.Inspect(instName) if err != nil { if errors.Is(err, os.ErrNotExist) { - return fmt.Errorf("instance %q does not exist, run `limactl create %s` to create a new instance", instName, instName) + _, err = startWithAsking(cmd, instName, true, true) + if err != nil { + return err + } + inst, err = store.Inspect(instName) + } + if err != nil { + return err } - return err } if inst.Status == store.StatusStopped { - return fmt.Errorf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName) + if _, err = startWithAsking(cmd, instName, false, true); err != nil { + return err + } } // When workDir is explicitly set, the shell MUST have workDir as the cwd, or exit with an error. diff --git a/cmd/limactl/start.go b/cmd/limactl/start.go index 3825bc5e683..d7d23b6b143 100644 --- a/cmd/limactl/start.go +++ b/cmd/limactl/start.go @@ -529,3 +529,55 @@ func startBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobr compTmpl, _ := bashCompleteTemplateNames(cmd) return append(compInst, compTmpl...), cobra.ShellCompDirectiveDefault } + +// startWithAsking starts the instance after a confirmation prompt. +// +// If newInst is set to true, this function creates the instance too. +// +// If mandatory is set to true, and the answer to the confirmation prompt is No, +// the function returns an error that contains an instruction to start the instance manually. +func startWithAsking(cmd *cobra.Command, instName string, newInst, mandatory bool) (bool, error) { + flags := cmd.Flags() + tty, err := flags.GetBool("tty") + if err != nil { + return false, err + } + errS := fmt.Sprintf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName) + if newInst { + errS = fmt.Sprintf("instance %q does not exist, run `limactl create %s` to create a new instance", instName, instName) + } + if !tty { + if mandatory { + return false, errors.New(errS) + } + return false, nil + } + logrus.Error(errS) + + message := fmt.Sprintf("Do you want to start the instance %q now?", instName) + if newInst { + message = fmt.Sprintf("Do you want to create and start the instance %q using the default template now?", instName) + } + ans, err := uiutil.Confirm(message, true) + if err != nil { + return false, err + } + if !ans { + if mandatory { + return ans, errors.New(errS) + } + return ans, nil + } + if newInst { + rootCmd := cmd.Root() + // The create command shows the template chooser UI, etc. + rootCmd.SetArgs([]string{"create", instName}) + if err := rootCmd.Execute(); err != nil { + return ans, err + } + } + rootCmd := cmd.Root() + // The start command reconciliates the networks, etc. + rootCmd.SetArgs([]string{"start", instName}) + return ans, rootCmd.Execute() +}