Provider obfuscation in command line

For Podman 6, we still have providers and will continue to have a default provider for each platform.  But where a platform has multiple providers, we want users to be able to cross provider boudnaries imposed in Podman 4/5.  The key change is to look up virtual machines by name, as before, but to then also iterate all possible providers.  As of this PR, init will still only create with the default provider, but a subsequent PR will introdouce an provider override.

I also removed the "--all-providers" command line option on `podman
machine ls` because it no longer makes sense. And I marked the all
provider list test to be skipped.

Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
Brent Baude
2025-10-01 14:27:29 -05:00
parent 5a0b74b13e
commit 0f22c1c772
19 changed files with 159 additions and 213 deletions

View File

@@ -14,7 +14,7 @@ import (
"github.com/containers/podman/v6/pkg/copy"
"github.com/containers/podman/v6/pkg/machine"
"github.com/containers/podman/v6/pkg/machine/define"
"github.com/containers/podman/v6/pkg/machine/env"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/containers/podman/v6/pkg/specgen"
"github.com/spf13/cobra"
@@ -78,12 +78,16 @@ func cp(_ *cobra.Command, args []string) error {
destPath = args[1]
}
mc, err := resolveMachine(srcMachine, destMachine)
vmName, err := resolveMachineName(srcMachine, destMachine)
if err != nil {
return err
}
mc, vmProvider, err := shim.VMExists(vmName)
if err != nil {
return err
}
state, err := provider.State(mc, false)
state, err := vmProvider.State(mc, false)
if err != nil {
return err
}
@@ -135,25 +139,18 @@ func localhostSSHCopy(opts *cpOptions) error {
return cmd.Run()
}
func resolveMachine(srcMachine, destMachine string) (*vmconfigs.MachineConfig, error) {
func resolveMachineName(srcMachine, destMachine string) (string, error) {
if len(srcMachine) > 0 && len(destMachine) > 0 {
return nil, errors.New("copying between two machines is unsupported")
return "", errors.New("copying between two machines is unsupported")
}
if len(srcMachine) == 0 && len(destMachine) == 0 {
return nil, errors.New("a machine name must prefix either the source path or destination path")
return "", errors.New("a machine name must prefix either the source path or destination path")
}
dirs, err := env.GetMachineDirs(provider.VMType())
if err != nil {
return nil, err
}
name := destMachine
if len(srcMachine) > 0 {
cpOpts.IsSrc = true
name = srcMachine
}
return vmconfigs.LoadMachineByName(name, dirs)
return name, nil
}

View File

@@ -12,7 +12,6 @@ import (
"github.com/containers/podman/v6/libpod/events"
"github.com/containers/podman/v6/pkg/machine/define"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/shirou/gopsutil/v4/mem"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -184,14 +183,20 @@ func initMachine(cmd *cobra.Command, args []string) error {
}
// Check if machine already exists
_, exists, err := shim.VMExists(initOpts.Name, []vmconfigs.VMProvider{provider})
if err != nil {
var errNotExists *define.ErrVMDoesNotExist
_, _, err := shim.VMExists(initOpts.Name)
// errors.As checks for nil so safe to use.
if !errors.As(err, &errNotExists) {
return err
}
// machine exists, return error
// Check if something on the hypervisor exists with the same name
exists, err := shim.VMExistsOnHyperVisor(initOpts.Name)
if err != nil {
return err
}
if exists {
return fmt.Errorf("%s: %w", initOpts.Name, define.ErrVMAlreadyExists)
return fmt.Errorf("%s already exists on hypervisor", initOpts.Name)
}
// check if a system connection already exists

View File

@@ -10,7 +10,7 @@ import (
"github.com/containers/podman/v6/cmd/podman/utils"
"github.com/containers/podman/v6/pkg/machine"
"github.com/containers/podman/v6/pkg/machine/env"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/spf13/cobra"
"go.podman.io/common/pkg/report"
)
@@ -48,33 +48,34 @@ func inspect(cmd *cobra.Command, args []string) error {
var (
errs utils.OutputErrors
)
dirs, err := env.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
if len(args) < 1 {
args = append(args, defaultMachineName)
}
vms := make([]machine.InspectInfo, 0, len(args))
for _, name := range args {
mc, err := vmconfigs.LoadMachineByName(name, dirs)
mc, vmProvider, err := shim.VMExists(name)
if err != nil {
errs = append(errs, err)
continue
}
state, err := provider.State(mc, false)
dirs, err := env.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
podmanSocket, podmanPipe, err := mc.ConnectionInfo(provider.VMType())
state, err := vmProvider.State(mc, false)
if err != nil {
return err
}
rosetta, err := provider.GetRosetta(mc)
podmanSocket, podmanPipe, err := mc.ConnectionInfo(vmProvider.VMType())
if err != nil {
return err
}
rosetta, err := vmProvider.GetRosetta(mc)
if err != nil {
return err
}
@@ -91,7 +92,7 @@ func inspect(cmd *cobra.Command, args []string) error {
Resources: mc.Resources,
SSHConfig: mc.SSH,
State: state,
UserModeNetworking: provider.UserModeNetworkEnabled(mc),
UserModeNetworking: vmProvider.UserModeNetworkEnabled(mc),
Rootful: mc.HostUser.Rootful,
Rosetta: rosetta,
}

View File

@@ -17,7 +17,6 @@ import (
"github.com/containers/podman/v6/pkg/machine"
provider2 "github.com/containers/podman/v6/pkg/machine/provider"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/docker/go-units"
"github.com/spf13/cobra"
"go.podman.io/common/pkg/completion"
@@ -44,10 +43,9 @@ var (
)
type listFlagType struct {
format string
noHeading bool
quiet bool
allProviders bool
format string
noHeading bool
quiet bool
}
func init() {
@@ -62,7 +60,6 @@ func init() {
_ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.ListReporter{}))
flags.BoolVarP(&listFlag.noHeading, "noheading", "n", false, "Do not print headers")
flags.BoolVarP(&listFlag.quiet, "quiet", "q", false, "Show only machine names")
flags.BoolVar(&listFlag.allProviders, "all-providers", false, "Show machines from all providers")
}
func list(cmd *cobra.Command, _ []string) error {
@@ -70,17 +67,7 @@ func list(cmd *cobra.Command, _ []string) error {
opts machine.ListOptions
err error
)
var providers []vmconfigs.VMProvider
if listFlag.allProviders {
providers = provider2.GetAll()
} else {
provider, err = provider2.Get()
if err != nil {
return err
}
providers = []vmconfigs.VMProvider{provider}
}
providers := provider2.GetAll()
listResponse, err := shim.List(providers, opts)
if err != nil {
return err

View File

@@ -42,6 +42,7 @@ var (
)
var (
// TODO This needs to be deleted!
provider vmconfigs.VMProvider
)

View File

@@ -8,7 +8,6 @@ import (
"github.com/containers/podman/v6/cmd/podman/registry"
"github.com/containers/podman/v6/cmd/podman/validate"
"github.com/containers/podman/v6/pkg/machine/os"
provider2 "github.com/containers/podman/v6/pkg/machine/provider"
"github.com/spf13/cobra"
)
@@ -49,11 +48,7 @@ func apply(_ *cobra.Command, args []string) error {
Restart: restart,
}
provider, err := provider2.Get()
if err != nil {
return err
}
osManager, err := NewOSManager(managerOpts, provider)
osManager, err := NewOSManager(managerOpts)
if err != nil {
return err
}

View File

@@ -9,10 +9,8 @@ import (
"strings"
"github.com/containers/podman/v6/pkg/machine/define"
"github.com/containers/podman/v6/pkg/machine/env"
pkgOS "github.com/containers/podman/v6/pkg/machine/os"
"github.com/containers/podman/v6/pkg/machine/provider"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/containers/podman/v6/pkg/machine/shim"
machineconfig "go.podman.io/common/pkg/machine"
)
@@ -23,13 +21,30 @@ type ManagerOpts struct {
}
// NewOSManager creates a new OSManager depending on the mode of the call
func NewOSManager(opts ManagerOpts, p vmconfigs.VMProvider) (pkgOS.Manager, error) {
func NewOSManager(opts ManagerOpts) (pkgOS.Manager, error) {
// If a VM name is specified, then we know that we are not inside a
// Podman VM, but rather outside of it.
if machineconfig.IsPodmanMachine() && opts.VMName == "" {
return guestOSManager()
}
return machineOSManager(opts, p)
// Set to the default name if no VM was provided
if opts.VMName == "" {
opts.VMName = define.DefaultMachineName
}
mc, vmProvider, err := shim.VMExists(opts.VMName)
if err != nil {
return nil, err
}
return &pkgOS.MachineOS{
VM: mc,
Provider: vmProvider,
Args: opts.CLIArgs,
VMName: opts.VMName,
Restart: opts.Restart,
}, nil
}
// guestOSManager returns an OSmanager for inside-VM operations
@@ -43,33 +58,6 @@ func guestOSManager() (pkgOS.Manager, error) {
}
}
// machineOSManager returns an os manager that manages outside the VM.
func machineOSManager(opts ManagerOpts, _ vmconfigs.VMProvider) (pkgOS.Manager, error) {
vmName := opts.VMName
if opts.VMName == "" {
vmName = define.DefaultMachineName
}
p, err := provider.Get()
if err != nil {
return nil, err
}
dirs, err := env.GetMachineDirs(p.VMType())
if err != nil {
return nil, err
}
mc, err := vmconfigs.LoadMachineByName(vmName, dirs)
if err != nil {
return nil, err
}
return &pkgOS.MachineOS{
VM: mc,
Provider: p,
Args: opts.CLIArgs,
VMName: vmName,
Restart: opts.Restart,
}, nil
}
type Distribution struct {
Name string
Variant string

View File

@@ -6,9 +6,7 @@ import (
"github.com/containers/podman/v6/cmd/podman/registry"
"github.com/containers/podman/v6/libpod/events"
"github.com/containers/podman/v6/pkg/machine"
"github.com/containers/podman/v6/pkg/machine/env"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
)
@@ -55,17 +53,12 @@ func rm(_ *cobra.Command, args []string) error {
vmName = args[0]
}
dirs, err := env.GetMachineDirs(provider.VMType())
mc, vmProvider, err := shim.VMExists(vmName)
if err != nil {
return err
}
mc, err := vmconfigs.LoadMachineByName(vmName, dirs)
if err != nil {
return err
}
if err := shim.Remove(mc, provider, dirs, destroyOptions); err != nil {
if err := shim.Remove(mc, vmProvider, destroyOptions); err != nil {
return err
}
newMachineEvent(events.Remove, events.Event{Name: vmName})

View File

@@ -5,9 +5,7 @@ package machine
import (
"github.com/containers/podman/v6/cmd/podman/registry"
"github.com/containers/podman/v6/pkg/machine/define"
"github.com/containers/podman/v6/pkg/machine/env"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
"go.podman.io/common/pkg/completion"
"go.podman.io/common/pkg/strongunits"
@@ -93,12 +91,7 @@ func setMachine(cmd *cobra.Command, args []string) error {
vmName = args[0]
}
dirs, err := env.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
mc, err := vmconfigs.LoadMachineByName(vmName, dirs)
mc, vmProvider, err := shim.VMExists(vmName)
if err != nil {
return err
}
@@ -129,5 +122,5 @@ func setMachine(cmd *cobra.Command, args []string) error {
// At this point, we have the known changed information, etc
// Walk through changes to the providers if they need them
return shim.Set(mc, provider, setOpts)
return shim.Set(mc, vmProvider, setOpts)
}

View File

@@ -3,14 +3,14 @@
package machine
import (
"errors"
"fmt"
"github.com/containers/podman/v6/pkg/machine/define"
"github.com/containers/podman/v6/pkg/machine/env"
"github.com/containers/podman/v6/cmd/podman/registry"
"github.com/containers/podman/v6/cmd/podman/utils"
"github.com/containers/podman/v6/pkg/machine"
"github.com/containers/podman/v6/pkg/machine/define"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
"go.podman.io/common/pkg/completion"
@@ -45,20 +45,14 @@ func init() {
_ = sshCmd.RegisterFlagCompletionFunc(usernameFlagName, completion.AutocompleteNone)
}
// TODO Remember that this changed upstream and needs to updated as such!
func ssh(_ *cobra.Command, args []string) error {
var (
err error
mc *vmconfigs.MachineConfig
validVM bool
err error
exists bool
mc *vmconfigs.MachineConfig
vmProvider vmconfigs.VMProvider
)
dirs, err := env.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
// Set the VM to default
vmName := defaultMachineName
// If len is greater than 0, it means we may have been
@@ -68,23 +62,22 @@ func ssh(_ *cobra.Command, args []string) error {
// note: previous incantations of this up by a specific name
// and errors were ignored. this error is not ignored because
// it implies podman cannot read its machine files, which is bad
machines, err := vmconfigs.LoadMachinesInDir(dirs)
mc, vmProvider, err = shim.VMExists(args[0])
if err != nil {
return err
}
mc, validVM = machines[args[0]]
if validVM {
if errors.Is(err, &define.ErrVMDoesNotExist{}) {
vmName = args[0]
} else {
sshOpts.Args = append(sshOpts.Args, args[0])
}
exists = true
}
// If len is greater than 1, it means we might have been
// given a vmname and args or just args
if len(args) > 1 {
if validVM {
if exists {
sshOpts.Args = args[1:]
} else {
sshOpts.Args = args
@@ -93,13 +86,12 @@ func ssh(_ *cobra.Command, args []string) error {
// If the machine config was not loaded earlier, we load it now
if mc == nil {
mc, err = vmconfigs.LoadMachineByName(vmName, dirs)
mc, vmProvider, err = shim.VMExists(vmName)
if err != nil {
return fmt.Errorf("vm %s not found: %w", vmName, err)
return err
}
}
state, err := provider.State(mc, false)
state, err := vmProvider.State(mc, false)
if err != nil {
return err
}

View File

@@ -8,9 +8,7 @@ import (
"github.com/containers/podman/v6/cmd/podman/registry"
"github.com/containers/podman/v6/libpod/events"
"github.com/containers/podman/v6/pkg/machine"
"github.com/containers/podman/v6/pkg/machine/env"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
)
@@ -54,11 +52,7 @@ func start(_ *cobra.Command, args []string) error {
vmName = args[0]
}
dirs, err := env.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
mc, err := vmconfigs.LoadMachineByName(vmName, dirs)
mc, vmProvider, err := shim.VMExists(vmName)
if err != nil {
return err
}
@@ -67,7 +61,7 @@ func start(_ *cobra.Command, args []string) error {
fmt.Printf("Starting machine %q\n", vmName)
}
if err := shim.Start(mc, provider, dirs, startOpts); err != nil {
if err := shim.Start(mc, vmProvider, startOpts); err != nil {
return err
}
fmt.Printf("Machine %q started successfully\n", vmName)

View File

@@ -7,9 +7,7 @@ import (
"github.com/containers/podman/v6/cmd/podman/registry"
"github.com/containers/podman/v6/libpod/events"
"github.com/containers/podman/v6/pkg/machine/env"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
)
@@ -44,16 +42,12 @@ func stop(_ *cobra.Command, args []string) error {
vmName = args[0]
}
dirs, err := env.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
mc, err := vmconfigs.LoadMachineByName(vmName, dirs)
mc, vmProvider, err := shim.VMExists(vmName)
if err != nil {
return err
}
if err := shim.Stop(mc, provider, dirs, false); err != nil {
if err := shim.Stop(mc, vmProvider, false); err != nil {
return err
}

View File

@@ -42,7 +42,7 @@ func resetMachine() error {
}
if state == define.Running {
if err := shim.Stop(mc, provider, dirs, true); err != nil {
if err := shim.Stop(mc, provider, true); err != nil {
logrus.Errorf("unable to stop running machine %s: %q", mc.Name, err)
}
}

View File

@@ -26,10 +26,6 @@ environment variable while the machines are running can lead to unexpected behav
## OPTIONS
#### **--all-providers**
Show machines from all providers
#### **--format**=*format*
Change the default output format. This can be of a supported type like 'json'

View File

@@ -7,12 +7,19 @@ import (
var (
ErrWrongState = errors.New("VM in wrong state to perform action")
ErrVMAlreadyExists = errors.New("VM already exists")
ErrNotImplemented = errors.New("functionality not implemented")
ErrInitRelaunchAttempt = errors.New("stopping execution: 'init' relaunched with --reexec flag to reinitialize the VM")
ErrRebootInitiated = errors.New("system reboot initiated")
)
type ErrVMAlreadyExists struct {
Name string
}
func (err *ErrVMAlreadyExists) Error() string {
return fmt.Sprintf("machine %q already exists", err.Name)
}
type ErrVMRunningCannotDestroyed struct {
Name string
}

View File

@@ -185,7 +185,7 @@ var _ = Describe("podman machine list", func() {
Expect(listSession.outputToString()).To(Equal("2GiB 11GiB"))
})
It("list machine from all providers", func() {
skipIfVmtype(define.QemuVirt, "linux only has one provider")
Skip("This test will be changed for when --provider is added to init")
// create machine on other provider
currprovider := os.Getenv("CONTAINERS_MACHINE_PROVIDER")

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"github.com/containers/podman/v6/pkg/machine"
"github.com/containers/podman/v6/pkg/machine/env"
"github.com/containers/podman/v6/pkg/machine/shim"
"github.com/containers/podman/v6/pkg/machine/vmconfigs"
)
@@ -28,16 +27,11 @@ func (m *MachineOS) Apply(image string, _ ApplyOptions) error {
return err
}
dirs, err := env.GetMachineDirs(m.Provider.VMType())
if err != nil {
return err
}
if m.Restart {
if err := shim.Stop(m.VM, m.Provider, dirs, false); err != nil {
if err := shim.Stop(m.VM, m.Provider, false); err != nil {
return err
}
if err := shim.Start(m.VM, m.Provider, dirs, machine.StartOptions{NoInfo: true}); err != nil {
if err := shim.Start(m.VM, m.Provider, machine.StartOptions{NoInfo: true}); err != nil {
return err
}
fmt.Printf("Machine %q restarted successfully\n", m.VMName)

View File

@@ -32,42 +32,35 @@ import (
// List is done at the host level to allow for a *possible* future where
// more than one provider is used
func List(vmstubbers []vmconfigs.VMProvider, _ machine.ListOptions) ([]*machine.ListResponse, error) {
var lrs []*machine.ListResponse
for _, s := range vmstubbers {
dirs, err := env.GetMachineDirs(s.VMType())
if err != nil {
return nil, err
}
mcs, err := vmconfigs.LoadMachinesInDir(dirs)
if err != nil {
return nil, err
}
for name, mc := range mcs {
state, err := s.State(mc, false)
if err != nil {
return nil, err
}
lr := machine.ListResponse{
Name: name,
CreatedAt: mc.Created,
LastUp: mc.LastUp,
Running: state == machineDefine.Running,
Starting: mc.Starting,
VMType: s.VMType().String(),
CPUs: mc.Resources.CPUs,
Memory: mc.Resources.Memory,
Swap: mc.Swap,
DiskSize: mc.Resources.DiskSize,
Port: mc.SSH.Port,
RemoteUsername: mc.SSH.RemoteUsername,
IdentityPath: mc.SSH.IdentityPath,
UserModeNetworking: s.UserModeNetworkEnabled(mc),
}
lrs = append(lrs, &lr)
}
lrs := make([]*machine.ListResponse, 0)
mcs, err := getMCsOverProviders(vmstubbers)
if err != nil {
return nil, err
}
for name, mc := range mcs {
state, err := mc.Provider.State(mc.MachineConfig, false)
if err != nil {
return nil, err
}
lr := machine.ListResponse{
Name: name,
CreatedAt: mc.Created,
LastUp: mc.LastUp,
Running: state == machineDefine.Running,
Starting: mc.Starting,
VMType: mc.Provider.VMType().String(),
CPUs: mc.Resources.CPUs,
Memory: mc.Resources.Memory,
Swap: mc.Swap,
DiskSize: mc.Resources.DiskSize,
Port: mc.SSH.Port,
RemoteUsername: mc.SSH.RemoteUsername,
IdentityPath: mc.SSH.IdentityPath,
UserModeNetworking: mc.Provider.UserModeNetworkEnabled(mc.MachineConfig),
}
lrs = append(lrs, &lr)
}
return lrs, nil
}
@@ -300,27 +293,37 @@ func Init(opts machineDefine.InitOptions, mp vmconfigs.VMProvider) error {
return mc.Write()
}
type MultiProvider []vmconfigs.VMProvider
// VMExists looks across given providers for a machine's existence. returns the actual config and found bool
func VMExists(name string, vmstubbers []vmconfigs.VMProvider) (*vmconfigs.MachineConfig, bool, error) {
func VMExists(name string) (*vmconfigs.MachineConfig, vmconfigs.VMProvider, error) {
// Look on disk first
mcs, err := getMCsOverProviders(vmstubbers)
mcs, err := getMCsOverProviders(provider.GetAll())
if err != nil {
return nil, false, err
return nil, nil, err
}
if mc, found := mcs[name]; found {
return mc.MachineConfig, true, nil
vmType := mc.Provider
return mc.MachineConfig, vmType, nil
}
// Check with the provider hypervisor
for _, vmstubber := range vmstubbers {
exists, err := vmstubber.Exists(name)
return nil, nil, &machineDefine.ErrVMDoesNotExist{Name: name}
}
// VMExistsOnHyperVisor actually checks the managing hypervisor (like WSL, HyperV)
// to make sure a VM with the same name does not happen to exist.
func VMExistsOnHyperVisor(name string) (bool, error) {
providers := provider.GetAll()
for _, p := range providers {
exists, err := p.Exists(name)
if err != nil {
return nil, false, err
return false, err
}
if exists {
return nil, true, fmt.Errorf("vm %q already exists on hypervisor", name)
return true, nil
}
}
return nil, false, nil
return false, nil
}
// checkExclusiveActiveVM checks if any of the machines are already running
@@ -356,8 +359,8 @@ func checkExclusiveActiveVM(currentProvider vmconfigs.VMProvider, mc *vmconfigs.
}
type knownMachineConfig struct {
Provider vmconfigs.VMProvider
MachineConfig *vmconfigs.MachineConfig
Provider vmconfigs.VMProvider
*vmconfigs.MachineConfig
}
// getMCsOverProviders loads machineconfigs from a config dir derived from the "provider". it returns only what is known on
@@ -373,15 +376,9 @@ func getMCsOverProviders(vmstubbers []vmconfigs.VMProvider) (map[string]knownMac
if err != nil {
return nil, err
}
// TODO When we get to golang-1.20+ we can replace the following with maps.Copy
// maps.Copy(mcs, stubberMCs)
// iterate known mcs and add the stubbers
for mcName, mc := range stubberMCs {
if _, ok := mcs[mcName]; !ok {
mcs[mcName] = knownMachineConfig{
Provider: stubber,
MachineConfig: mc,
}
mcs[mcName] = knownMachineConfig{Provider: stubber, MachineConfig: mc}
}
}
}
@@ -389,7 +386,11 @@ func getMCsOverProviders(vmstubbers []vmconfigs.VMProvider) (map[string]knownMac
}
// Stop stops the machine as well as supporting binaries/processes
func Stop(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *machineDefine.MachineDirs, hardStop bool) error {
func Stop(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, hardStop bool) error {
dirs, err := env.GetMachineDirs(mp.VMType())
if err != nil {
return err
}
// state is checked here instead of earlier because stopping a stopped vm is not considered
// an error. so putting in one place instead of sprinkling all over.
mc.Lock()
@@ -445,11 +446,15 @@ func stopLocked(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *mach
return mc.Write()
}
func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *machineDefine.MachineDirs, opts machine.StartOptions) error {
func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, opts machine.StartOptions) error {
defaultBackoff := 500 * time.Millisecond
maxBackoffs := 6
signalChanClosed := false
dirs, err := env.GetMachineDirs(mp.VMType())
if err != nil {
return err
}
mc.Lock()
defer mc.Unlock()
if err := mc.Refresh(); err != nil {
@@ -672,7 +677,11 @@ func Set(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, opts machineDefin
return mc.Write()
}
func Remove(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *machineDefine.MachineDirs, opts machine.RemoveOptions) error {
func Remove(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, opts machine.RemoveOptions) error {
dirs, err := env.GetMachineDirs(mp.VMType())
if err != nil {
return err
}
mc.Lock()
defer mc.Unlock()
if err := mc.Refresh(); err != nil {
@@ -776,7 +785,7 @@ func Reset(mps []vmconfigs.VMProvider, _ machine.ResetOptions) error {
}
for _, mc := range mcs {
err := Stop(mc, p, d, true)
err := Stop(mc, p, true)
if err != nil {
resetErrors = multierror.Append(resetErrors, err)
}

View File

@@ -59,7 +59,7 @@ func NewMachineConfig(opts define.InitOptions, dirs *define.MachineDirs, sshIden
// Given that we are locked now and check again that the config file does not exists,
// if it does it means the VM was already created and we should error.
if err := fileutils.Exists(cf.Path); err == nil {
return nil, fmt.Errorf("%s: %w", opts.Name, define.ErrVMAlreadyExists)
return nil, &define.ErrVMAlreadyExists{Name: opts.Name}
}
if vmtype != define.QemuVirt && len(opts.USBs) > 0 {