From 4bbcd98876faf5e227d04d236f594a43b111db67 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Tue, 5 Mar 2024 15:13:15 +0100 Subject: [PATCH 1/5] vf: Make ToVzBootloader private It's only used in the vf package, so it can be renamed to toVzBootloader Signed-off-by: Christophe Fergeau --- pkg/vf/bootloader.go | 2 +- pkg/vf/vm.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/vf/bootloader.go b/pkg/vf/bootloader.go index 3125ae4f..7065cef0 100644 --- a/pkg/vf/bootloader.go +++ b/pkg/vf/bootloader.go @@ -81,7 +81,7 @@ func toVzEFIBootloader(bootloader *config.EFIBootloader) (vz.BootLoader, error) ) } -func ToVzBootloader(bootloader config.Bootloader) (vz.BootLoader, error) { +func toVzBootloader(bootloader config.Bootloader) (vz.BootLoader, error) { switch b := bootloader.(type) { case *config.LinuxBootloader: return toVzLinuxBootloader(b) diff --git a/pkg/vf/vm.go b/pkg/vf/vm.go index cde5cf98..e021c356 100644 --- a/pkg/vf/vm.go +++ b/pkg/vf/vm.go @@ -21,7 +21,7 @@ type vzVirtualMachineConfiguration struct { } func newVzVirtualMachineConfiguration(vm *config.VirtualMachine) (*vzVirtualMachineConfiguration, error) { - vzBootloader, err := ToVzBootloader(vm.Bootloader) + vzBootloader, err := toVzBootloader(vm.Bootloader) if err != nil { return nil, err } From 5f99aa8cd4ac1f2ebcd783882d31724389ac1766 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Tue, 20 Feb 2024 12:47:23 +0100 Subject: [PATCH 2/5] vf: Rename inconsistent VirtioGPU.toVZ() All other methods are named toVz() with a lower-case 'z' Signed-off-by: Christophe Fergeau --- pkg/vf/virtio.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/vf/virtio.go b/pkg/vf/virtio.go index 547ee8a5..d7b7b2be 100644 --- a/pkg/vf/virtio.go +++ b/pkg/vf/virtio.go @@ -117,7 +117,7 @@ func (dev *VirtioInput) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConf return nil } -func (dev *VirtioGPU) toVZ() (vz.GraphicsDeviceConfiguration, error) { +func (dev *VirtioGPU) toVz() (vz.GraphicsDeviceConfiguration, error) { gpuDeviceConfig, err := vz.NewVirtioGraphicsDeviceConfiguration() if err != nil { return nil, fmt.Errorf("failed to initialize virtio graphic device: %w", err) @@ -134,7 +134,7 @@ func (dev *VirtioGPU) toVZ() (vz.GraphicsDeviceConfiguration, error) { } func (dev *VirtioGPU) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { - gpuDeviceConfig, err := dev.toVZ() + gpuDeviceConfig, err := dev.toVz() if err != nil { return err } From 9276842122a14a70ba0d415e9f5f84a7bf9974a9 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Tue, 5 Mar 2024 17:34:29 +0100 Subject: [PATCH 3/5] rest: Refactor/simplify vf code The rest/vf package introduces a `VzVirtualMachine` type to wrap virtual machine interactions. This type is a struct with a `VzVM *vz.VirtualMachine` member. This commit makes this struct member anonymous instead of naming it `VzVM`, this allows to remove the VzVirtualMachine state related methods which were thin wrappers over methods with (almost) the same name already defined in `*vz.VirtualMachine`. Signed-off-by: Christophe Fergeau --- pkg/rest/vf/state_change.go | 55 ++++--------------------------------- pkg/rest/vf/vm_config.go | 10 +++---- 2 files changed, 11 insertions(+), 54 deletions(-) diff --git a/pkg/rest/vf/state_change.go b/pkg/rest/vf/state_change.go index df600c59..56fe904f 100644 --- a/pkg/rest/vf/state_change.go +++ b/pkg/rest/vf/state_change.go @@ -3,7 +3,6 @@ package rest import ( "fmt" - "github.com/Code-Hex/vz/v3" "github.com/crc-org/vfkit/pkg/rest/define" "github.com/sirupsen/logrus" ) @@ -15,61 +14,19 @@ func (vm *VzVirtualMachine) ChangeState(newState define.StateChange) error { ) switch newState { case define.Pause: + logrus.Debug("pausing virtual machine") response = vm.Pause() case define.Resume: + logrus.Debug("resuming machine") response = vm.Resume() case define.Stop: - response = vm.Stop() + logrus.Debug("stopping machine") + _, response = vm.RequestStop() case define.HardStop: - response = vm.HardStop() + logrus.Debug("force stopping machine") + response = vm.Stop() default: - logrus.Error(response) return fmt.Errorf("invalid new VMState: %s", newState) } return response } - -// GetState returns state of the VM -func (vm *VzVirtualMachine) GetState() vz.VirtualMachineState { - return vm.VzVM.State() -} - -func (vm *VzVirtualMachine) Pause() error { - logrus.Debug("pausing virtual machine") - return vm.VzVM.Pause() -} - -func (vm *VzVirtualMachine) Resume() error { - logrus.Debug("resuming machine") - return vm.VzVM.Resume() -} - -func (vm *VzVirtualMachine) Stop() error { - logrus.Debug("stopping machine") - _, err := vm.VzVM.RequestStop() - return err -} -func (vm *VzVirtualMachine) HardStop() error { - logrus.Debug("force stopping machine") - return vm.VzVM.Stop() -} - -func (vm *VzVirtualMachine) CanStart() bool { - return vm.VzVM.CanStart() -} - -func (vm *VzVirtualMachine) CanPause() bool { - return vm.VzVM.CanPause() -} - -func (vm *VzVirtualMachine) CanResume() bool { - return vm.VzVM.CanResume() -} - -func (vm *VzVirtualMachine) CanStop() bool { - return vm.VzVM.CanRequestStop() -} - -func (vm *VzVirtualMachine) CanHardStop() bool { - return vm.VzVM.CanStop() -} diff --git a/pkg/rest/vf/vm_config.go b/pkg/rest/vf/vm_config.go index a4aff1dd..d85c4f9c 100644 --- a/pkg/rest/vf/vm_config.go +++ b/pkg/rest/vf/vm_config.go @@ -11,13 +11,13 @@ import ( ) type VzVirtualMachine struct { - VzVM *vz.VirtualMachine + *vz.VirtualMachine config *vz.VirtualMachineConfiguration vmConfig *config.VirtualMachine } func NewVzVirtualMachine(vm *vz.VirtualMachine, config *vz.VirtualMachineConfiguration, vmConfig *config.VirtualMachine) *VzVirtualMachine { - return &VzVirtualMachine{config: config, VzVM: vm, vmConfig: vmConfig} + return &VzVirtualMachine{config: config, VirtualMachine: vm, vmConfig: vmConfig} } // Inspect returns information about the virtual machine like hw resources @@ -28,14 +28,14 @@ func (vm *VzVirtualMachine) Inspect(c *gin.Context) { // GetVMState retrieves the current vm state func (vm *VzVirtualMachine) GetVMState(c *gin.Context) { - current := vm.GetState() + current := vm.State() c.JSON(http.StatusOK, gin.H{ "state": current.String(), "canStart": vm.CanStart(), "canPause": vm.CanPause(), "canResume": vm.CanResume(), - "canStop": vm.CanStop(), - "canHardStop": vm.CanHardStop(), + "canStop": vm.CanRequestStop(), + "canHardStop": vm.CanStop(), }) } From 999a1e3fbac0d8f1ea70fb78f372d30f91f48278 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Wed, 21 Feb 2024 14:19:11 +0100 Subject: [PATCH 4/5] vf: Add VirtualMachineConfig type This commit renames vzVirtualMachineConfiguration to VirtualMachineConfig. vzVirtualMachineConfiguration was a wrapper over the Code-Hex/vz type vz.VirtualMachineConfiguration. VirtualMachineConfig improves vzVirtualMachineConfiguration because it also keeps around the config.VirtualMachine go object which was used to created the vz.VirtualMachineConfiguration object. This will be useful in simplifying the code using the pkg/vf package. Signed-off-by: Christophe Fergeau --- cmd/vfkit/main.go | 14 ++++++++--- pkg/vf/rosetta_amd64.go | 2 +- pkg/vf/rosetta_arm64.go | 2 +- pkg/vf/virtio.go | 22 ++++++++--------- pkg/vf/virtionet.go | 2 +- pkg/vf/vm.go | 55 +++++++++++++++++++---------------------- 6 files changed, 50 insertions(+), 47 deletions(-) diff --git a/cmd/vfkit/main.go b/cmd/vfkit/main.go index 9e7b515c..9208cd10 100644 --- a/cmd/vfkit/main.go +++ b/cmd/vfkit/main.go @@ -113,16 +113,22 @@ func waitForVMState(vm *vz.VirtualMachine, state vz.VirtualMachineState, timeout func runVFKit(vmConfig *config.VirtualMachine, opts *cmdline.Options) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - vzVMConfig, err := vf.ToVzVirtualMachineConfig(vmConfig) - if err != nil { - return err - } gpuDevs := vmConfig.VirtioGPUDevices() if opts.UseGUI && len(gpuDevs) > 0 { gpuDevs[0].UsesGUI = true } + vfVMConfig, err := vf.NewVirtualMachineConfiguration(vmConfig) + if err != nil { + return err + } + + vzVMConfig, err := vfVMConfig.ToVz() + if err != nil { + return err + } + vm, err := vz.NewVirtualMachine(vzVMConfig) if err != nil { return err diff --git a/pkg/vf/rosetta_amd64.go b/pkg/vf/rosetta_amd64.go index ddd3bc01..b4dbb96e 100644 --- a/pkg/vf/rosetta_amd64.go +++ b/pkg/vf/rosetta_amd64.go @@ -4,6 +4,6 @@ import ( "fmt" ) -func (dev *RosettaShare) AddToVirtualMachineConfig(_ *vzVirtualMachineConfiguration) error { +func (dev *RosettaShare) AddToVirtualMachineConfig(_ *VirtualMachineConfiguration) error { return fmt.Errorf("rosetta is unsupported on non-arm64 platforms") } diff --git a/pkg/vf/rosetta_arm64.go b/pkg/vf/rosetta_arm64.go index 9eb4ef5d..a21c6868 100644 --- a/pkg/vf/rosetta_arm64.go +++ b/pkg/vf/rosetta_arm64.go @@ -50,7 +50,7 @@ func (dev *RosettaShare) toVz() (vz.DirectorySharingDeviceConfiguration, error) return config, nil } -func (dev *RosettaShare) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *RosettaShare) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { fileSystemDeviceConfig, err := dev.toVz() if err != nil { return err diff --git a/pkg/vf/virtio.go b/pkg/vf/virtio.go index d7b7b2be..38cec7a9 100644 --- a/pkg/vf/virtio.go +++ b/pkg/vf/virtio.go @@ -37,7 +37,7 @@ func (dev *NVMExpressController) toVz() (vz.StorageDeviceConfiguration, error) { return devConfig, nil } -func (dev *NVMExpressController) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *NVMExpressController) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { storageDeviceConfig, err := dev.toVz() if err != nil { return err @@ -69,7 +69,7 @@ func (dev *VirtioBlk) toVz() (vz.StorageDeviceConfiguration, error) { return devConfig, nil } -func (dev *VirtioBlk) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *VirtioBlk) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { storageDeviceConfig, err := dev.toVz() if err != nil { return err @@ -99,7 +99,7 @@ func (dev *VirtioInput) toVz() (interface{}, error) { return inputConfig, nil } -func (dev *VirtioInput) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *VirtioInput) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { inputDeviceConfig, err := dev.toVz() if err != nil { return err @@ -133,7 +133,7 @@ func (dev *VirtioGPU) toVz() (vz.GraphicsDeviceConfiguration, error) { return gpuDeviceConfig, nil } -func (dev *VirtioGPU) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *VirtioGPU) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { gpuDeviceConfig, err := dev.toVz() if err != nil { return err @@ -174,7 +174,7 @@ func (dev *VirtioFs) toVz() (vz.DirectorySharingDeviceConfiguration, error) { return fileSystemDeviceConfig, nil } -func (dev *VirtioFs) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *VirtioFs) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { fileSystemDeviceConfig, err := dev.toVz() if err != nil { return err @@ -188,7 +188,7 @@ func (dev *VirtioRng) toVz() (*vz.VirtioEntropyDeviceConfiguration, error) { return vz.NewVirtioEntropyDeviceConfiguration() } -func (dev *VirtioRng) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *VirtioRng) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { log.Infof("Adding virtio-rng device") entropyConfig, err := dev.toVz() if err != nil { @@ -235,9 +235,9 @@ func (dev *VirtioSerial) toVz() (*vz.VirtioConsoleDeviceSerialPortConfiguration, } return vz.NewVirtioConsoleDeviceSerialPortConfiguration(serialPortAttachment) - } -func (dev *VirtioSerial) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { + +func (dev *VirtioSerial) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { if dev.LogFile != "" { log.Infof("Adding virtio-serial device (logFile: %s)", dev.LogFile) } @@ -254,7 +254,7 @@ func (dev *VirtioSerial) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineCon return nil } -func (dev *VirtioVsock) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *VirtioVsock) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { if len(vmConfig.socketDevicesConfiguration) != 0 { log.Debugf("virtio-vsock device already present, not adding a second one") return nil @@ -269,7 +269,7 @@ func (dev *VirtioVsock) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConf return nil } -func AddToVirtualMachineConfig(dev config.VirtioDevice, vmConfig *vzVirtualMachineConfiguration) error { +func AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration, dev config.VirtioDevice) error { switch d := dev.(type) { case *config.USBMassStorage: return (*USBMassStorage)(d).AddToVirtualMachineConfig(vmConfig) @@ -317,7 +317,7 @@ func (dev *USBMassStorage) toVz() (vz.StorageDeviceConfiguration, error) { return vz.NewUSBMassStorageDeviceConfiguration(attachment) } -func (dev *USBMassStorage) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *USBMassStorage) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { storageDeviceConfig, err := dev.toVz() if err != nil { return err diff --git a/pkg/vf/virtionet.go b/pkg/vf/virtionet.go index 947011ab..72fd73c2 100644 --- a/pkg/vf/virtionet.go +++ b/pkg/vf/virtionet.go @@ -125,7 +125,7 @@ func (dev *VirtioNet) toVz() (*vz.VirtioNetworkDeviceConfiguration, error) { return networkConfig, nil } -func (dev *VirtioNet) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error { +func (dev *VirtioNet) AddToVirtualMachineConfig(vmConfig *VirtualMachineConfiguration) error { log.Infof("Adding virtio-net device (nat: %t macAddress: [%s])", dev.Nat, dev.MacAddress) if dev.Socket != nil { log.Infof("Using fd %d", dev.Socket.Fd()) diff --git a/pkg/vf/vm.go b/pkg/vf/vm.go index e021c356..5eecb993 100644 --- a/pkg/vf/vm.go +++ b/pkg/vf/vm.go @@ -7,8 +7,9 @@ import ( "github.com/crc-org/vfkit/pkg/config" ) -type vzVirtualMachineConfiguration struct { - *vz.VirtualMachineConfiguration +type VirtualMachineConfiguration struct { + *vz.VirtualMachineConfiguration // wrapper for Objective-C type + config *config.VirtualMachine // go-friendly virtual machine configuration definition storageDevicesConfiguration []vz.StorageDeviceConfiguration directorySharingDevicesConfiguration []vz.DirectorySharingDeviceConfiguration keyboardConfiguration []vz.KeyboardConfiguration @@ -20,57 +21,53 @@ type vzVirtualMachineConfiguration struct { socketDevicesConfiguration []vz.SocketDeviceConfiguration } -func newVzVirtualMachineConfiguration(vm *config.VirtualMachine) (*vzVirtualMachineConfiguration, error) { - vzBootloader, err := toVzBootloader(vm.Bootloader) +func NewVirtualMachineConfiguration(vmConfig *config.VirtualMachine) (*VirtualMachineConfiguration, error) { + vzBootloader, err := toVzBootloader(vmConfig.Bootloader) if err != nil { return nil, err } - vzVMConfig, err := vz.NewVirtualMachineConfiguration(vzBootloader, vm.Vcpus, uint64(vm.Memory.ToBytes())) + vzVMConfig, err := vz.NewVirtualMachineConfiguration(vzBootloader, vmConfig.Vcpus, uint64(vmConfig.Memory.ToBytes())) if err != nil { return nil, err } - return &vzVirtualMachineConfiguration{ + return &VirtualMachineConfiguration{ VirtualMachineConfiguration: vzVMConfig, + config: vmConfig, }, nil } -func ToVzVirtualMachineConfig(vm *config.VirtualMachine) (*vz.VirtualMachineConfiguration, error) { - vzVMConfig, err := newVzVirtualMachineConfiguration(vm) - if err != nil { - return nil, err - } - - for _, dev := range vm.Devices { - if err := AddToVirtualMachineConfig(dev, vzVMConfig); err != nil { +func (cfg *VirtualMachineConfiguration) ToVz() (*vz.VirtualMachineConfiguration, error) { + for _, dev := range cfg.config.Devices { + if err := AddToVirtualMachineConfig(cfg, dev); err != nil { return nil, err } } - vzVMConfig.SetStorageDevicesVirtualMachineConfiguration(vzVMConfig.storageDevicesConfiguration) - vzVMConfig.SetDirectorySharingDevicesVirtualMachineConfiguration(vzVMConfig.directorySharingDevicesConfiguration) - vzVMConfig.SetPointingDevicesVirtualMachineConfiguration(vzVMConfig.pointingDevicesConfiguration) - vzVMConfig.SetKeyboardsVirtualMachineConfiguration(vzVMConfig.keyboardConfiguration) - vzVMConfig.SetGraphicsDevicesVirtualMachineConfiguration(vzVMConfig.graphicsDevicesConfiguration) - vzVMConfig.SetNetworkDevicesVirtualMachineConfiguration(vzVMConfig.networkDevicesConfiguration) - vzVMConfig.SetEntropyDevicesVirtualMachineConfiguration(vzVMConfig.entropyDevicesConfiguration) - vzVMConfig.SetSerialPortsVirtualMachineConfiguration(vzVMConfig.serialPortsConfiguration) - // len(vzVMConfig.socketDevicesConfiguration should be 0 or 1 + cfg.SetStorageDevicesVirtualMachineConfiguration(cfg.storageDevicesConfiguration) + cfg.SetDirectorySharingDevicesVirtualMachineConfiguration(cfg.directorySharingDevicesConfiguration) + cfg.SetPointingDevicesVirtualMachineConfiguration(cfg.pointingDevicesConfiguration) + cfg.SetKeyboardsVirtualMachineConfiguration(cfg.keyboardConfiguration) + cfg.SetGraphicsDevicesVirtualMachineConfiguration(cfg.graphicsDevicesConfiguration) + cfg.SetNetworkDevicesVirtualMachineConfiguration(cfg.networkDevicesConfiguration) + cfg.SetEntropyDevicesVirtualMachineConfiguration(cfg.entropyDevicesConfiguration) + cfg.SetSerialPortsVirtualMachineConfiguration(cfg.serialPortsConfiguration) + // len(cfg.socketDevicesConfiguration should be 0 or 1 // https://developer.apple.com/documentation/virtualization/vzvirtiosocketdeviceconfiguration?language=objc - vzVMConfig.SetSocketDevicesVirtualMachineConfiguration(vzVMConfig.socketDevicesConfiguration) + cfg.SetSocketDevicesVirtualMachineConfiguration(cfg.socketDevicesConfiguration) - if vm.Timesync != nil && vm.Timesync.VsockPort != 0 { + if cfg.config.Timesync != nil && cfg.config.Timesync.VsockPort != 0 { // automatically add the vsock device we'll need for communication over VsockPort vsockDev := VirtioVsock{ - Port: vm.Timesync.VsockPort, + Port: cfg.config.Timesync.VsockPort, Listen: false, } - if err := vsockDev.AddToVirtualMachineConfig(vzVMConfig); err != nil { + if err := vsockDev.AddToVirtualMachineConfig(cfg); err != nil { return nil, err } } - valid, err := vzVMConfig.Validate() + valid, err := cfg.Validate() if err != nil { return nil, err } @@ -78,5 +75,5 @@ func ToVzVirtualMachineConfig(vm *config.VirtualMachine) (*vz.VirtualMachineConf return nil, fmt.Errorf("Invalid virtual machine configuration") } - return vzVMConfig.VirtualMachineConfiguration, nil + return cfg.VirtualMachineConfiguration, nil } From c0e9175b85cebed8791f2d319188e157bd278f3d Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Wed, 21 Feb 2024 14:40:44 +0100 Subject: [PATCH 5/5] vf: Add vf.VirtualMachine type Similarly to the vf.VirtualMachineConfiguration type introduced in the previous commit, the vf.VirtualMachine type wraps both a vz.VirtualMachine instance, and the vfkit/go data which was used to generate it, which is the aforementioned VirtualMachineConfiguration type. This allows to simplify some users of pkg/vf, in particular the rest code. `code-hex/vz` is now only imported in pkg/vf Signed-off-by: Christophe Fergeau --- cmd/vfkit/main.go | 20 +++++------------- cmd/vfkit/timesync.go | 6 ++---- pkg/rest/vf/vm_config.go | 13 +++++------- pkg/vf/vm.go | 44 +++++++++++++++++++++++++++++++++++++++- pkg/vf/vsock.go | 10 ++++----- 5 files changed, 59 insertions(+), 34 deletions(-) diff --git a/cmd/vfkit/main.go b/cmd/vfkit/main.go index 9208cd10..645bba27 100644 --- a/cmd/vfkit/main.go +++ b/cmd/vfkit/main.go @@ -89,7 +89,7 @@ func newVMConfiguration(opts *cmdline.Options) (*config.VirtualMachine, error) { return vmConfig, nil } -func waitForVMState(vm *vz.VirtualMachine, state vz.VirtualMachineState, timeout <-chan time.Time) error { +func waitForVMState(vm *vf.VirtualMachine, state vz.VirtualMachineState, timeout <-chan time.Time) error { signalCh := make(chan os.Signal, 1) signal.Notify(signalCh, syscall.SIGPIPE) @@ -119,34 +119,24 @@ func runVFKit(vmConfig *config.VirtualMachine, opts *cmdline.Options) error { gpuDevs[0].UsesGUI = true } - vfVMConfig, err := vf.NewVirtualMachineConfiguration(vmConfig) - if err != nil { - return err - } - - vzVMConfig, err := vfVMConfig.ToVz() - if err != nil { - return err - } - - vm, err := vz.NewVirtualMachine(vzVMConfig) + vfVM, err := vf.NewVirtualMachine(*vmConfig) if err != nil { return err } // Do not enable the rests server if user sets scheme to None if opts.RestfulURI != cmdline.DefaultRestfulURI { - restVM := restvf.NewVzVirtualMachine(vm, vzVMConfig, vmConfig) + restVM := restvf.NewVzVirtualMachine(vfVM) srv, err := rest.NewServer(restVM, restVM, opts.RestfulURI) if err != nil { return err } srv.Start() } - return runVirtualMachine(vmConfig, vm) + return runVirtualMachine(vmConfig, vfVM) } -func runVirtualMachine(vmConfig *config.VirtualMachine, vm *vz.VirtualMachine) error { +func runVirtualMachine(vmConfig *config.VirtualMachine, vm *vf.VirtualMachine) error { if err := vm.Start(); err != nil { return err } diff --git a/cmd/vfkit/timesync.go b/cmd/vfkit/timesync.go index 4e70bd85..56184ba1 100644 --- a/cmd/vfkit/timesync.go +++ b/cmd/vfkit/timesync.go @@ -6,7 +6,6 @@ import ( "net" "time" - "github.com/Code-Hex/vz/v3" "github.com/crc-org/vfkit/pkg/config" "github.com/crc-org/vfkit/pkg/vf" sleepnotifier "github.com/prashantgupta24/mac-sleep-notifier/notifier" @@ -34,7 +33,7 @@ func syncGuestTime(conn net.Conn) error { return nil } -func watchWakeupNotifications(vm *vz.VirtualMachine, vsockPort uint) { +func watchWakeupNotifications(vm *vf.VirtualMachine, vsockPort uint) { var vsockConn net.Conn defer func() { if vsockConn != nil { @@ -60,10 +59,9 @@ func watchWakeupNotifications(vm *vz.VirtualMachine, vsockPort uint) { } } } - } -func setupGuestTimeSync(vm *vz.VirtualMachine, timesync *config.TimeSync) error { +func setupGuestTimeSync(vm *vf.VirtualMachine, timesync *config.TimeSync) error { if timesync == nil { return nil } diff --git a/pkg/rest/vf/vm_config.go b/pkg/rest/vf/vm_config.go index d85c4f9c..add379bd 100644 --- a/pkg/rest/vf/vm_config.go +++ b/pkg/rest/vf/vm_config.go @@ -3,27 +3,24 @@ package rest import ( "net/http" - "github.com/Code-Hex/vz/v3" - "github.com/crc-org/vfkit/pkg/config" "github.com/crc-org/vfkit/pkg/rest/define" + "github.com/crc-org/vfkit/pkg/vf" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" ) type VzVirtualMachine struct { - *vz.VirtualMachine - config *vz.VirtualMachineConfiguration - vmConfig *config.VirtualMachine + *vf.VirtualMachine } -func NewVzVirtualMachine(vm *vz.VirtualMachine, config *vz.VirtualMachineConfiguration, vmConfig *config.VirtualMachine) *VzVirtualMachine { - return &VzVirtualMachine{config: config, VirtualMachine: vm, vmConfig: vmConfig} +func NewVzVirtualMachine(vm *vf.VirtualMachine) *VzVirtualMachine { + return &VzVirtualMachine{vm} } // Inspect returns information about the virtual machine like hw resources // and devices func (vm *VzVirtualMachine) Inspect(c *gin.Context) { - c.JSON(http.StatusOK, vm.vmConfig) + c.JSON(http.StatusOK, vm.Config()) } // GetVMState retrieves the current vm state diff --git a/pkg/vf/vm.go b/pkg/vf/vm.go index 5eecb993..b751500e 100644 --- a/pkg/vf/vm.go +++ b/pkg/vf/vm.go @@ -7,6 +7,48 @@ import ( "github.com/crc-org/vfkit/pkg/config" ) +type VirtualMachine struct { + *vz.VirtualMachine + vfConfig *VirtualMachineConfiguration +} + +func NewVirtualMachine(vmConfig config.VirtualMachine) (*VirtualMachine, error) { + vfConfig, err := NewVirtualMachineConfiguration(&vmConfig) + if err != nil { + return nil, err + } + return &VirtualMachine{ + vfConfig: vfConfig, + }, nil +} + +func (vm *VirtualMachine) Start() error { + if vm.VirtualMachine == nil { + if err := vm.toVz(); err != nil { + return err + } + } + return vm.VirtualMachine.Start() +} + +func (vm *VirtualMachine) toVz() error { + vzVMConfig, err := vm.vfConfig.toVz() + if err != nil { + return err + } + vzVM, err := vz.NewVirtualMachine(vzVMConfig) + if err != nil { + return err + } + vm.VirtualMachine = vzVM + + return nil +} + +func (vm *VirtualMachine) Config() *config.VirtualMachine { + return vm.vfConfig.config +} + type VirtualMachineConfiguration struct { *vz.VirtualMachineConfiguration // wrapper for Objective-C type config *config.VirtualMachine // go-friendly virtual machine configuration definition @@ -38,7 +80,7 @@ func NewVirtualMachineConfiguration(vmConfig *config.VirtualMachine) (*VirtualMa }, nil } -func (cfg *VirtualMachineConfiguration) ToVz() (*vz.VirtualMachineConfiguration, error) { +func (cfg *VirtualMachineConfiguration) toVz() (*vz.VirtualMachineConfiguration, error) { for _, dev := range cfg.config.Devices { if err := AddToVirtualMachineConfig(cfg, dev); err != nil { return nil, err diff --git a/pkg/vf/vsock.go b/pkg/vf/vsock.go index 4e0d0fb4..26f9963f 100644 --- a/pkg/vf/vsock.go +++ b/pkg/vf/vsock.go @@ -8,18 +8,17 @@ import ( "net/url" "strconv" - "github.com/Code-Hex/vz/v3" "inet.af/tcpproxy" ) -func ExposeVsock(vm *vz.VirtualMachine, port uint, vsockPath string, listen bool) (io.Closer, error) { +func ExposeVsock(vm *VirtualMachine, port uint, vsockPath string, listen bool) (io.Closer, error) { if listen { return listenVsock(vm, port, vsockPath) } return connectVsock(vm, port, vsockPath) } -func ConnectVsockSync(vm *vz.VirtualMachine, port uint) (net.Conn, error) { +func ConnectVsockSync(vm *VirtualMachine, port uint) (net.Conn, error) { socketDevices := vm.SocketDevices() if len(socketDevices) != 1 { return nil, fmt.Errorf("VM has too many/not enough virtio-vsock devices (%d)", len(socketDevices)) @@ -37,8 +36,7 @@ func ConnectVsockSync(vm *vz.VirtualMachine, port uint) (net.Conn, error) { // connectVsock proxies connections from a host unix socket to a vsock port // This allows the host to initiate connections to the guest over vsock -func connectVsock(vm *vz.VirtualMachine, port uint, vsockPath string) (io.Closer, error) { - +func connectVsock(vm *VirtualMachine, port uint, vsockPath string) (io.Closer, error) { var proxy tcpproxy.Proxy // listen for connections on the host unix socket proxy.ListenFunc = func(_, laddr string) (net.Listener, error) { @@ -76,7 +74,7 @@ func connectVsock(vm *vz.VirtualMachine, port uint, vsockPath string) (io.Closer // listenVsock proxies connections from a vsock port to a host unix socket. // This allows the guest to initiate connections to the host over vsock -func listenVsock(vm *vz.VirtualMachine, port uint, vsockPath string) (io.Closer, error) { +func listenVsock(vm *VirtualMachine, port uint, vsockPath string) (io.Closer, error) { var proxy tcpproxy.Proxy // listen for connections on the vsock port proxy.ListenFunc = func(_, laddr string) (net.Listener, error) {