summaryrefslogtreecommitdiff
path: root/pkg/machine
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/machine')
-rw-r--r--pkg/machine/config.go9
-rw-r--r--pkg/machine/fcos.go1
-rw-r--r--pkg/machine/fedora.go6
-rw-r--r--pkg/machine/ignition.go28
-rw-r--r--pkg/machine/ignition_darwin.go3
-rw-r--r--pkg/machine/ignition_schema.go1
-rw-r--r--pkg/machine/ignition_windows.go3
-rw-r--r--pkg/machine/keys.go1
-rw-r--r--pkg/machine/machine_unsupported.go1
-rw-r--r--pkg/machine/pull.go5
-rw-r--r--pkg/machine/qemu/config.go9
-rw-r--r--pkg/machine/qemu/machine.go193
-rw-r--r--pkg/machine/qemu/machine_unsupported.go1
-rw-r--r--pkg/machine/qemu/options_darwin_arm64.go1
-rw-r--r--pkg/machine/wsl/machine_unsupported.go1
15 files changed, 192 insertions, 71 deletions
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index efb1eda15..aaf8da872 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -1,3 +1,4 @@
+//go:build amd64 || arm64
// +build amd64 arm64
package machine
@@ -28,14 +29,16 @@ type InitOptions struct {
Username string
ReExec bool
Rootful bool
+ // The numberical userid of the user that called machine
+ UID string
}
type QemuMachineStatus = string
const (
- // Running indicates the qemu vm is running
+ // Running indicates the qemu vm is running.
Running QemuMachineStatus = "running"
- // Stopped indicates the vm has stopped
+ // Stopped indicates the vm has stopped.
Stopped QemuMachineStatus = "stopped"
DefaultMachineName string = "podman-machine-default"
)
@@ -144,7 +147,7 @@ func (rc RemoteConnectionType) MakeSSHURL(host, path, port, userName string) url
}
// GetDataDir returns the filepath where vm images should
-// live for podman-machine
+// live for podman-machine.
func GetDataDir(vmType string) (string, error) {
data, err := homedir.GetDataHome()
if err != nil {
diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go
index 4d3e2edf4..6215ae08f 100644
--- a/pkg/machine/fcos.go
+++ b/pkg/machine/fcos.go
@@ -1,3 +1,4 @@
+//go:build amd64 || arm64
// +build amd64 arm64
package machine
diff --git a/pkg/machine/fedora.go b/pkg/machine/fedora.go
index cd713dde7..bed45c6da 100644
--- a/pkg/machine/fedora.go
+++ b/pkg/machine/fedora.go
@@ -1,3 +1,4 @@
+//go:build amd64 || arm64
// +build amd64 arm64
package machine
@@ -58,7 +59,10 @@ func (f FedoraDownload) Get() *Download {
func (f FedoraDownload) HasUsableCache() (bool, error) {
info, err := os.Stat(f.LocalPath)
if err != nil {
- return false, nil
+ if errors.Is(err, os.ErrNotExist) {
+ return false, nil
+ }
+ return false, err
}
return info.Size() == f.Size, nil
}
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index 47b1836f0..b2dabb689 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -51,6 +51,7 @@ type DynamicIgnition struct {
Name string
Key string
TimeZone string
+ UID int
VMName string
WritePath string
}
@@ -63,12 +64,13 @@ func NewIgnitionFile(ign DynamicIgnition) error {
ignVersion := Ignition{
Version: "3.2.0",
}
-
ignPassword := Passwd{
Users: []PasswdUser{
{
Name: ign.Name,
SSHAuthorizedKeys: []SSHAuthorizedKey{SSHAuthorizedKey(ign.Key)},
+ // Set the UID of the core user inside the machine
+ UID: intToPtr(ign.UID),
},
{
Name: "root",
@@ -289,9 +291,7 @@ func getDirs(usrName string) []Directory {
}
func getFiles(usrName string) []File {
- var (
- files []File
- )
+ files := make([]File, 0)
lingerExample := `[Unit]
Description=A systemd user unit demo
@@ -310,6 +310,7 @@ machine_enabled=true
delegateConf := `[Service]
Delegate=memory pids cpu io
`
+ subUID := `%s:100000:1000000`
// Add a fake systemd service to get the user socket rolling
files = append(files, File{
@@ -344,6 +345,25 @@ Delegate=memory pids cpu io
},
})
+ // Setup /etc/subuid and /etc/subgid
+ for _, sub := range []string{"/etc/subuid", "/etc/subgid"} {
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp("root"),
+ Path: sub,
+ User: getNodeUsr("root"),
+ Overwrite: boolToPtr(true),
+ },
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ Contents: Resource{
+ Source: encodeDataURLPtr(fmt.Sprintf(subUID, usrName)),
+ },
+ Mode: intToPtr(0744),
+ },
+ })
+ }
+
// Set delegate.conf so cpu,io subsystem is delegated to non-root users as well for cgroupv2
// by default
files = append(files, File{
diff --git a/pkg/machine/ignition_darwin.go b/pkg/machine/ignition_darwin.go
index 9ede4b026..b9fbf218d 100644
--- a/pkg/machine/ignition_darwin.go
+++ b/pkg/machine/ignition_darwin.go
@@ -1,4 +1,5 @@
-//+build darwin
+//go:build darwin
+// +build darwin
package machine
diff --git a/pkg/machine/ignition_schema.go b/pkg/machine/ignition_schema.go
index 8cfb0d04e..d6b86229c 100644
--- a/pkg/machine/ignition_schema.go
+++ b/pkg/machine/ignition_schema.go
@@ -1,3 +1,4 @@
+//go:build amd64 || arm64
// +build amd64 arm64
package machine
diff --git a/pkg/machine/ignition_windows.go b/pkg/machine/ignition_windows.go
index c0de48bd3..0fcc06273 100644
--- a/pkg/machine/ignition_windows.go
+++ b/pkg/machine/ignition_windows.go
@@ -1,4 +1,5 @@
-//+build windows
+//go:build windows
+// +build windows
package machine
diff --git a/pkg/machine/keys.go b/pkg/machine/keys.go
index 711b091f0..15c1f73d8 100644
--- a/pkg/machine/keys.go
+++ b/pkg/machine/keys.go
@@ -1,3 +1,4 @@
+//go:build amd64 || arm64
// +build amd64 arm64
package machine
diff --git a/pkg/machine/machine_unsupported.go b/pkg/machine/machine_unsupported.go
index da1437984..a12140e16 100644
--- a/pkg/machine/machine_unsupported.go
+++ b/pkg/machine/machine_unsupported.go
@@ -1,3 +1,4 @@
+//go:build !amd64 && !arm64
// +build !amd64,!arm64
package machine
diff --git a/pkg/machine/pull.go b/pkg/machine/pull.go
index 280b47f96..26abedfcd 100644
--- a/pkg/machine/pull.go
+++ b/pkg/machine/pull.go
@@ -1,3 +1,4 @@
+//go:build amd64 || arm64
// +build amd64 arm64
package machine
@@ -19,8 +20,8 @@ import (
"github.com/containers/storage/pkg/archive"
"github.com/sirupsen/logrus"
"github.com/ulikunitz/xz"
- "github.com/vbauerster/mpb/v6"
- "github.com/vbauerster/mpb/v6/decor"
+ "github.com/vbauerster/mpb/v7"
+ "github.com/vbauerster/mpb/v7/decor"
)
// GenericDownload is used when a user provides a URL
diff --git a/pkg/machine/qemu/config.go b/pkg/machine/qemu/config.go
index c619b7dd4..211d96ccb 100644
--- a/pkg/machine/qemu/config.go
+++ b/pkg/machine/qemu/config.go
@@ -1,8 +1,11 @@
+//go:build (amd64 && !windows) || (arm64 && !windows)
// +build amd64,!windows arm64,!windows
package qemu
-import "time"
+import (
+ "time"
+)
type Provider struct{}
@@ -35,6 +38,8 @@ type MachineVM struct {
RemoteUsername string
// Whether this machine should run in a rootful or rootless manner
Rootful bool
+ // UID is the numerical id of the user that called machine
+ UID int
}
type Mount struct {
@@ -56,6 +61,6 @@ type Monitor struct {
var (
// defaultQMPTimeout is the timeout duration for the
- // qmp monitor interactions
+ // qmp monitor interactions.
defaultQMPTimeout time.Duration = 2 * time.Second
)
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 9beec2173..3b14572a6 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -34,7 +34,7 @@ import (
var (
qemuProvider = &Provider{}
- // vmtype refers to qemu (vs libvirt, krun, etc)
+ // vmtype refers to qemu (vs libvirt, krun, etc).
vmtype = "qemu"
)
@@ -88,11 +88,16 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) {
vm.Memory = opts.Memory
vm.DiskSize = opts.DiskSize
- // Look up the executable
- execPath, err := exec.LookPath(QemuCommand)
+ // Find the qemu executable
+ cfg, err := config.Default()
+ if err != nil {
+ return nil, err
+ }
+ execPath, err := cfg.FindHelperBinary(QemuCommand, true)
if err != nil {
return nil, err
}
+
cmd := append([]string{execPath})
// Add memory
cmd = append(cmd, []string{"-m", strconv.Itoa(int(vm.Memory))}...)
@@ -129,7 +134,7 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) {
// LoadByName reads a json file that describes a known qemu vm
// and returns a vm instance
func (p *Provider) LoadVMByName(name string) (machine.VM, error) {
- vm := new(MachineVM)
+ vm := &MachineVM{UID: -1} // posix reserves -1, so use it to signify undefined
vmConfigDir, err := machine.GetConfDir(vmtype)
if err != nil {
return nil, err
@@ -245,12 +250,13 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
}
}
v.Mounts = mounts
+ v.UID = os.Getuid()
// Add location of bootable image
v.CmdLine = append(v.CmdLine, "-drive", "if=virtio,file="+v.ImagePath)
// This kind of stinks but no other way around this r/n
if len(opts.IgnitionPath) < 1 {
- uri := machine.SSHRemoteConnection.MakeSSHURL("localhost", "/run/user/1000/podman/podman.sock", strconv.Itoa(v.Port), v.RemoteUsername)
+ uri := machine.SSHRemoteConnection.MakeSSHURL("localhost", fmt.Sprintf("/run/user/%d/podman/podman.sock", v.UID), strconv.Itoa(v.Port), v.RemoteUsername)
uriRoot := machine.SSHRemoteConnection.MakeSSHURL("localhost", "/run/podman/podman.sock", strconv.Itoa(v.Port), "root")
identity := filepath.Join(sshDir, v.Name)
@@ -272,7 +278,9 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
fmt.Println("An ignition path was provided. No SSH connection was added to Podman")
}
// Write the JSON file
- v.writeConfig()
+ if err := v.writeConfig(); err != nil {
+ return false, fmt.Errorf("writing JSON file: %w", err)
+ }
// User has provided ignition file so keygen
// will be skipped.
@@ -296,7 +304,16 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
// only if the virtualdisk size is less than
// the given disk size
if opts.DiskSize<<(10*3) > originalDiskSize {
- resize := exec.Command("qemu-img", []string{"resize", v.ImagePath, strconv.Itoa(int(opts.DiskSize)) + "G"}...)
+ // Find the qemu executable
+ cfg, err := config.Default()
+ if err != nil {
+ return false, err
+ }
+ resizePath, err := cfg.FindHelperBinary("qemu-img", true)
+ if err != nil {
+ return false, err
+ }
+ resize := exec.Command(resizePath, []string{"resize", v.ImagePath, strconv.Itoa(int(opts.DiskSize)) + "G"}...)
resize.Stdout = os.Stdout
resize.Stderr = os.Stderr
if err := resize.Run(); err != nil {
@@ -319,6 +336,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
VMName: v.Name,
TimeZone: opts.TimeZone,
WritePath: v.IgnitionFilePath,
+ UID: v.UID,
}
err = machine.NewIgnitionFile(ign)
return err == nil, err
@@ -354,9 +372,13 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
conn net.Conn
err error
qemuSocketConn net.Conn
- wait time.Duration = time.Millisecond * 500
+ wait = time.Millisecond * 500
)
+ 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)
+ }
+
forwardSock, forwardState, err := v.startHostNetworking()
if err != nil {
return errors.Errorf("unable to start host networking: %q", err)
@@ -459,7 +481,17 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
for _, mount := range v.Mounts {
fmt.Printf("Mounting volume... %s:%s\n", mount.Source, mount.Target)
// create mountpoint directory if it doesn't exist
- err = v.SSH(name, machine.SSHOptions{Args: []string{"-q", "--", "sudo", "mkdir", "-p", mount.Target}})
+ // because / is immutable, we have to monkey around with permissions
+ // if we dont mount in /home or /mnt
+ args := []string{"-q", "--"}
+ if !strings.HasPrefix(mount.Target, "/home") || !strings.HasPrefix(mount.Target, "/mnt") {
+ args = append(args, "sudo", "chattr", "-i", "/", ";")
+ }
+ args = append(args, "sudo", "mkdir", "-p", mount.Target)
+ if !strings.HasPrefix(mount.Target, "/home") || !strings.HasPrefix(mount.Target, "/mnt") {
+ args = append(args, ";", "sudo", "chattr", "+i", "/", ";")
+ }
+ err = v.SSH(name, machine.SSHOptions{Args: args})
if err != nil {
return err
}
@@ -480,7 +512,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
}
}
- waitAPIAndPrintInfo(forwardState, forwardSock, v.Rootful, v.Name)
+ v.waitAPIAndPrintInfo(forwardState, forwardSock)
return nil
}
@@ -596,7 +628,8 @@ func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
}
if err := qmpMonitor.Disconnect(); err != nil {
- return nil
+ // FIXME: this error should probably be returned
+ return nil // nolint: nilerr
}
disconnected = true
@@ -653,7 +686,7 @@ func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, fun
if err != nil {
return "", nil, err
}
- if running {
+ if running && !opts.Force {
return "", nil, errors.Errorf("running vm %q cannot be destroyed", v.Name)
}
@@ -667,6 +700,11 @@ func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, fun
if !opts.SaveImage {
files = append(files, v.ImagePath)
}
+ socketPath, err := v.getForwardSocketPath()
+ if err != nil {
+ logrus.Error(err)
+ }
+ files = append(files, socketPath)
files = append(files, v.archRemovalFiles()...)
if err := machine.RemoveConnection(v.Name); err != nil {
@@ -720,7 +758,8 @@ func (v *MachineVM) isRunning() (bool, error) {
// Check if we can dial it
monitor, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address, v.QMPMonitor.Timeout)
if err != nil {
- return false, nil
+ // FIXME: this error should probably be returned
+ return false, nil // nolint: nilerr
}
if err := monitor.Connect(); err != nil {
return false, err
@@ -743,7 +782,7 @@ func (v *MachineVM) isRunning() (bool, error) {
func (v *MachineVM) isListening() bool {
// Check if we can dial it
- conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", "localhost", v.Port), 10*time.Millisecond)
+ conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", v.Port), 10*time.Millisecond)
if err != nil {
return false
}
@@ -790,7 +829,16 @@ func (v *MachineVM) SSH(name string, opts machine.SSHOptions) error {
// executes qemu-image info to get the virtual disk size
// of the diskimage
func getDiskSize(path string) (uint64, error) {
- diskInfo := exec.Command("qemu-img", "info", "--output", "json", path)
+ // Find the qemu executable
+ cfg, err := config.Default()
+ if err != nil {
+ return 0, err
+ }
+ qemuPathDir, err := cfg.FindHelperBinary("qemu-img", true)
+ if err != nil {
+ return 0, err
+ }
+ diskInfo := exec.Command(qemuPathDir, "info", "--output", "json", path)
stdout, err := diskInfo.StdoutPipe()
if err != nil {
return 0, err
@@ -935,7 +983,11 @@ func (v *MachineVM) startHostNetworking() (string, apiForwardingState, error) {
// Add the ssh port
cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", v.Port)}...)
- cmd, forwardSock, state := v.setupAPIForwarding(cmd)
+ var forwardSock string
+ var state apiForwardingState
+ if !v.isIncompatible() {
+ cmd, forwardSock, state = v.setupAPIForwarding(cmd)
+ }
if logrus.GetLevel() == logrus.DebugLevel {
cmd = append(cmd, "--debug")
@@ -952,7 +1004,7 @@ func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwa
return cmd, "", noForwarding
}
- destSock := "/run/user/1000/podman/podman.sock"
+ destSock := fmt.Sprintf("/run/user/%d/podman/podman.sock", v.UID)
forwardUser := "core"
if v.Rootful {
@@ -1003,6 +1055,10 @@ func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwa
return cmd, dockerSock, dockerGlobal
}
+func (v *MachineVM) isIncompatible() bool {
+ return v.UID == -1
+}
+
func (v *MachineVM) getForwardSocketPath() (string, error) {
path, err := machine.GetDataDir(v.Name)
if err != nil {
@@ -1045,10 +1101,13 @@ func waitAndPingAPI(sock string) {
Transport: &http.Transport{
DialContext: func(context.Context, string, string) (net.Conn, error) {
con, err := net.DialTimeout("unix", sock, apiUpTimeout)
- if err == nil {
- con.SetDeadline(time.Now().Add(apiUpTimeout))
+ if err != nil {
+ return nil, err
+ }
+ if err := con.SetDeadline(time.Now().Add(apiUpTimeout)); err != nil {
+ return nil, err
}
- return con, err
+ return con, nil
},
},
}
@@ -1062,46 +1121,66 @@ func waitAndPingAPI(sock string) {
}
}
-func waitAPIAndPrintInfo(forwardState apiForwardingState, forwardSock string, rootFul bool, name string) {
- if forwardState != noForwarding {
- waitAndPingAPI(forwardSock)
- if !rootFul {
- fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
- fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
- fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
-
- suffix := ""
- if name != machine.DefaultMachineName {
- suffix = " " + name
- }
- fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
- }
+func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forwardSock string) {
+ suffix := ""
+ if v.Name != machine.DefaultMachineName {
+ suffix = " " + v.Name
+ }
- fmt.Printf("API forwarding listening on: %s\n", forwardSock)
- if forwardState == dockerGlobal {
- fmt.Printf("Docker API clients default to this address. You do not need to set DOCKER_HOST.\n\n")
- } else {
- stillString := "still "
- switch forwardState {
- case notInstalled:
- fmt.Printf("\nThe system helper service is not installed; the default Docker API socket\n")
- fmt.Printf("address can't be used by podman. ")
- if helper := findClaimHelper(); len(helper) > 0 {
- fmt.Printf("If you would like to install it run the\nfollowing command:\n")
- fmt.Printf("\n\tsudo %s install\n\n", helper)
- }
- case machineLocal:
- fmt.Printf("\nAnother process was listening on the default Docker API socket address.\n")
- case claimUnsupported:
- fallthrough
- default:
- stillString = ""
- }
+ if v.isIncompatible() {
+ fmt.Fprintf(os.Stderr, "\n!!! ACTION REQUIRED: INCOMPATIBLE MACHINE !!!\n")
+
+ fmt.Fprintf(os.Stderr, "\nThis machine was created by an older podman release that is incompatible\n")
+ fmt.Fprintf(os.Stderr, "with this release of podman. It has been started in a limited operational\n")
+ fmt.Fprintf(os.Stderr, "mode to allow you to copy any necessary files before recreating it. This\n")
+ fmt.Fprintf(os.Stderr, "can be accomplished with the following commands:\n\n")
+ fmt.Fprintf(os.Stderr, "\t# Login and copy desired files (Optional)\n")
+ fmt.Fprintf(os.Stderr, "\t# podman machine ssh%s tar cvPf - /path/to/files > backup.tar\n\n", suffix)
+ fmt.Fprintf(os.Stderr, "\t# Recreate machine (DESTRUCTIVE!) \n")
+ fmt.Fprintf(os.Stderr, "\tpodman machine stop%s\n", suffix)
+ fmt.Fprintf(os.Stderr, "\tpodman machine rm -f%s\n", suffix)
+ fmt.Fprintf(os.Stderr, "\tpodman machine init --now%s\n\n", suffix)
+ fmt.Fprintf(os.Stderr, "\t# Copy back files (Optional)\n")
+ fmt.Fprintf(os.Stderr, "\t# cat backup.tar | podman machine ssh%s tar xvPf - \n\n", suffix)
+ }
+
+ if forwardState == noForwarding {
+ return
+ }
- fmt.Printf("You can %sconnect Docker API clients by setting DOCKER_HOST using the\n", stillString)
- fmt.Printf("following command in your terminal session:\n")
- fmt.Printf("\n\texport DOCKER_HOST='unix://%s'\n\n", forwardSock)
+ waitAndPingAPI(forwardSock)
+ if !v.Rootful {
+ fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
+ fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
+ fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
+ fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
+ }
+
+ fmt.Printf("API forwarding listening on: %s\n", forwardSock)
+ if forwardState == dockerGlobal {
+ fmt.Printf("Docker API clients default to this address. You do not need to set DOCKER_HOST.\n\n")
+ } else {
+ stillString := "still "
+ switch forwardState {
+ case notInstalled:
+ fmt.Printf("\nThe system helper service is not installed; the default Docker API socket\n")
+ fmt.Printf("address can't be used by podman. ")
+ if helper := findClaimHelper(); len(helper) > 0 {
+ fmt.Printf("If you would like to install it run the\nfollowing commands:\n")
+ fmt.Printf("\n\tsudo %s install\n", helper)
+ fmt.Printf("\tpodman machine stop%s; podman machine start%s\n\n", suffix, suffix)
+ }
+ case machineLocal:
+ fmt.Printf("\nAnother process was listening on the default Docker API socket address.\n")
+ case claimUnsupported:
+ fallthrough
+ default:
+ stillString = ""
}
+
+ fmt.Printf("You can %sconnect Docker API clients by setting DOCKER_HOST using the\n", stillString)
+ fmt.Printf("following command in your terminal session:\n")
+ fmt.Printf("\n\texport DOCKER_HOST='unix://%s'\n\n", forwardSock)
}
}
diff --git a/pkg/machine/qemu/machine_unsupported.go b/pkg/machine/qemu/machine_unsupported.go
index e3ce05e3d..794e710f9 100644
--- a/pkg/machine/qemu/machine_unsupported.go
+++ b/pkg/machine/qemu/machine_unsupported.go
@@ -1,3 +1,4 @@
+//go:build (!amd64 && !arm64) || windows
// +build !amd64,!arm64 windows
package qemu
diff --git a/pkg/machine/qemu/options_darwin_arm64.go b/pkg/machine/qemu/options_darwin_arm64.go
index 727a275d2..5b6cdc86d 100644
--- a/pkg/machine/qemu/options_darwin_arm64.go
+++ b/pkg/machine/qemu/options_darwin_arm64.go
@@ -45,6 +45,7 @@ func getOvmfDir(imagePath, vmName string) string {
*/
func getEdk2CodeFd(name string) string {
dirs := []string{
+ "/opt/homebrew/opt/podman/libexec/share/qemu",
"/usr/local/share/qemu",
"/opt/homebrew/share/qemu",
}
diff --git a/pkg/machine/wsl/machine_unsupported.go b/pkg/machine/wsl/machine_unsupported.go
index 043c5d729..856f9dd0c 100644
--- a/pkg/machine/wsl/machine_unsupported.go
+++ b/pkg/machine/wsl/machine_unsupported.go
@@ -1,3 +1,4 @@
+//go:build !windows
// +build !windows
package wsl