diff --git a/pkg/crc/cache/cache.go b/pkg/crc/cache/cache.go index 6cd2cf027f..1216599527 100644 --- a/pkg/crc/cache/cache.go +++ b/pkg/crc/cache/cache.go @@ -59,7 +59,7 @@ func getVersionGeneric(executablePath string, args ...string) (string, error) { logging.Debugf("failed to run executable %s: %v", executablePath, err) return "", err } - parsedOutput := strings.Split(stdOut, ":") + parsedOutput := strings.Split(stdOut, " ") if len(parsedOutput) < 2 { logging.Debugf("failed to parse version information for %s: %s", executablePath, stdOut) return "", fmt.Errorf("Unable to parse the version information of %s", executablePath) @@ -144,7 +144,45 @@ func (c *Cache) cacheExecutable() error { if err != nil { return err } + if c.GetExecutableName() == constants.KrunkitCommand { + err = signKrunkit(finalExecutablePath) + if err != nil { + return err + } + } + } + return nil +} + +func signKrunkit(executablePath string) error { + const krunkitEntitlements = ` + + + + com.apple.security.cs.disable-library-validation + + com.apple.security.hypervisor + + + +` + tmpFile, err := os.CreateTemp("", "krunkit-entitlements-*.plist") + if err != nil { + return fmt.Errorf("failed to create temp entitlements file: %w", err) + } + defer os.Remove(tmpFile.Name()) + + if _, err := tmpFile.WriteString(krunkitEntitlements); err != nil { + tmpFile.Close() + return fmt.Errorf("failed to write entitlements: %w", err) + } + tmpFile.Close() + + _, _, err = crcos.RunWithDefaultLocale("codesign", "-s", "-", "--entitlements", tmpFile.Name(), "--force", executablePath) + if err != nil { + return err } + logging.Debugf("Signed %s", executablePath) return nil } @@ -183,7 +221,7 @@ func (c *Cache) CheckVersion() error { } func isTarball(filename string) bool { - tarballExtensions := []string{".tar", ".tar.gz", ".tar.xz", ".zip", ".tar.bz2", ".crcbundle"} + tarballExtensions := []string{".tar", ".tar.gz", ".tar.xz", ".zip", ".tar.bz2", ".crcbundle", ".tgz"} for _, extension := range tarballExtensions { if strings.HasSuffix(strings.ToLower(filename), extension) { return true diff --git a/pkg/crc/cache/cache_darwin.go b/pkg/crc/cache/cache_darwin.go index 2cf57439b8..03c63a7bab 100644 --- a/pkg/crc/cache/cache_darwin.go +++ b/pkg/crc/cache/cache_darwin.go @@ -7,11 +7,11 @@ import ( ) func NewVfkitCache() *Cache { - return newCache(vfkit.ExecutablePath(), vfkit.VfkitDownloadURL, vfkit.VfkitVersion, getVfkitVersion) + return newCache(vfkit.ExecutablePath(), vfkit.DownloadURL(), vfkit.Version(), getVfkitVersion) } func getVfkitVersion(executablePath string) (string, error) { - version, err := getVersionGeneric(executablePath, "-v") + version, err := getVersionGeneric(executablePath, "--version") if err != nil { return version, err } diff --git a/pkg/crc/constants/constants.go b/pkg/crc/constants/constants.go index b2cc95feca..ede46003b5 100644 --- a/pkg/crc/constants/constants.go +++ b/pkg/crc/constants/constants.go @@ -143,7 +143,7 @@ func GetDefaultBundleSignedHashURL(preset crcpreset.Preset) string { } func ResolveHelperPath(executableName string) string { - if version.IsInstaller() { + if version.IsInstaller() && executableName != KrunkitCommand { return filepath.Join(version.InstallPath(), executableName) } return filepath.Join(CrcBinDir, executableName) diff --git a/pkg/crc/constants/constants_darwin.go b/pkg/crc/constants/constants_darwin.go index 96a2c00503..50a4c5f0cf 100644 --- a/pkg/crc/constants/constants_darwin.go +++ b/pkg/crc/constants/constants_darwin.go @@ -1,6 +1,10 @@ +//go:build darwin + package constants import ( + "log" + "os" "path/filepath" ) @@ -9,8 +13,27 @@ const ( PodmanRemoteExecutableName = "podman" DaemonAgentLabel = "com.redhat.crc.daemon" QemuGuestAgentPort = 1234 + + VfkitCommand = "vfkit" + KrunkitCommand = "krunkit" ) +func Provider() string { + provider := os.Getenv("CRC_PROVIDER") + if provider == "" { + provider = VfkitCommand + } + switch provider { + case VfkitCommand: + return VfkitCommand + case KrunkitCommand: + return KrunkitCommand + default: + log.Fatalf("Invalid provider: %s. Choose between %s or %s", provider, VfkitCommand, KrunkitCommand) + return "" + } +} + var ( TapSocketPath = filepath.Join(CrcBaseDir, "tap.sock") DaemonHTTPSocketPath = filepath.Join(CrcBaseDir, "crc-http.sock") diff --git a/pkg/crc/constants/constants_linux.go b/pkg/crc/constants/constants_linux.go index 4797b15ae7..4e65f52967 100644 --- a/pkg/crc/constants/constants_linux.go +++ b/pkg/crc/constants/constants_linux.go @@ -8,6 +8,11 @@ const ( OcExecutableName = "oc" PodmanRemoteExecutableName = "podman-remote" TapSocketPath = "" + KrunkitCommand = "" ) var DaemonHTTPSocketPath = filepath.Join(CrcBaseDir, "crc-http.sock") + +func Provider() string { + return "" +} diff --git a/pkg/crc/constants/constants_windows.go b/pkg/crc/constants/constants_windows.go index 23aa84707e..0caedbfd81 100644 --- a/pkg/crc/constants/constants_windows.go +++ b/pkg/crc/constants/constants_windows.go @@ -7,4 +7,9 @@ const ( DaemonHTTPNamedPipe = `\\.\pipe\crc-http` DaemonTaskName = "crcDaemon" AdminHelperServiceName = "crcAdminHelper" + KrunkitCommand = "" ) + +func Provider() string { + return "" +} diff --git a/pkg/crc/machine/vfkit/constants.go b/pkg/crc/machine/vfkit/constants.go index d6d8e9e1bf..dc047cbd4b 100644 --- a/pkg/crc/machine/vfkit/constants.go +++ b/pkg/crc/machine/vfkit/constants.go @@ -4,20 +4,50 @@ package vfkit import ( "fmt" + "path/filepath" "github.com/crc-org/crc/v2/pkg/crc/constants" ) const ( - VfkitVersion = "0.6.1" - vfkitCommand = "vfkit" + VfkitVersion = "0.6.1" + VfkitCommand = "vfkit" + KrunkitVersion = "1.1.1" + KrunkitCommand = "krunkit" ) var ( - VfkitDownloadURL = fmt.Sprintf("https://github.com/crc-org/vfkit/releases/download/v%s/%s", VfkitVersion, vfkitCommand) + VfkitDownloadURL = fmt.Sprintf("https://github.com/crc-org/vfkit/releases/download/v%s/%s", VfkitVersion, VfkitCommand) VfkitEntitlementsURL = fmt.Sprintf("https://raw.githubusercontent.com/crc-org/vfkit/v%s/vf.entitlements", VfkitVersion) + KrunkitDownloadURL = fmt.Sprintf("https://github.com/containers/krunkit/releases/download/v%s/krunkit-podman-unsigned-%s.tgz", KrunkitVersion, KrunkitVersion) ) func ExecutablePath() string { - return constants.ResolveHelperPath(vfkitCommand) + provider := constants.Provider() + if provider == KrunkitCommand { + return filepath.Join(constants.CrcBinDir, provider) + } + return constants.ResolveHelperPath(provider) +} + +func DownloadURL() string { + switch constants.Provider() { + case VfkitCommand: + return VfkitDownloadURL + case KrunkitCommand: + return KrunkitDownloadURL + default: + return "" + } +} + +func Version() string { + switch constants.Provider() { + case VfkitCommand: + return VfkitVersion + case KrunkitCommand: + return KrunkitVersion + default: + return "" + } } diff --git a/pkg/crc/machine/vfkit/driver_darwin.go b/pkg/crc/machine/vfkit/driver_darwin.go index 882f8ccaf1..8cbd1d4fa3 100644 --- a/pkg/crc/machine/vfkit/driver_darwin.go +++ b/pkg/crc/machine/vfkit/driver_darwin.go @@ -11,12 +11,10 @@ import ( ) func CreateHost(machineConfig config.MachineConfig) *vfkit.Driver { - vfDriver := vfkit.NewDriver(machineConfig.Name, constants.MachineBaseDir) + vfDriver := vfkit.NewDriver(machineConfig.Name, constants.MachineBaseDir, VfkitCommand) config.InitVMDriverFromMachineConfig(machineConfig, vfDriver.VMDriver) - vfDriver.VfkitPath = ExecutablePath() - vfDriver.VirtioNet = machineConfig.NetworkMode == network.SystemNetworkingMode vfDriver.VsockPath = constants.TapSocketPath diff --git a/pkg/crc/preflight/preflight_checks_darwin.go b/pkg/crc/preflight/preflight_checks_darwin.go index e0fd3b5b6f..300d7a05cc 100644 --- a/pkg/crc/preflight/preflight_checks_darwin.go +++ b/pkg/crc/preflight/preflight_checks_darwin.go @@ -162,7 +162,10 @@ func killVfkitProcess() error { func getDaemonConfig() (*launchd.AgentConfig, error) { logFilePath := filepath.Join(constants.CrcBaseDir, ".launchd-crcd.log") - env := map[string]string{"Version": version.GetCRCVersion()} + env := map[string]string{ + "Version": version.GetCRCVersion(), + "CRC_PROVIDER": constants.Provider(), + } daemonConfig := launchd.AgentConfig{ Label: constants.DaemonAgentLabel, ExecutablePath: constants.CrcSymlinkPath, diff --git a/pkg/crc/preflight/preflight_darwin.go b/pkg/crc/preflight/preflight_darwin.go index 0deca36e7b..a611d051d5 100644 --- a/pkg/crc/preflight/preflight_darwin.go +++ b/pkg/crc/preflight/preflight_darwin.go @@ -33,15 +33,15 @@ var vfkitPreflightChecks = []Check{ }, { configKeySuffix: "check-vfkit-installed", - checkDescription: "Checking if vfkit is installed", + checkDescription: "Checking if " + constants.Provider() + " is installed", check: checkVfkitInstalled, - fixDescription: "Setting up virtualization with vfkit", + fixDescription: "Setting up virtualization with " + constants.Provider(), fix: fixVfkitInstallation, labels: labels{Os: Darwin}, }, { - cleanupDescription: "Stopping CRC vfkit process", + cleanupDescription: "Stopping CRC " + constants.Provider() + " process", cleanup: killVfkitProcess, flags: CleanUpOnly, diff --git a/pkg/drivers/vfkit/driver_darwin.go b/pkg/drivers/vfkit/driver_darwin.go index 2b6d555e01..91f50b2817 100644 --- a/pkg/drivers/vfkit/driver_darwin.go +++ b/pkg/drivers/vfkit/driver_darwin.go @@ -52,7 +52,7 @@ type Driver struct { UnixgramSockPath string } -func NewDriver(hostName, storePath string) *Driver { +func NewDriver(hostName, storePath, executableName string) *Driver { // checks that vfdriver.Driver implements the libmachine.Driver interface var _ drivers.Driver = &Driver{} return &Driver{ @@ -69,6 +69,7 @@ func NewDriver(hostName, storePath string) *Driver { DaemonVsockPort: constants.DaemonVsockPort, UnixgramSockPath: constants.UnixgramSocketPath, UnixgramMacAddress: constants.VsockMacAddress, + VfkitPath: constants.ResolveHelperPath(executableName), } } @@ -272,20 +273,6 @@ func (d *Driver) Start() error { } } - // when loading a VM created by a crc version predating this commit, - // d.QemuGAVsockPort will be missing from ~/.crc/machines/crc/config.json - // In such a case, assume the VM will not support time sync - if d.QemuGAVsockPort != 0 { - timesync, err := config.TimeSyncNew(d.QemuGAVsockPort) - if err != nil { - return err - } - err = vm.AddDevice(timesync) - if err != nil { - return err - } - } - args, err := vm.ToCmdLine() if err != nil { return err @@ -447,7 +434,7 @@ func (d *Driver) findVfkitProcess() (*process.Process, error) { if err != nil { return nil, err } - if !strings.HasPrefix(name, "vfkit") { + if !strings.HasPrefix(name, constants.Provider()) { // return InvalidExecutable error? log.Debugf("pid %d is stale, and is being used by %s", pid, name) return nil, nil diff --git a/pkg/libmachine/load_darwin.go b/pkg/libmachine/load_darwin.go index 231a626143..b06a3e8ecc 100644 --- a/pkg/libmachine/load_darwin.go +++ b/pkg/libmachine/load_darwin.go @@ -3,12 +3,13 @@ package libmachine import ( "encoding/json" - "github.com/crc-org/crc/v2/pkg/drivers/vfkit" + "github.com/crc-org/crc/v2/pkg/crc/constants" + vfkitDriver "github.com/crc-org/crc/v2/pkg/drivers/vfkit" "github.com/crc-org/crc/v2/pkg/libmachine/host" ) func (api *Client) NewHost(_ string, driverPath string, rawDriver []byte) (*host.Host, error) { - driver := vfkit.NewDriver("", "") + driver := vfkitDriver.NewDriver("", "", constants.Provider()) if err := json.Unmarshal(rawDriver, &driver); err != nil { return nil, err } @@ -29,10 +30,11 @@ func (api *Client) Load(name string) (*host.Host, error) { return nil, err } - driver := vfkit.NewDriver("", "") + driver := vfkitDriver.NewDriver("", "", constants.Provider()) if err := json.Unmarshal(h.RawDriver, &driver); err != nil { return nil, err } + driver.VfkitPath = constants.ResolveHelperPath(constants.Provider()) h.Driver = driver return h, nil }