Implement generic providers

The intial refactor used specifically qemu for testing and infra bring
up.  But the whole point was to have things interfaced.  This PR results
in an interface experience like podman 4 using the same term `provider`
to generically represent 'a provider' like qemu/applehv/etc.

This PR is required to move forward with new providers.

Also renamed pkg/machine/p5 to pkg/machine/shim.

[NO NEW TESTS REQUIRED]

Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
Brent Baude
2024-01-22 15:21:37 -06:00
parent 9bb191df51
commit e8501ca991
22 changed files with 133 additions and 104 deletions

View File

@ -16,7 +16,6 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/machine"
machineDefine "github.com/containers/podman/v4/pkg/machine/define"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
@ -101,10 +100,7 @@ func hostInfo() (*entities.MachineHostInfo, error) {
host.Arch = runtime.GOARCH
host.OS = runtime.GOOS
// TODO This is temporary
s := new(qemu.QEMUStubber)
dirs, err := machine.GetMachineDirs(s.VMType())
dirs, err := machine.GetMachineDirs(provider.VMType())
if err != nil {
return nil, err
}
@ -130,7 +126,7 @@ func hostInfo() (*entities.MachineHostInfo, error) {
host.DefaultMachine = vm.Name
}
// If machine is running or starting, it is automatically the current machine
state, err := s.State(vm, false)
state, err := provider.State(vm, false)
if err != nil {
return nil, err
}
@ -153,7 +149,7 @@ func hostInfo() (*entities.MachineHostInfo, error) {
}
}
host.VMType = s.VMType().String()
host.VMType = provider.VMType().String()
host.MachineImageDir = dirs.DataDir.GetPath()
host.MachineConfigDir = dirs.ConfigDir.GetPath()

View File

