Skip to content

Commit

Permalink
vm: default to vz for m3 devices (#924)
Browse files Browse the repository at this point in the history
  • Loading branch information
abiosoft authored Dec 10, 2023
1 parent a8d533d commit ba1be00
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 144 deletions.
10 changes: 10 additions & 0 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ func setDefaults(cmd *cobra.Command) {
startCmdArgs.VMType = defaultVMType
}

// m3 devices cannot use qemu
if util.M3() {
startCmdArgs.VMType = "vz"
cmd.Flag("vm-type").Changed = true
}

if util.MacOS13OrNewer() {
// changing to vz implies changing mount type to virtiofs
if cmd.Flag("vm-type").Changed && startCmdArgs.VMType == "vz" && !cmd.Flag("mount-type").Changed {
Expand Down Expand Up @@ -275,6 +281,10 @@ func setConfigDefaults(conf *config.Config) {
if conf.VMType == "" {
conf.VMType = defaultVMType
}
// m3 devices cannot use qemu
if util.M3() {
conf.VMType = "vz"
}

if conf.MountType == "" {
conf.MountType = defaultMountTypeQEMU
Expand Down
105 changes: 105 additions & 0 deletions util/macos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package util

import (
"bytes"
"encoding/json"
"fmt"
"os/exec"
"runtime"
"strings"

"github.com/abiosoft/colima/cli"
"github.com/coreos/go-semver/semver"
"github.com/sirupsen/logrus"
)

// MacOS returns if the current OS is macOS.
func MacOS() bool {
return runtime.GOOS == "darwin"
}

// MacOS13OrNewer returns if the current OS is macOS 13 or newer.
func MacOS13OrNewerOnM1() bool {
return runtime.GOARCH == "arm64" && MacOS13OrNewer()
}

// MacOS13OrNewer returns if the current OS is macOS 13 or newer.
func MacOS13OrNewer() bool {
if !MacOS() {
return false
}
ver, err := macOSProductVersion()
if err != nil {
logrus.Warnln(fmt.Errorf("error retrieving macOS version: %w", err))
return false
}

cver, err := semver.NewVersion("13.0.0")
if err != nil {
logrus.Warnln(fmt.Errorf("error parsing version: %w", err))
return false
}

return cver.Compare(*ver) <= 0
}

// M3 returns if the current device is an Apple M3 device.
func M3() bool {
var resp struct {
SPHardwareDataType []struct {
ChipType string `json:"chip_type"`
} `json:"SPHardwareDataType"`
}

var buf bytes.Buffer
cmd := cli.Command("system_profiler", "-json", "SPHardwareDataType")
cmd.Stdout = &buf

if err := cmd.Run(); err != nil {
logrus.Trace(fmt.Errorf("error retriving chip version: %w", err))
return false
}

if err := json.NewDecoder(&buf).Decode(&resp); err != nil {
logrus.Trace(fmt.Errorf("error decoding system_profiler response: %w", err))
return false
}

if len(resp.SPHardwareDataType) == 0 {
return false
}

chipType := strings.ToUpper(resp.SPHardwareDataType[0].ChipType)
return strings.Contains(chipType, "M3")
}

// RosettaRunning checks if Rosetta process is running.
func RosettaRunning() bool {
if !MacOS() {
return false
}
cmd := cli.Command("pgrep", "oahd")
cmd.Stderr = nil
cmd.Stdout = nil
return cmd.Run() == nil
}

// macOSProductVersion returns the host's macOS version.
func macOSProductVersion() (*semver.Version, error) {
cmd := exec.Command("sw_vers", "-productVersion")
// output is like "12.3.1\n"
b, err := cmd.Output()
if err != nil {
return nil, fmt.Errorf("failed to execute %v: %w", cmd.Args, err)
}
verTrimmed := strings.TrimSpace(string(b))
// macOS 12.4 returns just "12.4\n"
for strings.Count(verTrimmed, ".") < 2 {
verTrimmed += ".0"
}
verSem, err := semver.NewVersion(verTrimmed)
if err != nil {
return nil, fmt.Errorf("failed to parse macOS version %q: %w", verTrimmed, err)
}
return verSem, nil
}
88 changes: 0 additions & 88 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ import (
"fmt"
"net"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"

"github.com/abiosoft/colima/cli"
"github.com/coreos/go-semver/semver"
"github.com/google/shlex"
"github.com/sirupsen/logrus"
)
Expand All @@ -25,70 +21,6 @@ func HomeDir() string {
return home
}

// MacOS returns if the current OS is macOS.
func MacOS() bool {
return runtime.GOOS == "darwin"
}

// MacOS13OrNewer returns if the current OS is macOS 13 or newer.
func MacOS13OrNewerOnM1() bool {
return runtime.GOARCH == "arm64" && MacOS13OrNewer()
}

// MacOS13OrNewer returns if the current OS is macOS 13 or newer.
func MacOS13OrNewer() bool {
if !MacOS() {
return false
}
ver, err := macOSProductVersion()
if err != nil {
logrus.Warnln(fmt.Errorf("error retrieving macOS version: %w", err))
return false
}

cver, err := semver.NewVersion("13.0.0")
if err != nil {
logrus.Warnln(fmt.Errorf("error parsing version: %w", err))
return false
}

return cver.Compare(*ver) <= 0
}

// RosettaRunning checks if Rosetta process is running.
func RosettaRunning() bool {
if !MacOS() {
return false
}
cmd := cli.Command("pgrep", "oahd")
cmd.Stderr = nil
cmd.Stdout = nil
return cmd.Run() == nil
}

// AppendToPath appends directory to PATH.
func AppendToPath(path, dir string) string {
if path == "" {
return dir
}
if dir == "" {
return path
}
return dir + ":" + path
}

// RemoveFromPath removes directory from PATH.
func RemoveFromPath(path, dir string) string {
var envPath []string
for _, p := range strings.Split(path, ":") {
if strings.TrimSuffix(p, "/") == strings.TrimSuffix(dir, "/") || strings.TrimSpace(p) == "" {
continue
}
envPath = append(envPath, p)
}
return strings.Join(envPath, ":")
}

// RandomAvailablePort returns an available port on the host machine.
func RandomAvailablePort() int {
listener, err := net.Listen("tcp", ":0")
Expand Down Expand Up @@ -135,23 +67,3 @@ func CleanPath(location string) (string, error) {

return strings.TrimSuffix(str, "/") + "/", nil
}

// macOSProductVersion returns the host's macOS version.
func macOSProductVersion() (*semver.Version, error) {
cmd := exec.Command("sw_vers", "-productVersion")
// output is like "12.3.1\n"
b, err := cmd.Output()
if err != nil {
return nil, fmt.Errorf("failed to execute %v: %w", cmd.Args, err)
}
verTrimmed := strings.TrimSpace(string(b))
// macOS 12.4 returns just "12.4\n"
for strings.Count(verTrimmed, ".") < 2 {
verTrimmed += ".0"
}
verSem, err := semver.NewVersion(verTrimmed)
if err != nil {
return nil, fmt.Errorf("failed to parse macOS version %q: %w", verTrimmed, err)
}
return verSem, nil
}
56 changes: 0 additions & 56 deletions util/util_test.go

This file was deleted.

0 comments on commit ba1be00

Please sign in to comment.