diff --git a/pkg/instance/start.go b/pkg/instance/start.go index e544a1e2e98..ec118772013 100644 --- a/pkg/instance/start.go +++ b/pkg/instance/start.go @@ -12,13 +12,11 @@ import ( "os" "os/exec" "path/filepath" - "syscall" "text/template" "time" "github.com/docker/go-units" "github.com/lima-vm/go-qcow2reader" - "github.com/mattn/go-isatty" "github.com/sirupsen/logrus" "github.com/lima-vm/lima/v2/pkg/downloader" @@ -29,7 +27,6 @@ import ( hostagentevents "github.com/lima-vm/lima/v2/pkg/hostagent/events" "github.com/lima-vm/lima/v2/pkg/imgutil/proxyimgutil" "github.com/lima-vm/lima/v2/pkg/limayaml" - "github.com/lima-vm/lima/v2/pkg/osutil" "github.com/lima-vm/lima/v2/pkg/registry" "github.com/lima-vm/lima/v2/pkg/store" "github.com/lima-vm/lima/v2/pkg/store/filenames" @@ -253,25 +250,7 @@ func Start(ctx context.Context, inst *store.Instance, limactl string, launchHost begin := time.Now() // used for logrus propagation if launchHostAgentForeground { - logrus.Info("Running the host agent in the foreground") - if isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) { - // Write message to standard log files to avoid confusing users - message := "This log file is not used because `limactl start` was launched in the terminal with the `--foreground` option." - if _, err := haStdoutW.WriteString(message); err != nil { - return err - } - if _, err := haStderrW.WriteString(message); err != nil { - return err - } - } else { - if err := osutil.Dup2(int(haStdoutW.Fd()), syscall.Stdout); err != nil { - return err - } - if err := osutil.Dup2(int(haStderrW.Fd()), syscall.Stderr); err != nil { - return err - } - } - if err := syscall.Exec(limactl, haCmd.Args, haCmd.Environ()); err != nil { + if err := execHostAgentForeground(limactl, haCmd); err != nil { return err } } else if err := haCmd.Start(); err != nil { diff --git a/pkg/instance/start_unix.go b/pkg/instance/start_unix.go new file mode 100644 index 00000000000..93bf2ad2009 --- /dev/null +++ b/pkg/instance/start_unix.go @@ -0,0 +1,48 @@ +//go:build !windows + +// SPDX-FileCopyrightText: Copyright The Lima Authors +// SPDX-License-Identifier: Apache-2.0 + +package instance + +import ( + "fmt" + "os" + "os/exec" + "syscall" + + "github.com/mattn/go-isatty" + "github.com/sirupsen/logrus" + + "github.com/lima-vm/lima/v2/pkg/osutil" +) + +func execHostAgentForeground(limactl string, haCmd *exec.Cmd) error { + haStdoutW, ok := haCmd.Stdout.(*os.File) + if !ok { + return fmt.Errorf("expected haCmd.Stdout to be *os.File, got %T", haCmd.Stdout) + } + haStderrW, ok := haCmd.Stderr.(*os.File) + if !ok { + return fmt.Errorf("expected haCmd.Stderr to be *os.File, got %T", haCmd.Stderr) + } + logrus.Info("Running the host agent in the foreground") + if isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) { + // Write message to standard log files to avoid confusing users + message := "This log file is not used because `limactl start` was launched in the terminal with the `--foreground` option." + if _, err := haStdoutW.WriteString(message); err != nil { + return err + } + if _, err := haStderrW.WriteString(message); err != nil { + return err + } + } else { + if err := osutil.Dup2(int(haStdoutW.Fd()), syscall.Stdout); err != nil { + return err + } + if err := osutil.Dup2(int(haStderrW.Fd()), syscall.Stderr); err != nil { + return err + } + } + return syscall.Exec(limactl, haCmd.Args, haCmd.Environ()) +} diff --git a/pkg/instance/start_windows.go b/pkg/instance/start_windows.go new file mode 100644 index 00000000000..2f85c03aec9 --- /dev/null +++ b/pkg/instance/start_windows.go @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: Copyright The Lima Authors +// SPDX-License-Identifier: Apache-2.0 + +package instance + +import ( + "errors" + "os/exec" +) + +func execHostAgentForeground(_ string, _ *exec.Cmd) error { + return errors.New("`limactl start --foreground` is not supported on Windows") +} diff --git a/pkg/qemuimgutil/qemuimgutil.go b/pkg/qemuimgutil/qemuimgutil.go index fc065450c59..8872eb56d52 100644 --- a/pkg/qemuimgutil/qemuimgutil.go +++ b/pkg/qemuimgutil/qemuimgutil.go @@ -103,6 +103,31 @@ type InfoFormatSpecificDataVmdkExtent struct { } func convertToRaw(source, dest string) error { + if source != dest { + return execQemuImgConvert(source, dest) + } + + // If source == dest, we need to use a temporary file to avoid file locking issues + + info, err := getInfo(source) + if err != nil { + return fmt.Errorf("failed to get info for source disk %q: %w", source, err) + } + if info.Format == "raw" { + return nil + } + + tempFile := dest + ".lima-qemu-convert.tmp" + defer os.Remove(tempFile) + + if err := execQemuImgConvert(source, tempFile); err != nil { + return err + } + + return os.Rename(tempFile, dest) +} + +func execQemuImgConvert(source, dest string) error { var stdout, stderr bytes.Buffer cmd := exec.Command("qemu-img", "convert", "-O", "raw", source, dest) cmd.Stdout = &stdout