Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add libhvee as alternative Hyper-V driver on Windows #3824

Merged
merged 3 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
github.com/cavaliergopher/grab/v3 v3.0.1
github.com/cheggaaa/pb/v3 v3.1.5
github.com/containers/common v0.59.1
github.com/containers/gvisor-tap-vsock v0.7.5
github.com/containers/image/v5 v5.32.2
github.com/containers/libhvee v0.7.1
github.com/coreos/go-systemd/v22 v22.5.0
github.com/crc-org/admin-helper v0.5.4
github.com/crc-org/machine v0.0.0-20240715101719-0c1bc9eb95f8
Expand Down Expand Up @@ -96,7 +98,7 @@ require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
github.com/go-openapi/errors v0.22.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
Expand Down
7 changes: 6 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,14 @@ github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vc
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containers/common v0.59.1 h1:7VkmJN3YvD0jLFwaUjLHSRJ98JLffydiyOJjYr0dUTo=
github.com/containers/common v0.59.1/go.mod h1:53VicJCZ2AD0O+Br7VVoyrS7viXF4YmwlTIocWUT8XE=
github.com/containers/gvisor-tap-vsock v0.7.5 h1:bTy4u3DOmmUPwurL6me2rsgfypAFDhyeJleUcQmBR/E=
github.com/containers/gvisor-tap-vsock v0.7.5/go.mod h1:GW9jOqAEEGdaS20XwTYdm6KCYDHIulOE/yEEOabkoE4=
github.com/containers/image/v5 v5.32.2 h1:SzNE2Y6sf9b1GJoC8qjCuMBXwQrACFp4p0RK15+4gmQ=
github.com/containers/image/v5 v5.32.2/go.mod h1:v1l73VeMugfj/QtKI+jhYbwnwFCFnNGckvbST3rQ5Hk=
github.com/containers/libhvee v0.7.1 h1:dWGF5GLq9DZvXo3P8aDp3cNieL5eCaSell4UmeA/jY4=
github.com/containers/libhvee v0.7.1/go.mod h1:fRKB3AyIqHMvq6xaeYhTpckM2cdoq0oecolyoiuLP7M=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM=
Expand Down Expand Up @@ -118,8 +122,9 @@ github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
Expand Down
18 changes: 9 additions & 9 deletions pkg/crc/machine/driver_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,36 @@ import (
"errors"

"github.com/crc-org/crc/v2/pkg/crc/machine/config"
"github.com/crc-org/crc/v2/pkg/crc/machine/hyperv"
machineHyperv "github.com/crc-org/crc/v2/pkg/drivers/hyperv"
"github.com/crc-org/crc/v2/pkg/crc/machine/libhvee"
machineLibhvee "github.com/crc-org/crc/v2/pkg/drivers/libhvee"
"github.com/crc-org/crc/v2/pkg/libmachine"
"github.com/crc-org/crc/v2/pkg/libmachine/host"
)

func newHost(api libmachine.API, machineConfig config.MachineConfig) (*host.Host, error) {
json, err := json.Marshal(hyperv.CreateHost(machineConfig))
json, err := json.Marshal(libhvee.CreateHost(machineConfig))
if err != nil {
return nil, errors.New("Failed to marshal driver options")
}
return api.NewHost("hyperv", "", json)
}