@ -11,8 +11,7 @@ import (
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/define"
"github.com/containers/podman/v4/pkg/machine/p5"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/shim"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
)
@ -144,10 +143,8 @@ func initMachine(cmd *cobra.Command, args []string) error {
return fmt.Errorf("cannot use %q for a machine name", initOpts.Name)
}
s := new(qemu.QEMUStubber)
// Check if machine already exists
_, exists, err := p5.VMExists(initOpts.Name, []vmconfigs.VMStubber{s})
_, exists, err := shim.VMExists(initOpts.Name, []vmconfigs.VMProvider{provider})
if err != nil {
return err
}
@ -194,7 +191,7 @@ func initMachine(cmd *cobra.Command, args []string) error {
// }
// TODO this is for QEMU only (change to generic when adding second provider)
mc, err := p5.Init(initOpts, s)
mc, err := shim.Init(initOpts, provider)
if err != nil {
return err
}

View File

@ -10,7 +10,6 @@ import (
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/utils"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
)
@ -48,8 +47,7 @@ func inspect(cmd *cobra.Command, args []string) error {
var (
errs utils.OutputErrors
)
s := new(qemu.QEMUStubber)
dirs, err := machine.GetMachineDirs(s.VMType())
dirs, err := machine.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
@ -65,7 +63,7 @@ func inspect(cmd *cobra.Command, args []string) error {
continue
}
state, err := s.State(mc, false)
state, err := provider.State(mc, false)
if err != nil {
return err
}

View File

@ -9,10 +9,6 @@ import (
"strconv"
"time"
"github.com/containers/podman/v4/pkg/machine/p5"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
"github.com/containers/podman/v4/cmd/podman/common"
@ -20,6 +16,8 @@ import (
"github.com/containers/podman/v4/cmd/podman/validate"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/shim"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/docker/go-units"
"github.com/spf13/cobra"
)
@ -67,8 +65,7 @@ func list(cmd *cobra.Command, args []string) error {
err error
)
s := new(qemu.QEMUStubber)
listResponse, err := p5.List([]vmconfigs.VMStubber{s}, opts)
listResponse, err := shim.List([]vmconfigs.VMProvider{provider}, opts)
if err != nil {
return err
}

View File

@ -41,6 +41,10 @@ var (
}
)
var (
provider vmconfigs.VMProvider
)
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: machineCmd,
@ -48,14 +52,11 @@ func init() {
}
func machinePreRunE(c *cobra.Command, args []string) error {
// TODO this should get enabled again once we define what a new provider is
// this can be done when the second "provider" is enabled.
// var err error
// provider, err = provider2.Get()
// if err != nil {
// return err
// }
var err error
provider, err = provider2.Get()
if err != nil {
return err
}
return rootlessOnly(c, args)
}

View File

@ -8,7 +8,7 @@ import (
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/validate"
"github.com/containers/podman/v4/pkg/machine/os"
"github.com/containers/podman/v4/pkg/machine/qemu"
provider2 "github.com/containers/podman/v4/pkg/machine/provider"
"github.com/spf13/cobra"
)
@ -49,10 +49,11 @@ func apply(cmd *cobra.Command, args []string) error {
Restart: restart,
}
// TODO This is temporary
s := new(qemu.QEMUStubber)
osManager, err := NewOSManager(managerOpts, s)
provider, err := provider2.Get()
if err != nil {
return err
}
osManager, err := NewOSManager(managerOpts, provider)
if err != nil {
return err
}

View File

@ -8,12 +8,11 @@ import (
"os"
"strings"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
machineconfig "github.com/containers/common/pkg/machine"
pkgMachine "github.com/containers/podman/v4/pkg/machine"
pkgOS "github.com/containers/podman/v4/pkg/machine/os"
"github.com/containers/podman/v4/pkg/machine/provider"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
)
type ManagerOpts struct {
@ -23,7 +22,7 @@ type ManagerOpts struct {
}
// NewOSManager creates a new OSManager depending on the mode of the call
func NewOSManager(opts ManagerOpts, p vmconfigs.VMStubber) (pkgOS.Manager, error) {
func NewOSManager(opts ManagerOpts, p vmconfigs.VMProvider) (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 == "" {
@ -44,7 +43,7 @@ func guestOSManager() (pkgOS.Manager, error) {
}
// machineOSManager returns an os manager that manages outside the VM.
func machineOSManager(opts ManagerOpts, _ vmconfigs.VMStubber) (pkgOS.Manager, error) {
func machineOSManager(opts ManagerOpts, _ vmconfigs.VMProvider) (pkgOS.Manager, error) {
vmName := opts.VMName
if opts.VMName == "" {
vmName = pkgMachine.DefaultMachineName

View File

@ -12,8 +12,7 @@ import (
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/define"
"github.com/containers/podman/v4/pkg/machine/p5"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/shim"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@ -62,9 +61,7 @@ func rm(_ *cobra.Command, args []string) error {
vmName = args[0]
}
// TODO this is for QEMU only (change to generic when adding second provider)
q := new(qemu.QEMUStubber)
dirs, err := machine.GetMachineDirs(q.VMType())
dirs, err := machine.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
@ -74,7 +71,7 @@ func rm(_ *cobra.Command, args []string) error {
return err
}
state, err := q.State(mc, false)
state, err := provider.State(mc, false)
if err != nil {
return err
}
@ -83,7 +80,7 @@ func rm(_ *cobra.Command, args []string) error {
if !destroyOptions.Force {
return &define.ErrVMRunningCannotDestroyed{Name: vmName}
}
if err := p5.Stop(mc, q, dirs, true); err != nil {
if err := shim.Stop(mc, provider, dirs, true); err != nil {
return err
}
}
@ -93,7 +90,7 @@ func rm(_ *cobra.Command, args []string) error {
return err
}
providerFiles, providerRm, err := q.Remove(mc)
providerFiles, providerRm, err := provider.Remove(mc)
if err != nil {
return err
}

View File

@ -9,7 +9,6 @@ import (
"github.com/containers/common/pkg/strongunits"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
)
@ -100,7 +99,6 @@ func setMachine(cmd *cobra.Command, args []string) error {
vmName = args[0]
}
provider := new(qemu.QEMUStubber)
dirs, err := machine.GetMachineDirs(provider.VMType())
if err != nil {
return err

View File

@ -12,7 +12,6 @@ import (
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/utils"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/spf13/cobra"
)
@ -55,9 +54,7 @@ func ssh(cmd *cobra.Command, args []string) error {
validVM bool
)
// TODO Temporary
q := new(qemu.QEMUStubber)
dirs, err := machine.GetMachineDirs(q.VMType())
dirs, err := machine.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
@ -109,7 +106,7 @@ func ssh(cmd *cobra.Command, args []string) error {
}
}
state, err := q.State(mc, false)
state, err := provider.State(mc, false)
if err != nil {
return err
}

View File

@ -5,18 +5,13 @@ package machine
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/containers/podman/v4/pkg/machine/p5"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/containers/podman/v4/pkg/machine/define"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/define"
"github.com/containers/podman/v4/pkg/machine/shim"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@ -60,10 +55,7 @@ func start(_ *cobra.Command, args []string) error {
vmName = args[0]
}
// TODO this is for QEMU only (change to generic when adding second provider)
q := new(qemu.QEMUStubber)
dirs, err := machine.GetMachineDirs(q.VMType())
dirs, err := machine.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
@ -72,7 +64,7 @@ func start(_ *cobra.Command, args []string) error {
return err
}
state, err := q.State(mc, false)
state, err := provider.State(mc, false)
if err != nil {
return err
}
@ -81,7 +73,7 @@ func start(_ *cobra.Command, args []string) error {
return define.ErrVMAlreadyRunning
}
if err := p5.CheckExclusiveActiveVM(q, mc); err != nil {
if err := shim.CheckExclusiveActiveVM(provider, mc); err != nil {
return err
}
@ -102,7 +94,7 @@ func start(_ *cobra.Command, args []string) error {
logrus.Error(err)
}
}()
if err := p5.Start(mc, q, dirs, startOpts); err != nil {
if err := shim.Start(mc, provider, dirs, startOpts); err != nil {
return err
}
fmt.Printf("Machine %q started successfully\n", vmName)

View File

@ -6,12 +6,10 @@ import (
"fmt"
"time"
"github.com/containers/podman/v4/pkg/machine/p5"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/shim"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@ -48,9 +46,7 @@ func stop(cmd *cobra.Command, args []string) error {
vmName = args[0]
}
// TODO this is for QEMU only (change to generic when adding second provider)
q := new(qemu.QEMUStubber)
dirs, err := machine.GetMachineDirs(q.VMType())
dirs, err := machine.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
@ -59,7 +55,7 @@ func stop(cmd *cobra.Command, args []string) error {
return err
}
if err := p5.Stop(mc, q, dirs, false); err != nil {
if err := shim.Stop(mc, provider, dirs, false); err != nil {
return err
}

View File

@ -3,7 +3,14 @@
package system
import (
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/connection"
"github.com/containers/podman/v4/pkg/machine/define"
p "github.com/containers/podman/v4/pkg/machine/provider"
"github.com/containers/podman/v4/pkg/machine/shim"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/containers/podman/v4/utils"
"github.com/sirupsen/logrus"
)
func resetMachine() error {
@ -11,5 +18,58 @@ func resetMachine() error {
if err != nil {
return err
}
return provider.RemoveAndCleanMachines()
dirs, err := machine.GetMachineDirs(provider.VMType())
if err != nil {
return err
}
mcs, err := vmconfigs.LoadMachinesInDir(dirs)
if err != nil {
// Note: the reason we might be cleaning is because a JSON file is messed
// up and is unreadable. This should not be fatal. Keep going ...
logrus.Errorf("unable to load machines: %q", err)
}
for _, mc := range mcs {
state, err := provider.State(mc, false)
if err != nil {
logrus.Errorf("unable to determine state of %s: %q", mc.Name, err)
}
if state == define.Running {
if err := shim.Stop(mc, provider, dirs, true); err != nil {
logrus.Errorf("unable to stop running machine %s: %q", mc.Name, err)
}
}
if err := connection.RemoveConnections(mc.Name, mc.Name+"-root"); err != nil {
logrus.Error(err)
}
// the thinking here is that the we dont need to remove machine specific files because
// we will nuke them all at the end of this. Just do what provider needs
_, providerRm, err := provider.Remove(mc)
if err != nil {
logrus.Errorf("unable to prepare provider machine removal: %q", err)
}
if err := providerRm(); err != nil {
logrus.Errorf("unable remove machine %s from provider: %q", mc.Name, err)
}
}
if err := utils.GuardedRemoveAll(dirs.DataDir.GetPath()); err != nil {
logrus.Errorf("unable to remove machine data dir %q: %q", dirs.DataDir.GetPath(), err)
}
if err := utils.GuardedRemoveAll(dirs.RuntimeDir.GetPath()); err != nil {
logrus.Errorf("unable to remove machine runtime dir %q: %q", dirs.RuntimeDir.GetPath(), err)
}
if err := utils.GuardedRemoveAll(dirs.ConfigDir.GetPath()); err != nil {
logrus.Errorf("unable to remove machine config dir %q: %q", dirs.ConfigDir.GetPath(), err)
}
// Just in case a provider needs something general done
return provider.RemoveAndCleanMachines(dirs)
}

View File

@ -48,7 +48,7 @@ func TestMachine(t *testing.T) {
RunSpecs(t, "Podman Machine tests")
}
var testProvider vmconfigs.VMStubber
var testProvider vmconfigs.VMProvider
var _ = BeforeSuite(func() {
var err error

View File

@ -6,7 +6,7 @@ import (
"fmt"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/p5"
"github.com/containers/podman/v4/pkg/machine/shim"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
)
@ -14,7 +14,7 @@ import (
type MachineOS struct {
Args []string
VM *vmconfigs.MachineConfig
Provider vmconfigs.VMStubber
Provider vmconfigs.VMProvider
VMName string
Restart bool
}
@ -33,10 +33,10 @@ func (m *MachineOS) Apply(image string, opts ApplyOptions) error {
}
if m.Restart {
if err := p5.Stop(m.VM, m.Provider, dirs, false); err != nil {
if err := shim.Stop(m.VM, m.Provider, dirs, false); err != nil {
return err
}
if err := p5.Start(m.VM, m.Provider, dirs, machine.StartOptions{NoInfo: true}); err != nil {
if err := shim.Start(m.VM, m.Provider, dirs, machine.StartOptions{NoInfo: true}); err != nil {
return err
}
fmt.Printf("Machine %q restarted successfully\n", m.VMName)

View File

@ -6,15 +6,14 @@ import (
"fmt"
"os"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v4/pkg/machine/define"
"github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
"github.com/sirupsen/logrus"
)
func Get() (vmconfigs.VMStubber, error) {
func Get() (vmconfigs.VMProvider, error) {
cfg, err := config.Default()
if err != nil {
return nil, err

View File

@ -252,8 +252,9 @@ func (q *QEMUStubber) StartNetworking(mc *vmconfigs.MachineConfig, cmd *gvproxy.
return nil
}
func (q *QEMUStubber) RemoveAndCleanMachines() error {
return define.ErrNotImplemented
func (q *QEMUStubber) RemoveAndCleanMachines(_ *define.MachineDirs) error {
// nothing to do but remove files
return nil
}
// mountVolumesToVM iterates through the machine's volumes and mounts them to the

View File

@ -1,4 +1,4 @@
package p5
package shim
import (
"fmt"

View File

@ -1,6 +1,6 @@
//build: !darwin
package p5
package shim
func dockerClaimHelperInstalled() bool {
return false

View File

@ -1,4 +1,4 @@
package p5
package shim
import (
"context"
@ -36,7 +36,7 @@ func SSH() {}
// List is done at the host level to allow for a *possible* future where
// more than one provider is used
func List(vmstubbers []vmconfigs.VMStubber, opts machine.ListOptions) ([]*machine.ListResponse, error) {
func List(vmstubbers []vmconfigs.VMProvider, opts machine.ListOptions) ([]*machine.ListResponse, error) {
var (
lrs []*machine.ListResponse
)
@ -78,7 +78,7 @@ func List(vmstubbers []vmconfigs.VMStubber, opts machine.ListOptions) ([]*machin
return lrs, nil
}
func Init(opts machineDefine.InitOptions, mp vmconfigs.VMStubber) (*vmconfigs.MachineConfig, error) {
func Init(opts machineDefine.InitOptions, mp vmconfigs.VMProvider) (*vmconfigs.MachineConfig, error) {
var (
err error
)
@ -219,7 +219,7 @@ func Init(opts machineDefine.InitOptions, mp vmconfigs.VMStubber) (*vmconfigs.Ma
}
// VMExists looks across given providers for a machine's existence. returns the actual config and found bool
func VMExists(name string, vmstubbers []vmconfigs.VMStubber) (*vmconfigs.MachineConfig, bool, error) {
func VMExists(name string, vmstubbers []vmconfigs.VMProvider) (*vmconfigs.MachineConfig, bool, error) {
mcs, err := getMCsOverProviders(vmstubbers)
if err != nil {
return nil, false, err
@ -229,9 +229,9 @@ func VMExists(name string, vmstubbers []vmconfigs.VMStubber) (*vmconfigs.Machine
}
// CheckExclusiveActiveVM checks if any of the machines are already running
func CheckExclusiveActiveVM(provider vmconfigs.VMStubber, mc *vmconfigs.MachineConfig) error {
func CheckExclusiveActiveVM(provider vmconfigs.VMProvider, mc *vmconfigs.MachineConfig) error {
// Check if any other machines are running; if so, we error
localMachines, err := getMCsOverProviders([]vmconfigs.VMStubber{provider})
localMachines, err := getMCsOverProviders([]vmconfigs.VMProvider{provider})
if err != nil {
return err
}
@ -249,7 +249,7 @@ func CheckExclusiveActiveVM(provider vmconfigs.VMStubber, mc *vmconfigs.MachineC
// getMCsOverProviders loads machineconfigs from a config dir derived from the "provider". it returns only what is known on
// disk so things like status may be incomplete or inaccurate
func getMCsOverProviders(vmstubbers []vmconfigs.VMStubber) (map[string]*vmconfigs.MachineConfig, error) {
func getMCsOverProviders(vmstubbers []vmconfigs.VMProvider) (map[string]*vmconfigs.MachineConfig, error) {
mcs := make(map[string]*vmconfigs.MachineConfig)
for _, stubber := range vmstubbers {
dirs, err := machine.GetMachineDirs(stubber.VMType())
@ -274,7 +274,7 @@ func getMCsOverProviders(vmstubbers []vmconfigs.VMStubber) (map[string]*vmconfig
// Stop stops the machine as well as supporting binaries/processes
// TODO: I think this probably needs to go somewhere that remove can call it.
func Stop(mc *vmconfigs.MachineConfig, mp vmconfigs.VMStubber, dirs *machineDefine.MachineDirs, hardStop bool) error {
func Stop(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *machineDefine.MachineDirs, hardStop bool) error {
// 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.
state, err := mp.State(mc, false)
@ -318,7 +318,7 @@ func Stop(mc *vmconfigs.MachineConfig, mp vmconfigs.VMStubber, dirs *machineDefi
return nil
}
func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMStubber, dirs *machineDefine.MachineDirs, opts machine.StartOptions) error {
func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *machineDefine.MachineDirs, opts machine.StartOptions) error {
defaultBackoff := 500 * time.Millisecond
maxBackoffs := 6

View File

@ -1,4 +1,4 @@
package p5
package shim
import (
"fmt"
@ -22,7 +22,7 @@ const (
dockerConnectTimeout = 5 * time.Second
)
func startNetworking(mc *vmconfigs.MachineConfig, provider vmconfigs.VMStubber) (string, machine.APIForwardingState, error) {
func startNetworking(mc *vmconfigs.MachineConfig, provider vmconfigs.VMProvider) (string, machine.APIForwardingState, error) {
var (
forwardingState machine.APIForwardingState
forwardSock string

View File

@ -105,13 +105,13 @@ func (f fcosMachineImage) path() string {
return ""
}
type VMStubber interface { //nolint:interfacebloat
type VMProvider interface { //nolint:interfacebloat
CreateVM(opts define.CreateVMOpts, mc *MachineConfig) error
GetHyperVisorVMs() ([]string, error)
MountType() VolumeMountType
MountVolumesToVM(mc *MachineConfig, quiet bool) error
Remove(mc *MachineConfig) ([]string, func() error, error)
RemoveAndCleanMachines() error
RemoveAndCleanMachines(dirs *define.MachineDirs) error
SetProviderAttrs(mc *MachineConfig, cpus, memory *uint64, newDiskSize *strongunits.GiB) error
StartNetworking(mc *MachineConfig, cmd *gvproxy.GvproxyCommand) error
StartVM(mc *MachineConfig) (func() error, func() error, error)