From b5ef9555ab52f2dfb6840fd0e01c32801f2a28a3 Mon Sep 17 00:00:00 2001 From: Arthur Sengileyev Date: Sun, 15 Jan 2023 19:12:37 +0200 Subject: [PATCH] Implement machine provider selection GetSystemDefaultProvider reworked to fetch provider value from the config file. Additional environment variable CONTAINERS_MACHINE_PROVIDER is supported to override the config for testing purposes. Signed-off-by: Arthur Sengileyev --- cmd/podman/machine/info.go | 5 +++- cmd/podman/machine/init.go | 6 +++-- cmd/podman/machine/inspect.go | 5 +++- cmd/podman/machine/list.go | 5 +++- cmd/podman/machine/machine.go | 5 +++- cmd/podman/machine/os/manager.go | 5 +++- cmd/podman/machine/platform.go | 28 ++++++++++++++++++++-- cmd/podman/machine/platform_windows.go | 32 ++++++++++++++++++++------ cmd/podman/machine/rm.go | 5 +++- cmd/podman/machine/set.go | 5 +++- cmd/podman/machine/ssh.go | 5 +++- cmd/podman/machine/start.go | 6 ++++- cmd/podman/machine/stop.go | 5 +++- cmd/podman/system/reset_machine.go | 5 +++- pkg/machine/config.go | 18 +++++++++++++++ 15 files changed, 118 insertions(+), 22 deletions(-) diff --git a/cmd/podman/machine/info.go b/cmd/podman/machine/info.go index 888728c89e74..fab6e329a958 100644 --- a/cmd/podman/machine/info.go +++ b/cmd/podman/machine/info.go @@ -101,7 +101,10 @@ func hostInfo() (*entities.MachineHostInfo, error) { host.Arch = runtime.GOARCH host.OS = runtime.GOOS - provider := GetSystemDefaultProvider() + provider, err := GetSystemProvider() + if err != nil { + return nil, err + } var listOpts machine.ListOptions listResponse, err := provider.List(listOpts) if err != nil { diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go index 959cef2bd99f..c865ddffcea9 100644 --- a/cmd/podman/machine/init.go +++ b/cmd/podman/machine/init.go @@ -30,7 +30,6 @@ var ( initOptionalFlags = InitOptionalFlags{} defaultMachineName = machine.DefaultMachineName now bool - defaultProvider = GetSystemDefaultProvider() ) // Flags which have a meaning when unspecified that differs from the flag default @@ -129,7 +128,10 @@ func initMachine(cmd *cobra.Command, args []string) error { vm machine.VM ) - provider := defaultProvider + provider, err := GetSystemProvider() + if err != nil { + return err + } initOpts.Name = defaultMachineName if len(args) > 0 { if len(args[0]) > maxMachineNameSize { diff --git a/cmd/podman/machine/inspect.go b/cmd/podman/machine/inspect.go index 410bb3889863..893cb228a0fb 100644 --- a/cmd/podman/machine/inspect.go +++ b/cmd/podman/machine/inspect.go @@ -51,7 +51,10 @@ func inspect(cmd *cobra.Command, args []string) error { args = append(args, defaultMachineName) } vms := make([]machine.InspectInfo, 0, len(args)) - provider := GetSystemDefaultProvider() + provider, err := GetSystemProvider() + if err != nil { + return err + } for _, vmName := range args { vm, err := provider.LoadVMByName(vmName) if err != nil { diff --git a/cmd/podman/machine/list.go b/cmd/podman/machine/list.go index ac87bfa64792..6d9088b922fc 100644 --- a/cmd/podman/machine/list.go +++ b/cmd/podman/machine/list.go @@ -66,7 +66,10 @@ func list(cmd *cobra.Command, args []string) error { err error ) - provider := GetSystemDefaultProvider() + provider, err := GetSystemProvider() + if err != nil { + return err + } listResponse, err = provider.List(opts) if err != nil { return fmt.Errorf("listing vms: %w", err) diff --git a/cmd/podman/machine/machine.go b/cmd/podman/machine/machine.go index 0618337cce21..7c13f24c583b 100644 --- a/cmd/podman/machine/machine.go +++ b/cmd/podman/machine/machine.go @@ -64,7 +64,10 @@ func autocompleteMachine(cmd *cobra.Command, args []string, toComplete string) ( func getMachines(toComplete string) ([]string, cobra.ShellCompDirective) { suggestions := []string{} - provider := GetSystemDefaultProvider() + provider, err := GetSystemProvider() + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } machines, err := provider.List(machine.ListOptions{}) if err != nil { cobra.CompErrorln(err.Error()) diff --git a/cmd/podman/machine/os/manager.go b/cmd/podman/machine/os/manager.go index b6f9bd4cadba..4d4af9b5bffd 100644 --- a/cmd/podman/machine/os/manager.go +++ b/cmd/podman/machine/os/manager.go @@ -48,7 +48,10 @@ func machineOSManager(opts ManagerOpts) (pkgOS.Manager, error) { if opts.VMName == "" { vmName = pkgMachine.DefaultMachineName } - provider := machine.GetSystemDefaultProvider() + provider, err := machine.GetSystemProvider() + if err != nil { + return nil, err + } vm, err := provider.LoadVMByName(vmName) if err != nil { return nil, err diff --git a/cmd/podman/machine/platform.go b/cmd/podman/machine/platform.go index 9e951326feb2..67b5543065dd 100644 --- a/cmd/podman/machine/platform.go +++ b/cmd/podman/machine/platform.go @@ -4,10 +4,34 @@ package machine import ( + "fmt" + "os" + + "github.com/containers/common/pkg/config" "github.com/containers/podman/v4/pkg/machine" "github.com/containers/podman/v4/pkg/machine/qemu" + "github.com/sirupsen/logrus" ) -func GetSystemDefaultProvider() machine.VirtProvider { - return qemu.GetVirtualizationProvider() +func GetSystemProvider() (machine.VirtProvider, error) { + cfg, err := config.Default() + if err != nil { + return nil, err + } + provider := cfg.Machine.Provider + if providerOverride, found := os.LookupEnv("CONTAINERS_MACHINE_PROVIDER"); found { + provider = providerOverride + } + resolvedVMType, err := machine.ParseVMType(provider, machine.QemuVirt) + if err != nil { + return nil, err + } + + logrus.Debugf("Using Podman machine with `%s` virtualization provider", resolvedVMType.String()) + switch resolvedVMType { + case machine.QemuVirt: + return qemu.GetVirtualizationProvider(), nil + default: + return nil, fmt.Errorf("unsupported virtualization provider: `%s`", resolvedVMType.String()) + } } diff --git a/cmd/podman/machine/platform_windows.go b/cmd/podman/machine/platform_windows.go index b0956e24433f..88a5a3531a38 100644 --- a/cmd/podman/machine/platform_windows.go +++ b/cmd/podman/machine/platform_windows.go @@ -1,19 +1,37 @@ package machine import ( + "fmt" "os" + "github.com/containers/common/pkg/config" "github.com/containers/podman/v4/pkg/machine" "github.com/containers/podman/v4/pkg/machine/hyperv" "github.com/containers/podman/v4/pkg/machine/wsl" + "github.com/sirupsen/logrus" ) -func GetSystemDefaultProvider() machine.VirtProvider { - // This is a work-around for default provider on windows while - // hyperv is one developer. - // TODO this needs to be changed back - if _, exists := os.LookupEnv("HYPERV"); exists { - return hyperv.GetVirtualizationProvider() +func GetSystemProvider() (machine.VirtProvider, error) { + cfg, err := config.Default() + if err != nil { + return nil, err + } + provider := cfg.Machine.Provider + if providerOverride, found := os.LookupEnv("CONTAINERS_MACHINE_PROVIDER"); found { + provider = providerOverride + } + resolvedVMType, err := machine.ParseVMType(provider, machine.WSLVirt) + if err != nil { + return nil, err + } + + logrus.Debugf("Using Podman machine with `%s` virtualization provider", resolvedVMType.String()) + switch resolvedVMType { + case machine.WSLVirt: + return wsl.GetWSLProvider(), nil + case machine.HyperVVirt: + return hyperv.GetVirtualizationProvider(), nil + default: + return nil, fmt.Errorf("unsupported virtualization provider: `%s`", resolvedVMType.String()) } - return wsl.GetWSLProvider() } diff --git a/cmd/podman/machine/rm.go b/cmd/podman/machine/rm.go index 6418b914100e..1ea32603c60b 100644 --- a/cmd/podman/machine/rm.go +++ b/cmd/podman/machine/rm.go @@ -63,7 +63,10 @@ func rm(_ *cobra.Command, args []string) error { vmName = args[0] } - provider := GetSystemDefaultProvider() + provider, err := GetSystemProvider() + if err != nil { + return err + } vm, err = provider.LoadVMByName(vmName) if err != nil { return err diff --git a/cmd/podman/machine/set.go b/cmd/podman/machine/set.go index 5c933ea49105..70d3a0f01752 100644 --- a/cmd/podman/machine/set.go +++ b/cmd/podman/machine/set.go @@ -89,7 +89,10 @@ func setMachine(cmd *cobra.Command, args []string) error { if len(args) > 0 && len(args[0]) > 0 { vmName = args[0] } - provider := GetSystemDefaultProvider() + provider, err := GetSystemProvider() + if err != nil { + return err + } vm, err = provider.LoadVMByName(vmName) if err != nil { return err diff --git a/cmd/podman/machine/ssh.go b/cmd/podman/machine/ssh.go index 1cadce916ad9..083c3a97f495 100644 --- a/cmd/podman/machine/ssh.go +++ b/cmd/podman/machine/ssh.go @@ -53,7 +53,10 @@ func ssh(cmd *cobra.Command, args []string) error { // Set the VM to default vmName := defaultMachineName - provider := GetSystemDefaultProvider() + provider, err := GetSystemProvider() + if err != nil { + return err + } // If len is greater than 0, it means we may have been // provided the VM name. If so, we check. The VM name, diff --git a/cmd/podman/machine/start.go b/cmd/podman/machine/start.go index d7a642536ad2..4dd4f7d4a17a 100644 --- a/cmd/podman/machine/start.go +++ b/cmd/podman/machine/start.go @@ -53,7 +53,11 @@ func start(_ *cobra.Command, args []string) error { vmName = args[0] } - provider := GetSystemDefaultProvider() + provider, err := GetSystemProvider() + if err != nil { + return err + } + vm, err = provider.LoadVMByName(vmName) if err != nil { return err diff --git a/cmd/podman/machine/stop.go b/cmd/podman/machine/stop.go index ce87a44c4901..5d10ce71aa01 100644 --- a/cmd/podman/machine/stop.go +++ b/cmd/podman/machine/stop.go @@ -42,7 +42,10 @@ func stop(cmd *cobra.Command, args []string) error { if len(args) > 0 && len(args[0]) > 0 { vmName = args[0] } - provider := GetSystemDefaultProvider() + provider, err := GetSystemProvider() + if err != nil { + return err + } vm, err = provider.LoadVMByName(vmName) if err != nil { return err diff --git a/cmd/podman/system/reset_machine.go b/cmd/podman/system/reset_machine.go index a07b4fb8301d..4994b422b6bc 100644 --- a/cmd/podman/system/reset_machine.go +++ b/cmd/podman/system/reset_machine.go @@ -8,6 +8,9 @@ import ( ) func resetMachine() error { - provider := cmdMach.GetSystemDefaultProvider() + provider, err := cmdMach.GetSystemProvider() + if err != nil { + return err + } return provider.RemoveAndCleanMachines() } diff --git a/pkg/machine/config.go b/pkg/machine/config.go index 5cd44bb71200..04ed7929944f 100644 --- a/pkg/machine/config.go +++ b/pkg/machine/config.go @@ -10,6 +10,7 @@ import ( "net/url" "os" "path/filepath" + "strings" "time" "github.com/containers/storage/pkg/homedir" @@ -413,3 +414,20 @@ const ( MachineLocal DockerGlobal ) + +func ParseVMType(input string, emptyFallback VMType) (VMType, error) { + switch strings.TrimSpace(strings.ToLower(input)) { + case "qemu": + return QemuVirt, nil + case "wsl": + return WSLVirt, nil + case "applehv": + return AppleHvVirt, nil + case "hyperv": + return HyperVVirt, nil + case "": + return emptyFallback, nil + default: + return QemuVirt, fmt.Errorf("unknown VMType `%s`", input) + } +}