aboutsummaryrefslogtreecommitdiff
path: root/pkg/machine
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/machine')
-rw-r--r--pkg/machine/config.go7
-rw-r--r--pkg/machine/fcos.go2
-rw-r--r--pkg/machine/keys.go11
-rw-r--r--pkg/machine/qemu/machine.go39
-rw-r--r--pkg/machine/qemu/options_darwin_arm64.go23
-rw-r--r--pkg/machine/wsl/machine.go1
6 files changed, 70 insertions, 13 deletions
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index abbebc9f9..fcc129338 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -42,7 +42,9 @@ const (
// Running indicates the qemu vm is running.
Running Status = "running"
// Stopped indicates the vm has stopped.
- Stopped Status = "stopped"
+ Stopped Status = "stopped"
+ // Starting indicated the vm is in the process of starting
+ Starting Status = "starting"
DefaultMachineName string = "podman-machine-default"
)
@@ -62,7 +64,7 @@ var (
DefaultIgnitionUserName = "core"
ErrNoSuchVM = errors.New("VM does not exist")
ErrVMAlreadyExists = errors.New("VM already exists")
- ErrVMAlreadyRunning = errors.New("VM already running")
+ ErrVMAlreadyRunning = errors.New("VM already running or starting")
ErrMultipleActiveVM = errors.New("only one VM can be active at a time")
ForwarderBinaryName = "gvproxy"
)
@@ -88,6 +90,7 @@ type ListResponse struct {
CreatedAt time.Time
LastUp time.Time
Running bool
+ Starting bool
Stream string
VMType string
CPUs uint64
diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go
index 77427139a..59ef6d975 100644
--- a/pkg/machine/fcos.go
+++ b/pkg/machine/fcos.go
@@ -139,7 +139,7 @@ func getStreamURL(streamType string) url2.URL {
// This should get Exported and stay put as it will apply to all fcos downloads
// getFCOS parses fedoraCoreOS's stream and returns the image download URL and the release version
-func GetFCOSDownload(imageStream string) (*FcosDownloadInfo, error) { //nolint:staticcheck
+func GetFCOSDownload(imageStream string) (*FcosDownloadInfo, error) {
var (
fcosstable stream.Stream
altMeta release.Release
diff --git a/pkg/machine/keys.go b/pkg/machine/keys.go
index 15c1f73d8..45d9801cc 100644
--- a/pkg/machine/keys.go
+++ b/pkg/machine/keys.go
@@ -59,7 +59,16 @@ func generatekeysPrefix(dir string, file string, passThru bool, prefix ...string
args := append([]string{}, prefix[1:]...)
args = append(args, sshCommand...)
args = append(args, file)
- cmd := exec.Command(prefix[0], args...)
+
+ binary, err := exec.LookPath(prefix[0])
+ if err != nil {
+ return err
+ }
+ binary, err = filepath.Abs(binary)
+ if err != nil {
+ return err
+ }
+ cmd := exec.Command(binary, args...)
cmd.Dir = dir
if passThru {
cmd.Stdin = os.Stdin
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index b9f23662e..288b2eeb0 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -16,9 +16,11 @@ import (
"net/url"
"os"
"os/exec"
+ "os/signal"
"path/filepath"
"strconv"
"strings"
+ "syscall"
"time"
"github.com/containers/common/pkg/config"
@@ -484,12 +486,26 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
if err := v.writeConfig(); err != nil {
return fmt.Errorf("writing JSON file: %w", err)
}
- defer func() {
+ doneStarting := func() {
v.Starting = false
if err := v.writeConfig(); err != nil {
logrus.Errorf("Writing JSON file: %v", err)
}
+ }
+ defer doneStarting()
+
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, os.Interrupt, syscall.SIGTERM)
+ go func() {
+ _, ok := <-c
+ if !ok {
+ return
+ }
+ doneStarting()
+ os.Exit(1)
}()
+ defer close(c)
+
if v.isIncompatible() {
logrus.Errorf("machine %q is incompatible with this release of podman and needs to be recreated, starting for recovery only", v.Name)
}
@@ -770,7 +786,7 @@ func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error {
if err := qmpMonitor.Disconnect(); err != nil {
// FIXME: this error should probably be returned
- return nil // nolint: nilerr
+ return nil //nolint: nilerr
}
disconnected = true
@@ -831,8 +847,14 @@ func (v *MachineVM) Remove(_ string, opts machine.RemoveOptions) (string, func()
if err != nil {
return "", nil, err
}
- if state == machine.Running && !opts.Force {
- return "", nil, errors.Errorf("running vm %q cannot be destroyed", v.Name)
+ if state == machine.Running {
+ if !opts.Force {
+ return "", nil, errors.Errorf("running vm %q cannot be destroyed", v.Name)
+ }
+ err := v.Stop(v.Name, machine.StopOptions{})
+ if err != nil {
+ return "", nil, err
+ }
}
// Collect all the files that need to be destroyed
@@ -904,7 +926,7 @@ func (v *MachineVM) State(bypass bool) (machine.Status, error) {
}
// Check if we can dial it
if v.Starting && !bypass {
- return "", nil
+ return machine.Starting, nil
}
monitor, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address.GetPath(), v.QMPMonitor.Timeout)
if err != nil {
@@ -1075,8 +1097,11 @@ func getVMInfos() ([]*machine.ListResponse, error) {
return err
}
}
- if state == machine.Running {
+ switch state {
+ case machine.Running:
listEntry.Running = true
+ case machine.Starting:
+ listEntry.Starting = true
}
listed = append(listed, listEntry)
@@ -1109,7 +1134,7 @@ func (p *Provider) CheckExclusiveActiveVM() (bool, string, error) {
return false, "", errors.Wrap(err, "error checking VM active")
}
for _, vm := range vms {
- if vm.Running {
+ if vm.Running || vm.Starting {
return true, vm.Name, nil
}
}
diff --git a/pkg/machine/qemu/options_darwin_arm64.go b/pkg/machine/qemu/options_darwin_arm64.go
index 4c954af00..d75237938 100644
--- a/pkg/machine/qemu/options_darwin_arm64.go
+++ b/pkg/machine/qemu/options_darwin_arm64.go
@@ -4,6 +4,8 @@ import (
"os"
"os/exec"
"path/filepath"
+
+ "github.com/containers/common/pkg/config"
)
var (
@@ -15,8 +17,8 @@ func (v *MachineVM) addArchOptions() []string {
opts := []string{
"-accel", "hvf",
"-accel", "tcg",
- "-cpu", "cortex-a57",
- "-M", "virt,highmem=off",
+ "-cpu", "host",
+ "-M", "virt,highmem=on",
"-drive", "file=" + getEdk2CodeFd("edk2-aarch64-code.fd") + ",if=pflash,format=raw,readonly=on",
"-drive", "file=" + ovmfDir + ",if=pflash,format=raw"}
return opts
@@ -38,6 +40,22 @@ func getOvmfDir(imagePath, vmName string) string {
}
/*
+ * When QEmu is installed in a non-default location in the system
+ * we can use the qemu-system-* binary path to figure the install
+ * location for Qemu and use it to look for edk2-code-fd
+ */
+func getEdk2CodeFdPathFromQemuBinaryPath() string {
+ cfg, err := config.Default()
+ if err == nil {
+ execPath, err := cfg.FindHelperBinary(QemuCommand, true)
+ if err == nil {
+ return filepath.Clean(filepath.Join(filepath.Dir(execPath), "..", "share", "qemu"))
+ }
+ }
+ return ""
+}
+
+/*
* QEmu can be installed in multiple locations on MacOS, especially on
* Apple Silicon systems. A build from source will likely install it in
* /usr/local/bin, whereas Homebrew package management standard is to
@@ -45,6 +63,7 @@ func getOvmfDir(imagePath, vmName string) string {
*/
func getEdk2CodeFd(name string) string {
dirs := []string{
+ getEdk2CodeFdPathFromQemuBinaryPath(),
"/opt/homebrew/opt/podman/libexec/share/qemu",
"/usr/local/share/qemu",
"/opt/homebrew/share/qemu",
diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go
index 06020aded..075f42cb2 100644
--- a/pkg/machine/wsl/machine.go
+++ b/pkg/machine/wsl/machine.go
@@ -1312,6 +1312,7 @@ func GetVMInfos() ([]*machine.ListResponse, error) {
listEntry.RemoteUsername = vm.RemoteUsername
listEntry.Port = vm.Port
listEntry.IdentityPath = vm.IdentityPath
+ listEntry.Starting = false
running := vm.isRunning()
listEntry.CreatedAt, listEntry.LastUp, _ = vm.updateTimeStamps(running)