Skip to content

Commit

Permalink
update README, add basic tests when using Virtualzation.framework / R…
Browse files Browse the repository at this point in the history
…osetta

Signed-off-by: Justin Alvarez <alvajus@amazon.com>
  • Loading branch information
pendo324 committed Mar 24, 2023
1 parent 1a2001a commit becc675
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 26 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,17 @@ memory: 4GiB
additional_directories:
# the path of each additional directory.
- path: /Volumes
# vmType (Experimental): sets which Hypervisor to use to launch the VM. (optional)
# Only takes effect when a new VM is launched (only on vm init).
# One of: "qemu", "vz".
# - "qemu" (default): Uses QEMU as the Hypervisor.
# - "vz": Uses Virtualization.framework as the Hypervisor.
vmType: "qemu"
# rosetta (Experimental): sets whether to enable Rosetta as the binfmt_misc handler inside the VM. (optional)
# Only takes effect when a new VM is launched (only on vm init).
# Only available when using vmType "vz" on Apple Silicon running macOS 13+.
# If true, also sets vmType to "vz".
rosetta: false
```
### FAQ
Expand Down
85 changes: 85 additions & 0 deletions e2e/vm/virtualization_framework_rosetta_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package vm

import (
"os/exec"
"path/filepath"
"runtime"

"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
"github.com/runfinch/common-tests/command"
"github.com/runfinch/common-tests/option"
"github.com/runfinch/common-tests/tests"

"github.com/runfinch/finch/e2e"
finch_cmd "github.com/runfinch/finch/pkg/command"
"github.com/runfinch/finch/pkg/config"
)

var testVirtualizationFrameworkAndRosetta = func(o *option.Option, installed bool) {
ginkgo.Describe("Virtualization framework", ginkgo.Ordered, func() {
var limaConfigFilePath string

supportsVz, supportsVzErr := config.SupportsVirtualizationFramework(finch_cmd.NewExecCmdCreator())
gomega.Expect(supportsVzErr).ShouldNot(gomega.HaveOccurred())

ginkgo.BeforeEach(func() {
origFinchCfg := readFile(finchConfigFilePath)
limaConfigFilePath = defaultLimaConfigFilePath
if installed {
path, err := exec.LookPath(e2e.InstalledTestSubject)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
realFinchPath, err := filepath.EvalSymlinks(path)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
limaConfigFilePath = filepath.Join(realFinchPath, "../../lima/data/_config/override.yaml")
}
origLimaCfg := readFile(limaConfigFilePath)

command.New(o, virtualMachineRootCmd, "stop", "-f").WithoutCheckingExitCode().WithTimeoutInSeconds(90).Run()
command.New(o, virtualMachineRootCmd, "remove", "-f").WithoutCheckingExitCode().WithTimeoutInSeconds(90).Run()

ginkgo.DeferCleanup(func() {
writeFile(finchConfigFilePath, origFinchCfg)
writeFile(limaConfigFilePath, origLimaCfg)
})
})

ginkgo.FDescribe("Virtualization framework", ginkgo.Ordered, func() {
ginkgo.BeforeEach(func() {
if !supportsVz {
ginkgo.Skip("Skipping because system does not support Virtualization.framework")
}

writeFile(finchConfigFilePath, []byte("memory: 4GiB\ncpus: 6\nvmType: vz\nrosetta: false"))
initCmdSession := command.New(o, virtualMachineRootCmd, "init").WithTimeoutInSeconds(120).Run()
gomega.Expect(initCmdSession).Should(gexec.Exit(0))
})

// Run sanity check tests
tests.Build(o)
tests.Run(&tests.RunOption{BaseOpt: o, CGMode: tests.Unified, DefaultHostGatewayIP: "192.168.5.2"})
tests.Port(o)
})

ginkgo.Describe("Virtualization framework and Rosetta", ginkgo.Ordered, func() {
ginkgo.BeforeEach(func() {
if !supportsVz || runtime.GOOS != "darwin" || runtime.GOARCH != "arm64" {
ginkgo.Skip("Skipping because system does not support Rosetta")
}

writeFile(finchConfigFilePath, []byte("memory: 4GiB\ncpus: 6\nvmType: vz\nrosetta: true"))
initCmdSession := command.New(o, virtualMachineRootCmd, "init").WithTimeoutInSeconds(120).Run()
gomega.Expect(initCmdSession).Should(gexec.Exit(0))
})

// Run sanity check tests
tests.Build(o)
tests.Run(&tests.RunOption{BaseOpt: o, CGMode: tests.Unified, DefaultHostGatewayIP: "192.168.5.2"})
tests.Port(o)
})
})
}
2 changes: 2 additions & 0 deletions e2e/vm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"

"github.com/runfinch/common-tests/command"

"github.com/runfinch/finch/e2e"
Expand Down Expand Up @@ -42,6 +43,7 @@ func TestVM(t *testing.T) {
testAdditionalDisk(o)
testConfig(o, *e2e.Installed)
testVersion(o)
testVirtualizationFrameworkAndRosetta(o, *e2e.Installed)
})

gomega.RegisterFailHandler(ginkgo.Fail)
Expand Down
27 changes: 27 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ import (
"errors"
"fmt"
"path"
"strconv"
"strings"

"github.com/lima-vm/lima/pkg/limayaml"
"github.com/spf13/afero"
"gopkg.in/yaml.v3"

"github.com/runfinch/finch/pkg/command"
"github.com/runfinch/finch/pkg/flog"
"github.com/runfinch/finch/pkg/fmemory"
"github.com/runfinch/finch/pkg/system"
Expand Down Expand Up @@ -149,3 +152,27 @@ func Load(fs afero.Fs, cfgPath string, log flog.Logger, systemDeps LoadSystemDep

return defCfg, nil
}

func SupportsVirtualizationFramework(cmdCreator command.Creator) (bool, error) {
cmd := cmdCreator.Create("sw_vers", "-productVersion")
out, err := cmd.Output()
if err != nil {
return false, fmt.Errorf("failed to run sw_vers command: %w", err)
}

splitVer := strings.Split(string(out), ".")
if len(splitVer) == 0 {
return false, fmt.Errorf("unexpected result from string split: %v", splitVer)
}

majorVersionInt, err := strconv.ParseInt(splitVer[0], 10, 64)
if err != nil {
return false, fmt.Errorf("failed to parse split sw_vers output (%s) into int: %w", splitVer[0], err)
}

if majorVersionInt >= 11 {
return true, nil
}

return false, nil
}
27 changes: 1 addition & 26 deletions pkg/config/lima_config_applier.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package config

import (
"fmt"
"strconv"
"strings"

"github.com/lima-vm/lima/pkg/limayaml"
Expand Down Expand Up @@ -107,7 +106,7 @@ func (lca *limaConfigApplier) Apply(isInit bool) error {

// applyInit changes settings that will only apply to the VM after a new init.
func (lca *limaConfigApplier) applyInit(limaCfg *limayaml.LimaYAML) (*limayaml.LimaYAML, error) {
hasSupport, hasSupportErr := lca.supportsVirtualizationFramework()
hasSupport, hasSupportErr := SupportsVirtualizationFramework(lca.cmdCreator)
if *lca.cfg.Rosetta &&
lca.systemDeps.OS() == "darwin" &&
lca.systemDeps.Arch() == "arm64" {
Expand Down Expand Up @@ -173,27 +172,3 @@ func hasUserModeEmulationInstallationScript(limaCfg *limayaml.LimaYAML) (int, bo

return scriptIdx, hasCrossArchToolInstallationScript
}

func (lca *limaConfigApplier) supportsVirtualizationFramework() (bool, error) {
cmd := lca.cmdCreator.Create("sw_vers", "-productVersion")
out, err := cmd.Output()
if err != nil {
return false, fmt.Errorf("failed to run sw_vers command: %w", err)
}

splitVer := strings.Split(string(out), ".")
if len(splitVer) == 0 {
return false, fmt.Errorf("unexpected result from string split: %v", splitVer)
}

majorVersionInt, err := strconv.ParseInt(splitVer[0], 10, 64)
if err != nil {
return false, fmt.Errorf("failed to parse split sw_vers output (%s) into int: %w", splitVer[0], err)
}

if majorVersionInt >= 11 {
return true, nil
}

return false, nil
}

0 comments on commit becc675

Please sign in to comment.