mirror of
https://github.com/containers/podman.git
synced 2025-05-21 17:16:22 +08:00
machine: Add -all-providers flag to machine list
Podman machine list now supports a new option, --all-providers, which lists all machines from all providers. Signed-off-by: Ashley Cui <acui@redhat.com>
This commit is contained in:
@ -7,15 +7,18 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/completion"
|
"github.com/containers/common/pkg/completion"
|
||||||
|
"github.com/containers/common/pkg/config"
|
||||||
"github.com/containers/common/pkg/report"
|
"github.com/containers/common/pkg/report"
|
||||||
"github.com/containers/podman/v5/cmd/podman/common"
|
"github.com/containers/podman/v5/cmd/podman/common"
|
||||||
"github.com/containers/podman/v5/cmd/podman/registry"
|
"github.com/containers/podman/v5/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v5/cmd/podman/validate"
|
"github.com/containers/podman/v5/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v5/pkg/domain/entities"
|
"github.com/containers/podman/v5/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v5/pkg/machine"
|
"github.com/containers/podman/v5/pkg/machine"
|
||||||
|
provider2 "github.com/containers/podman/v5/pkg/machine/provider"
|
||||||
"github.com/containers/podman/v5/pkg/machine/shim"
|
"github.com/containers/podman/v5/pkg/machine/shim"
|
||||||
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
@ -28,7 +31,8 @@ var (
|
|||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Short: "List machines",
|
Short: "List machines",
|
||||||
Long: "List managed virtual machines.",
|
Long: "List managed virtual machines.",
|
||||||
PersistentPreRunE: machinePreRunE,
|
// do not use machinePreRunE, as that pre-sets the provider
|
||||||
|
PersistentPreRunE: rootlessOnly,
|
||||||
RunE: list,
|
RunE: list,
|
||||||
Args: validate.NoArgs,
|
Args: validate.NoArgs,
|
||||||
ValidArgsFunction: completion.AutocompleteNone,
|
ValidArgsFunction: completion.AutocompleteNone,
|
||||||
@ -43,6 +47,7 @@ type listFlagType struct {
|
|||||||
format string
|
format string
|
||||||
noHeading bool
|
noHeading bool
|
||||||
quiet bool
|
quiet bool
|
||||||
|
allProviders bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -57,6 +62,7 @@ func init() {
|
|||||||
_ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.ListReporter{}))
|
_ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.ListReporter{}))
|
||||||
flags.BoolVarP(&listFlag.noHeading, "noheading", "n", false, "Do not print headers")
|
flags.BoolVarP(&listFlag.noHeading, "noheading", "n", false, "Do not print headers")
|
||||||
flags.BoolVarP(&listFlag.quiet, "quiet", "q", false, "Show only machine names")
|
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, args []string) error {
|
func list(cmd *cobra.Command, args []string) error {
|
||||||
@ -64,8 +70,18 @@ func list(cmd *cobra.Command, args []string) error {
|
|||||||
opts machine.ListOptions
|
opts machine.ListOptions
|
||||||
err error
|
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}
|
||||||
|
}
|
||||||
|
|
||||||
listResponse, err := shim.List([]vmconfigs.VMProvider{provider}, opts)
|
listResponse, err := shim.List(providers, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -79,12 +95,8 @@ func list(cmd *cobra.Command, args []string) error {
|
|||||||
return listResponse[i].Running
|
return listResponse[i].Running
|
||||||
})
|
})
|
||||||
|
|
||||||
defaultCon := ""
|
|
||||||
con, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetConnection("", true)
|
|
||||||
if err == nil {
|
|
||||||
// ignore the error here we only want to know if we have a default connection to show it in list
|
// ignore the error here we only want to know if we have a default connection to show it in list
|
||||||
defaultCon = con.Name
|
defaultCon, _ := registry.PodmanConfig().ContainersConfDefaultsRO.GetConnection("", true)
|
||||||
}
|
|
||||||
|
|
||||||
if report.IsJSON(listFlag.format) {
|
if report.IsJSON(listFlag.format) {
|
||||||
machineReporter := toMachineFormat(listResponse, defaultCon)
|
machineReporter := toMachineFormat(listResponse, defaultCon)
|
||||||
@ -152,11 +164,16 @@ func streamName(imageStream string) string {
|
|||||||
return imageStream
|
return imageStream
|
||||||
}
|
}
|
||||||
|
|
||||||
func toMachineFormat(vms []*machine.ListResponse, defaultCon string) []*entities.ListReporter {
|
func toMachineFormat(vms []*machine.ListResponse, defaultCon *config.Connection) []*entities.ListReporter {
|
||||||
machineResponses := make([]*entities.ListReporter, 0, len(vms))
|
machineResponses := make([]*entities.ListReporter, 0, len(vms))
|
||||||
for _, vm := range vms {
|
for _, vm := range vms {
|
||||||
|
isDefault := false
|
||||||
|
// check port, in case we somehow have machines with the same name in different providers
|
||||||
|
if defaultCon != nil {
|
||||||
|
isDefault = vm.Name == defaultCon.Name && strings.Contains(defaultCon.URI, strconv.Itoa((vm.Port)))
|
||||||
|
}
|
||||||
response := new(entities.ListReporter)
|
response := new(entities.ListReporter)
|
||||||
response.Default = vm.Name == defaultCon
|
response.Default = isDefault
|
||||||
response.Name = vm.Name
|
response.Name = vm.Name
|
||||||
response.Running = vm.Running
|
response.Running = vm.Running
|
||||||
response.LastUp = strTime(vm.LastUp)
|
response.LastUp = strTime(vm.LastUp)
|
||||||
@ -177,11 +194,16 @@ func toMachineFormat(vms []*machine.ListResponse, defaultCon string) []*entities
|
|||||||
return machineResponses
|
return machineResponses
|
||||||
}
|
}
|
||||||
|
|
||||||
func toHumanFormat(vms []*machine.ListResponse, defaultCon string) []*entities.ListReporter {
|
func toHumanFormat(vms []*machine.ListResponse, defaultCon *config.Connection) []*entities.ListReporter {
|
||||||
humanResponses := make([]*entities.ListReporter, 0, len(vms))
|
humanResponses := make([]*entities.ListReporter, 0, len(vms))
|
||||||
for _, vm := range vms {
|
for _, vm := range vms {
|
||||||
response := new(entities.ListReporter)
|
response := new(entities.ListReporter)
|
||||||
if vm.Name == defaultCon {
|
isDefault := false
|
||||||
|
// check port, in case we somehow have machines with the same name in different providers
|
||||||
|
if defaultCon != nil {
|
||||||
|
isDefault = vm.Name == defaultCon.Name && strings.Contains(defaultCon.URI, strconv.Itoa((vm.Port)))
|
||||||
|
}
|
||||||
|
if isDefault {
|
||||||
response.Name = vm.Name + "*"
|
response.Name = vm.Name + "*"
|
||||||
response.Default = true
|
response.Default = true
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/containers/podman/v5/pkg/machine"
|
"github.com/containers/podman/v5/pkg/machine"
|
||||||
provider2 "github.com/containers/podman/v5/pkg/machine/provider"
|
provider2 "github.com/containers/podman/v5/pkg/machine/provider"
|
||||||
"github.com/containers/podman/v5/pkg/machine/shim"
|
"github.com/containers/podman/v5/pkg/machine/shim"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -50,10 +51,18 @@ func reset(_ *cobra.Command, _ []string) error {
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
providers, err := provider2.GetAll(resetOptions.Force)
|
providers := provider2.GetAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for _, p := range providers {
|
||||||
|
hasPerms := provider2.HasPermsForProvider(p.VMType())
|
||||||
|
isInstalled, err := provider2.IsInstalled(p.VMType())
|
||||||
|
if !hasPerms && (isInstalled || err != nil) && !resetOptions.Force {
|
||||||
|
logrus.Warnf("Managing %s machines require admin authority.", p.VMType().String())
|
||||||
|
logrus.Warnf("Continuing to reset may cause Podman to be unaware of remaining VMs in the VM manager.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !resetOptions.Force {
|
if !resetOptions.Force {
|
||||||
listResponse, err := shim.List(providers, machine.ListOptions{})
|
listResponse, err := shim.List(providers, machine.ListOptions{})
|
||||||
|
@ -26,6 +26,10 @@ environment variable while the machines are running can lead to unexpected behav
|
|||||||
|
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
|
#### **--all-providers**
|
||||||
|
|
||||||
|
Show machines from all providers
|
||||||
|
|
||||||
#### **--format**=*format*
|
#### **--format**=*format*
|
||||||
|
|
||||||
Change the default output format. This can be of a supported type like 'json'
|
Change the default output format. This can be of a supported type like 'json'
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
package e2e_test
|
package e2e_test
|
||||||
|
|
||||||
|
import "github.com/containers/podman/v5/pkg/machine/define"
|
||||||
|
|
||||||
const podmanBinary = "../../../bin/darwin/podman"
|
const podmanBinary = "../../../bin/darwin/podman"
|
||||||
|
|
||||||
|
func getOtherProvider() string {
|
||||||
|
if isVmtype(define.AppleHvVirt) {
|
||||||
|
return "libkrun"
|
||||||
|
} else if isVmtype(define.LibKrun) {
|
||||||
|
return "applehv"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
package e2e_test
|
package e2e_test
|
||||||
|
|
||||||
const podmanBinary = "../../../bin/podman-remote"
|
const podmanBinary = "../../../bin/podman-remote"
|
||||||
|
|
||||||
|
func getOtherProvider() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@ type listMachine struct {
|
|||||||
format string
|
format string
|
||||||
noHeading bool
|
noHeading bool
|
||||||
quiet bool
|
quiet bool
|
||||||
|
allProviders bool
|
||||||
|
|
||||||
cmd []string
|
cmd []string
|
||||||
}
|
}
|
||||||
@ -25,6 +26,10 @@ func (i *listMachine) buildCmd(m *machineTestBuilder) []string {
|
|||||||
if i.quiet {
|
if i.quiet {
|
||||||
cmd = append(cmd, "--quiet")
|
cmd = append(cmd, "--quiet")
|
||||||
}
|
}
|
||||||
|
if i.allProviders {
|
||||||
|
cmd = append(cmd, "--all-providers")
|
||||||
|
}
|
||||||
|
|
||||||
i.cmd = cmd
|
i.cmd = cmd
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@ -43,3 +48,8 @@ func (i *listMachine) withFormat(format string) *listMachine {
|
|||||||
i.format = format
|
i.format = format
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *listMachine) withAllProviders() *listMachine {
|
||||||
|
i.allProviders = true
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
)
|
)
|
||||||
|
|
||||||
const podmanBinary = "../../../bin/windows/podman.exe"
|
const podmanBinary = "../../../bin/windows/podman.exe"
|
||||||
@ -23,3 +25,12 @@ func pgrep(n string) (string, error) {
|
|||||||
}
|
}
|
||||||
return strOut, nil
|
return strOut, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOtherProvider() string {
|
||||||
|
if isVmtype(define.WSLVirt) {
|
||||||
|
return "hyperv"
|
||||||
|
} else if isVmtype(define.HyperVVirt) {
|
||||||
|
return "wsl"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package e2e_test
|
package e2e_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/podman/v5/pkg/domain/entities"
|
"github.com/containers/podman/v5/pkg/domain/entities"
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@ -182,6 +184,47 @@ var _ = Describe("podman machine list", func() {
|
|||||||
Expect(listSession).To(Exit(0))
|
Expect(listSession).To(Exit(0))
|
||||||
Expect(listSession.outputToString()).To(Equal("2GiB 11GiB"))
|
Expect(listSession.outputToString()).To(Equal("2GiB 11GiB"))
|
||||||
})
|
})
|
||||||
|
It("list machine from all providers", func() {
|
||||||
|
skipIfVmtype(define.QemuVirt, "linux only has one provider")
|
||||||
|
|
||||||
|
// create machine on other provider
|
||||||
|
currprovider := os.Getenv("CONTAINERS_MACHINE_PROVIDER")
|
||||||
|
os.Setenv("CONTAINERS_MACHINE_PROVIDER", getOtherProvider())
|
||||||
|
defer os.Setenv("CONTAINERS_MACHINE_PROVIDER", currprovider)
|
||||||
|
|
||||||
|
// this may take a long time - we're not pre-fetching this image
|
||||||
|
othermach := new(initMachine)
|
||||||
|
session, err := mb.setName("otherprovider").setCmd(othermach).run()
|
||||||
|
// make sure to remove machine from other provider later
|
||||||
|
defer func() {
|
||||||
|
os.Setenv("CONTAINERS_MACHINE_PROVIDER", getOtherProvider())
|
||||||
|
defer os.Setenv("CONTAINERS_MACHINE_PROVIDER", currprovider)
|
||||||
|
rm := new(rmMachine)
|
||||||
|
removed, err := mb.setName("otherprovider").setCmd(rm.withForce()).run()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(removed).To(Exit(0))
|
||||||
|
}()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(session).To(Exit(0))
|
||||||
|
|
||||||
|
// change back to current provider
|
||||||
|
os.Setenv("CONTAINERS_MACHINE_PROVIDER", currprovider)
|
||||||
|
name := randomString()
|
||||||
|
i := new(initMachine)
|
||||||
|
session, err = mb.setName(name).setCmd(i.withImage(mb.imagePath)).run()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(session).To(Exit(0))
|
||||||
|
|
||||||
|
list := new(listMachine)
|
||||||
|
listSession, err := mb.setCmd(list.withAllProviders().withFormat("{{.Name}}")).run()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(listSession).To(Exit(0))
|
||||||
|
listNames := listSession.outputToStringSlice()
|
||||||
|
stripAsterisk(listNames)
|
||||||
|
Expect(listNames).To(HaveLen(2))
|
||||||
|
Expect(slices.Contains(listNames, "otherprovider")).To(BeTrue())
|
||||||
|
Expect(slices.Contains(listNames, name)).To(BeTrue())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
func stripAsterisk(sl []string) {
|
func stripAsterisk(sl []string) {
|
||||||
|
@ -1,71 +1,20 @@
|
|||||||
//go:build !windows && !darwin
|
|
||||||
|
|
||||||
package provider
|
package provider
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
"github.com/containers/podman/v5/pkg/machine/define"
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
"github.com/containers/podman/v5/pkg/machine/qemu"
|
|
||||||
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Get() (vmconfigs.VMProvider, 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 := define.ParseVMType(provider, define.QemuVirt)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
logrus.Debugf("Using Podman machine with `%s` virtualization provider", resolvedVMType.String())
|
|
||||||
switch resolvedVMType {
|
|
||||||
case define.QemuVirt:
|
|
||||||
return qemu.NewStubber()
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unsupported virtualization provider: `%s`", resolvedVMType.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetAll(_ bool) ([]vmconfigs.VMProvider, error) {
|
|
||||||
return []vmconfigs.VMProvider{new(qemu.QEMUStubber)}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportedProviders returns the providers that are supported on the host operating system
|
|
||||||
func SupportedProviders() []define.VMType {
|
|
||||||
return []define.VMType{define.QemuVirt}
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstalledProviders returns the supported providers that are installed on the host
|
|
||||||
func InstalledProviders() ([]define.VMType, error) {
|
func InstalledProviders() ([]define.VMType, error) {
|
||||||
cfg, err := config.Default()
|
installedTypes := []define.VMType{}
|
||||||
|
providers := GetAll()
|
||||||
|
for _, p := range providers {
|
||||||
|
installed, err := IsInstalled(p.VMType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = cfg.FindHelperBinary(qemu.QemuCommand, true)
|
if installed {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
installedTypes = append(installedTypes, p.VMType())
|
||||||
return []define.VMType{}, nil
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
return installedTypes, nil
|
||||||
return []define.VMType{define.QemuVirt}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasPermsForProvider returns whether the host operating system has the proper permissions to use the given provider
|
|
||||||
func HasPermsForProvider(provider define.VMType) bool {
|
|
||||||
// there are no permissions required for QEMU
|
|
||||||
return provider == define.QemuVirt
|
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,11 @@ func Get() (vmconfigs.VMProvider, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAll(_ bool) ([]vmconfigs.VMProvider, error) {
|
func GetAll() []vmconfigs.VMProvider {
|
||||||
return []vmconfigs.VMProvider{
|
return []vmconfigs.VMProvider{
|
||||||
new(applehv.AppleHVStubber),
|
new(applehv.AppleHVStubber),
|
||||||
new(libkrun.LibKrunStubber),
|
new(libkrun.LibKrunStubber),
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SupportedProviders returns the providers that are supported on the host operating system
|
// SupportedProviders returns the providers that are supported on the host operating system
|
||||||
@ -58,27 +58,23 @@ func SupportedProviders() []define.VMType {
|
|||||||
return supported
|
return supported
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstalledProviders returns the supported providers that are installed on the host
|
func IsInstalled(provider define.VMType) (bool, error) {
|
||||||
func InstalledProviders() ([]define.VMType, error) {
|
switch provider {
|
||||||
installed := []define.VMType{}
|
case define.AppleHvVirt:
|
||||||
|
ahv, err := appleHvInstalled()
|
||||||
appleHvInstalled, err := appleHvInstalled()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return false, err
|
||||||
}
|
}
|
||||||
if appleHvInstalled {
|
return ahv, nil
|
||||||
installed = append(installed, define.AppleHvVirt)
|
case define.LibKrun:
|
||||||
}
|
lkr, err := libKrunInstalled()
|
||||||
|
|
||||||
libKrunInstalled, err := libKrunInstalled()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return false, err
|
||||||
}
|
}
|
||||||
if libKrunInstalled {
|
return lkr, nil
|
||||||
installed = append(installed, define.LibKrun)
|
default:
|
||||||
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return installed, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func appleHvInstalled() (bool, error) {
|
func appleHvInstalled() (bool, error) {
|
||||||
|
77
pkg/machine/provider/platform_unix.go
Normal file
77
pkg/machine/provider/platform_unix.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//go:build !windows && !darwin
|
||||||
|
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/containers/common/pkg/config"
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/qemu"
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Get() (vmconfigs.VMProvider, 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 := define.ParseVMType(provider, define.QemuVirt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("Using Podman machine with `%s` virtualization provider", resolvedVMType.String())
|
||||||
|
switch resolvedVMType {
|
||||||
|
case define.QemuVirt:
|
||||||
|
return qemu.NewStubber()
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported virtualization provider: `%s`", resolvedVMType.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAll() []vmconfigs.VMProvider {
|
||||||
|
return []vmconfigs.VMProvider{new(qemu.QEMUStubber)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupportedProviders returns the providers that are supported on the host operating system
|
||||||
|
func SupportedProviders() []define.VMType {
|
||||||
|
return []define.VMType{define.QemuVirt}
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsInstalled(provider define.VMType) (bool, error) {
|
||||||
|
switch provider {
|
||||||
|
case define.QemuVirt:
|
||||||
|
cfg, err := config.Default()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if cfg == nil {
|
||||||
|
return false, fmt.Errorf("error fetching getting default config")
|
||||||
|
}
|
||||||
|
_, err = cfg.FindHelperBinary(qemu.QemuCommand, true)
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
default:
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasPermsForProvider returns whether the host operating system has the proper permissions to use the given provider
|
||||||
|
func HasPermsForProvider(provider define.VMType) bool {
|
||||||
|
// there are no permissions required for QEMU
|
||||||
|
return provider == define.QemuVirt
|
||||||
|
}
|
@ -43,16 +43,11 @@ func Get() (vmconfigs.VMProvider, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAll(force bool) ([]vmconfigs.VMProvider, error) {
|
func GetAll() []vmconfigs.VMProvider {
|
||||||
providers := []vmconfigs.VMProvider{
|
return []vmconfigs.VMProvider{
|
||||||
new(wsl.WSLStubber),
|
new(wsl.WSLStubber),
|
||||||
|
new(hyperv.HyperVStubber),
|
||||||
}
|
}
|
||||||
if !wsl.HasAdminRights() && !force {
|
|
||||||
logrus.Warn("managing hyperv machines require admin authority.")
|
|
||||||
} else {
|
|
||||||
providers = append(providers, new(hyperv.HyperVStubber))
|
|
||||||
}
|
|
||||||
return providers, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SupportedProviders returns the providers that are supported on the host operating system
|
// SupportedProviders returns the providers that are supported on the host operating system
|
||||||
@ -60,20 +55,22 @@ func SupportedProviders() []define.VMType {
|
|||||||
return []define.VMType{define.HyperVVirt, define.WSLVirt}
|
return []define.VMType{define.HyperVVirt, define.WSLVirt}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstalledProviders returns the supported providers that are installed on the host
|
func IsInstalled(provider define.VMType) (bool, error) {
|
||||||
func InstalledProviders() ([]define.VMType, error) {
|
switch provider {
|
||||||
installed := []define.VMType{}
|
case define.WSLVirt:
|
||||||
if wutil.IsWSLInstalled() {
|
return wutil.IsWSLInstalled(), nil
|
||||||
installed = append(installed, define.WSLVirt)
|
case define.HyperVVirt:
|
||||||
}
|
|
||||||
|
|
||||||
service, err := hypervctl.NewLocalHyperVService()
|
service, err := hypervctl.NewLocalHyperVService()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
installed = append(installed, define.HyperVVirt)
|
return true, nil
|
||||||
|
}
|
||||||
|
if service != nil {
|
||||||
|
defer service.Close()
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
default:
|
||||||
|
return false, nil
|
||||||
}
|
}
|
||||||
service.Close()
|
|
||||||
|
|
||||||
return installed, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasPermsForProvider returns whether the host operating system has the proper permissions to use the given provider
|
// HasPermsForProvider returns whether the host operating system has the proper permissions to use the given provider
|
||||||
|
Reference in New Issue
Block a user