Skip to content

Commit

Permalink
Merge pull request #22479 from jakecorrenti/provider-detection
Browse files Browse the repository at this point in the history
machine: Add provider detection API
  • Loading branch information
openshift-merge-bot[bot] authored May 7, 2024
2 parents 6a551b3 + 431cbff commit 97f3f9c
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 0 deletions.
30 changes: 30 additions & 0 deletions pkg/machine/provider/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
package provider

import (
"errors"
"fmt"
"io/fs"
"os"

"github.com/containers/common/pkg/config"
Expand Down Expand Up @@ -35,3 +37,31 @@ func Get() (vmconfigs.VMProvider, error) {
return nil, fmt.Errorf("unsupported virtualization provider: `%s`", resolvedVMType.String())
}
}

// 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) {
cfg, err := config.Default()
if err != nil {
return nil, err
}
_, err = cfg.FindHelperBinary(qemu.QemuCommand, true)
if errors.Is(err, fs.ErrNotExist) {
return []define.VMType{}, nil
}
if err != nil {
return nil, err
}

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
}
47 changes: 47 additions & 0 deletions pkg/machine/provider/platform_darwin.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package provider

import (
"bytes"
"errors"
"fmt"
"os"
"os/exec"
"strconv"
"strings"

"github.com/containers/common/pkg/config"
"github.com/containers/podman/v5/pkg/machine/applehv"
Expand Down Expand Up @@ -36,3 +41,45 @@ func Get() (vmconfigs.VMProvider, error) {
return nil, fmt.Errorf("unsupported virtualization provider: `%s`", resolvedVMType.String())
}
}

// SupportedProviders returns the providers that are supported on the host operating system
func SupportedProviders() []define.VMType {
return []define.VMType{define.AppleHvVirt}
}

// InstalledProviders returns the supported providers that are installed on the host
func InstalledProviders() ([]define.VMType, error) {
var outBuf bytes.Buffer
// Apple's Virtualization.Framework is only supported on MacOS 11.0+
const SupportedMacOSVersion = 11

cmd := exec.Command("sw_vers", "--productVersion")
cmd.Stdout = &outBuf
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("unable to check current macOS version using `sw_vers --productVersion`: %s", err)
}

// the output will be in the format of MAJOR.MINOR.PATCH
output := outBuf.String()
idx := strings.Index(output, ".")
if idx < 0 {
return nil, errors.New("invalid output provided by sw_vers --productVersion")
}
majorString := output[:idx]
majorInt, err := strconv.Atoi(majorString)
if err != nil {
return nil, err
}

if majorInt >= SupportedMacOSVersion {
return []define.VMType{define.AppleHvVirt}, nil
}

return []define.VMType{}, 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 AppleHV
return provider == define.AppleHvVirt
}
76 changes: 76 additions & 0 deletions pkg/machine/provider/platform_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package provider

import (
"runtime"
"testing"

"github.com/containers/podman/v5/pkg/machine/define"
"github.com/stretchr/testify/assert"
)

func TestSupportedProviders(t *testing.T) {
switch runtime.GOOS {
case "darwin":
assert.Equal(t, []define.VMType{define.AppleHvVirt}, SupportedProviders())
case "windows":
assert.Equal(t, []define.VMType{define.WSLVirt, define.HyperVVirt}, SupportedProviders())
case "linux":
assert.Equal(t, []define.VMType{define.QemuVirt}, SupportedProviders())
}
}

func TestInstalledProviders(t *testing.T) {
installed, err := InstalledProviders()
assert.Nil(t, err)
switch runtime.GOOS {
case "darwin":
assert.Equal(t, []define.VMType{define.AppleHvVirt}, installed)
case "windows":
provider, err := Get()
assert.Nil(t, err)
assert.Contains(t, installed, provider)
case "linux":
assert.Equal(t, []define.VMType{define.QemuVirt}, installed)
}
}

func TestHasPermsForProvider(t *testing.T) {
provider, err := Get()
assert.Nil(t, err)
assert.True(t, HasPermsForProvider(provider.VMType()))
}

func TestHasBadPerms(t *testing.T) {
switch runtime.GOOS {
case "darwin":
assert.False(t, HasPermsForProvider(define.QemuVirt))
case "windows":
assert.False(t, HasPermsForProvider(define.QemuVirt))
case "linux":
assert.False(t, HasPermsForProvider(define.AppleHvVirt))
}
}

func TestBadSupportedProviders(t *testing.T) {
switch runtime.GOOS {
case "darwin":
assert.NotEqual(t, []define.VMType{define.QemuVirt}, SupportedProviders())
case "windows":
assert.NotEqual(t, []define.VMType{define.QemuVirt}, SupportedProviders())
case "linux":
assert.NotEqual(t, []define.VMType{define.AppleHvVirt}, SupportedProviders())
}
}

func TestBadInstalledProviders(t *testing.T) {
installed, err := InstalledProviders()
assert.Nil(t, err)
switch runtime.GOOS {
case "darwin":
assert.NotEqual(t, []define.VMType{define.QemuVirt}, installed)
case "windows":
assert.NotContains(t, installed, define.QemuVirt)
case "linux":
assert.NotEqual(t, []define.VMType{define.AppleHvVirt}, installed)
}
}
37 changes: 37 additions & 0 deletions pkg/machine/provider/platform_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"fmt"
"os"

"github.com/containers/libhvee/pkg/hypervctl"
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
"github.com/containers/podman/v5/pkg/machine/wsl"
"github.com/containers/podman/v5/pkg/machine/wsl/wutil"

"github.com/containers/common/pkg/config"
"github.com/containers/podman/v5/pkg/machine/define"
Expand Down Expand Up @@ -40,3 +42,38 @@ func Get() (vmconfigs.VMProvider, error) {
return nil, fmt.Errorf("unsupported virtualization provider: `%s`", resolvedVMType.String())
}
}

// SupportedProviders returns the providers that are supported on the host operating system
func SupportedProviders() []define.VMType {
return []define.VMType{define.HyperVVirt, define.WSLVirt}
}

// InstalledProviders returns the supported providers that are installed on the host
func InstalledProviders() ([]define.VMType, error) {
installed := []define.VMType{}
if wutil.IsWSLInstalled() {
installed = append(installed, define.WSLVirt)
}

service, err := hypervctl.NewLocalHyperVService()
if err == nil {
installed = append(installed, define.HyperVVirt)
}
service.Close()

return installed, nil
}

// HasPermsForProvider returns whether the host operating system has the proper permissions to use the given provider
func HasPermsForProvider(provider define.VMType) bool {
switch provider {
case define.QemuVirt:
fallthrough
case define.AppleHvVirt:
return false
case define.HyperVVirt:
return wsl.HasAdminRights()
}

return true
}

1 comment on commit 97f3f9c

@packit-as-a-service
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

podman-next COPR build failed. @containers/packit-build please check.

Please sign in to comment.