func loadDriverConfig(host *host.Host) (*machineHyperv.Driver, error) {
var hypervDriver machineHyperv.Driver
err := json.Unmarshal(host.RawDriver, &hypervDriver)
func loadDriverConfig(host *host.Host) (*machineLibhvee.Driver, error) {
var libhveeDriver machineLibhvee.Driver
err := json.Unmarshal(host.RawDriver, &libhveeDriver)

return &hypervDriver, err
return &libhveeDriver, err
}

func updateDriverConfig(host *host.Host, driver *machineHyperv.Driver) error {
func updateDriverConfig(host *host.Host, driver *machineLibhvee.Driver) error {
driverData, err := json.Marshal(driver)
if err != nil {
return err
}
return host.UpdateConfig(driverData)
}

func updateDriverStruct(host *host.Host, driver *machineHyperv.Driver) error {
func updateDriverStruct(host *host.Host, driver *machineLibhvee.Driver) error {
host.Driver = driver
return nil
}
6 changes: 0 additions & 6 deletions pkg/crc/machine/hyperv/constants_windows.go

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,34 +1,22 @@
package hyperv
package libhvee

import (
"path/filepath"
"strings"

"github.com/crc-org/crc/v2/pkg/crc/constants"
"github.com/crc-org/crc/v2/pkg/crc/machine/config"
"github.com/crc-org/crc/v2/pkg/crc/network"
"github.com/crc-org/crc/v2/pkg/drivers/hyperv"
winnet "github.com/crc-org/crc/v2/pkg/os/windows/network"
"github.com/crc-org/crc/v2/pkg/drivers/libhvee"
"github.com/crc-org/machine/libmachine/drivers"
)

func CreateHost(machineConfig config.MachineConfig) *hyperv.Driver {
hypervDriver := hyperv.NewDriver(machineConfig.Name, constants.MachineBaseDir)
func CreateHost(machineConfig config.MachineConfig) *libhvee.Driver {
libhveeDriver := libhvee.NewDriver(machineConfig.Name, constants.MachineBaseDir)

config.InitVMDriverFromMachineConfig(machineConfig, hypervDriver.VMDriver)
config.InitVMDriverFromMachineConfig(machineConfig, libhveeDriver.VMDriver)

hypervDriver.DisableDynamicMemory = true

if machineConfig.NetworkMode == network.UserNetworkingMode {
hypervDriver.VirtualSwitch = ""
} else {
// Determine the Virtual Switch to be used
_, switchName := winnet.SelectSwitchByNameOrDefault(AlternativeNetwork)
hypervDriver.VirtualSwitch = switchName
}

hypervDriver.SharedDirs = configureShareDirs(machineConfig)
return hypervDriver
libhveeDriver.SharedDirs = configureShareDirs(machineConfig)
return libhveeDriver
}

// converts a path like c:\users\crc to /mnt/c/users/crc
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package hyperv
package libhvee

import (
"testing"
Expand Down
26 changes: 0 additions & 26 deletions pkg/crc/preflight/preflight_checks_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ import (
"github.com/crc-org/crc/v2/pkg/crc/logging"

"github.com/crc-org/crc/v2/pkg/crc/adminhelper"
winnet "github.com/crc-org/crc/v2/pkg/os/windows/network"
"github.com/crc-org/crc/v2/pkg/os/windows/powershell"

"github.com/crc-org/crc/v2/pkg/crc/constants"
"github.com/crc-org/crc/v2/pkg/crc/machine/hyperv"
)

const (
Expand Down Expand Up @@ -166,19 +164,6 @@ func fixUserPartOfCrcUsersAndHypervAdminsGroup() error {
return errReboot
}

func checkIfHyperVVirtualSwitchExists() error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Fwiw, it would be good to split the system mode networking removal on Windows in its own preparatory commit, this would make it easier to focus on/review the config/preflight changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Honestly, I do not even know if this functionality still works. I'll consider, but these checks are also performed when not even necessary (like the existence of the virtual switch) and therefore actually wrong.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've done this in https://github.com/cfergeau/crc/tree/libhvee, this removes even more code

switchName := hyperv.AlternativeNetwork

// use winnet instead
exists, foundName := winnet.SelectSwitchByNameOrDefault(switchName)
if exists {
logging.Info("Found Virtual Switch to use: ", foundName)
return nil
}

return fmt.Errorf("Virtual Switch not found")
}

func checkIfRunningAsNormalUser() error {
if !powershell.IsAdmin() {
return nil
Expand All @@ -187,17 +172,6 @@ func checkIfRunningAsNormalUser() error {
return fmt.Errorf("crc should be run in a shell without administrator rights")
}

func removeDNSServerAddress() error {
resetDNSCommand := `Set-DnsClientServerAddress -InterfaceAlias ("vEthernet (crc)") -ResetServerAddresses`
if exist, defaultSwitch := winnet.GetDefaultSwitchName(); exist {
resetDNSCommand = fmt.Sprintf(`Set-DnsClientServerAddress -InterfaceAlias ("vEthernet (%s)","vEthernet (crc)") -ResetServerAddresses`, defaultSwitch)
}
if _, _, err := powershell.ExecuteAsAdmin("Remove dns entry for default switch", resetDNSCommand); err != nil {
return err
}
return nil
}

func removeCrcVM() (err error) {
if _, _, err := powershell.Execute("Get-VM -Name crc"); err != nil {
// This means that there is no crc VM exist
Expand Down
15 changes: 0 additions & 15 deletions pkg/crc/preflight/preflight_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,6 @@ var hypervPreflightChecks = []Check{

labels: labels{Os: Windows},
},
{
configKeySuffix: "check-hyperv-switch",
checkDescription: "Checking if the Hyper-V virtual switch exists",
check: checkIfHyperVVirtualSwitchExists,
flags: StartUpOnly,

labels: labels{Os: Windows, NetworkMode: System},
},
{
cleanupDescription: "Removing dns server from interface",
cleanup: removeDNSServerAddress,
flags: CleanUpOnly,

labels: labels{Os: Windows, NetworkMode: System},
},
}

var cleanupCheckRemoveCrcVM = Check{
Expand Down
4 changes: 2 additions & 2 deletions pkg/crc/preflight/preflight_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ func TestCountConfigurationOptions(t *testing.T) {
}

func TestCountPreflights(t *testing.T) {
assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 24)
assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 24)
assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 22)
assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 22)

assert.Len(t, getPreflightChecks(false, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 23)
assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 23)
Expand Down
42 changes: 3 additions & 39 deletions pkg/crc/services/dns/dns_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,14 @@ package dns

import (
"fmt"
"time"

"github.com/crc-org/crc/v2/pkg/crc/network"
"github.com/crc-org/crc/v2/pkg/crc/services"
winnet "github.com/crc-org/crc/v2/pkg/os/windows/network"
"github.com/crc-org/crc/v2/pkg/os/windows/powershell"
"github.com/crc-org/crc/v2/pkg/os/windows/win32"
crcstrings "github.com/crc-org/crc/v2/pkg/strings"
)

const (
// Alternative
AlternativeNetwork = "crc"
)

func runPostStartForOS(serviceConfig services.ServicePostStartConfig) error {
if serviceConfig.NetworkMode == network.UserNetworkingMode {
return addOpenShiftHosts(serviceConfig)
}

_, switchName := winnet.SelectSwitchByNameOrDefault(AlternativeNetwork)
networkInterface := fmt.Sprintf("vEthernet (%s)", switchName)

setInterfaceNameserverValue(networkInterface, serviceConfig.IP)

time.Sleep(2 * time.Second)

if !crcstrings.Contains(getInterfaceNameserverValues(networkInterface), serviceConfig.IP) {
return fmt.Errorf("Nameserver %s not successfully set on interface %s. Perhaps you can try this new network mode: https://github.com/crc-org/crc/wiki/VPN-support--with-an--userland-network-stack", serviceConfig.IP, networkInterface)
if serviceConfig.NetworkMode != network.UserNetworkingMode {
return fmt.Errorf("only user-mode networking is supported on Windows")
}
return nil
}

func getInterfaceNameserverValues(iface string) []string {
getDNSServerCommand := fmt.Sprintf(`(Get-DnsClientServerAddress "%s")[0].ServerAddresses`, iface)
stdOut, _, _ := powershell.Execute(getDNSServerCommand)

return crcstrings.SplitLines(stdOut)
}

func setInterfaceNameserverValue(iface string, address string) {
exe := "netsh"
args := fmt.Sprintf(`interface ip set dns "%s" static %s primary`, iface, address)

// ignore the error as this is useless (prefer not to use nolint here)
_ = win32.ShellExecuteAsAdmin(fmt.Sprintf("add dns server address to interface %s", iface), win32.HwndDesktop, exe, args, "", 0)
return addOpenShiftHosts(serviceConfig)
}
Loading