Skip to content

Commit

Permalink
vf: Add toVz() methods for all virtio devices
Browse files Browse the repository at this point in the history
This follows the same model as for virtio-fs or virtio-blk devices so that
it's possible to add multiple devices of the same type to the VM.
The only exception is virtio-vsock which is documented by Apple as only
being allowed once.
  • Loading branch information
cfergeau committed Jul 4, 2023
1 parent c9a4b08 commit a5db53d
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 58 deletions.
113 changes: 59 additions & 54 deletions pkg/vf/virtio.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (dev *VirtioBlk) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfig
return err
}
log.Infof("Adding virtio-blk device (imagePath: %s)", dev.ImagePath)
vmConfig.storageDeviceConfiguration = append(vmConfig.storageDeviceConfiguration, storageDeviceConfig)
vmConfig.storageDevicesConfiguration = append(vmConfig.storageDevicesConfiguration, storageDeviceConfig)

return nil
}
Expand Down Expand Up @@ -80,17 +80,13 @@ func (dev *VirtioInput) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConf
return err
}

log.Infof("Adding virtio-input device")

switch conf := inputDeviceConfig.(type) {
case *vz.USBScreenCoordinatePointingDeviceConfiguration:
vmConfig.SetPointingDevicesVirtualMachineConfiguration([]vz.PointingDeviceConfiguration{
conf,
})
case *vz.USBKeyboardConfiguration:
vmConfig.SetKeyboardsVirtualMachineConfiguration([]vz.KeyboardConfiguration{
conf,
})
case vz.PointingDeviceConfiguration:
log.Info("Adding virtio-input pointing device")
vmConfig.pointingDevicesConfiguration = append(vmConfig.pointingDevicesConfiguration, conf)
case vz.KeyboardConfiguration:
log.Info("Adding virtio-input keyboard device")
vmConfig.keyboardConfiguration = append(vmConfig.keyboardConfiguration, conf)
}

return nil
Expand Down Expand Up @@ -120,9 +116,7 @@ func (dev *VirtioGPU) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfig

log.Infof("Adding virtio-gpu device")

vmConfig.SetGraphicsDevicesVirtualMachineConfiguration([]vz.GraphicsDeviceConfiguration{
gpuDeviceConfig,
})
vmConfig.graphicsDevicesConfiguration = append(vmConfig.graphicsDevicesConfiguration, gpuDeviceConfig)

return nil
}
Expand Down Expand Up @@ -161,7 +155,7 @@ func (dev *VirtioFs) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfigu
return err
}
log.Infof("Adding virtio-fs device")
vmConfig.directorySharingDeviceConfiguration = append(vmConfig.directorySharingDeviceConfiguration, fileSystemDeviceConfig)
vmConfig.directorySharingDevicesConfiguration = append(vmConfig.directorySharingDevicesConfiguration, fileSystemDeviceConfig)
return nil
}

Expand All @@ -180,30 +174,19 @@ func (dev *VirtioNet) connectUnixPath() error {
return nil
}

func (dev *VirtioNet) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error {
func (dev *VirtioNet) toVz() (*vz.VirtioNetworkDeviceConfiguration, error) {
var (
mac *vz.MACAddress
err 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())
}
if dev.UnixSocketPath != "" {
log.Infof("Using unix socket %s", dev.UnixSocketPath)
if err := dev.connectUnixPath(); err != nil {
return err
}
}

if len(dev.MacAddress) == 0 {
mac, err = vz.NewRandomLocallyAdministeredMACAddress()
} else {
mac, err = vz.NewMACAddress(dev.MacAddress)
}
if err != nil {
return err
return nil, err
}
var attachment vz.NetworkDeviceAttachment
if dev.Socket != nil {
Expand All @@ -212,29 +195,49 @@ func (dev *VirtioNet) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfig
attachment, err = vz.NewNATNetworkDeviceAttachment()
}
if err != nil {
return err
return nil, err
}
networkConfig, err := vz.NewVirtioNetworkDeviceConfiguration(attachment)
if err != nil {
return err
return nil, err
}
networkConfig.SetMACAddress(mac)
vmConfig.SetNetworkDevicesVirtualMachineConfiguration([]*vz.VirtioNetworkDeviceConfiguration{
networkConfig,
})

return networkConfig, nil
}

func (dev *VirtioNet) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) 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())
}
if dev.UnixSocketPath != "" {
log.Infof("Using unix socket %s", dev.UnixSocketPath)
if err := dev.connectUnixPath(); err != nil {
return err
}
}
netConfig, err := dev.toVz()
if err != nil {
return err
}

vmConfig.networkDevicesConfiguration = append(vmConfig.networkDevicesConfiguration, netConfig)

return nil
}

func (dev *VirtioRng) toVz() (*vz.VirtioEntropyDeviceConfiguration, error) {
return vz.NewVirtioEntropyDeviceConfiguration()
}

func (dev *VirtioRng) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error {
log.Infof("Adding virtio-rng device")
entropyConfig, err := vz.NewVirtioEntropyDeviceConfiguration()
entropyConfig, err := dev.toVz()
if err != nil {
return err
}
vmConfig.SetEntropyDevicesVirtualMachineConfiguration([]*vz.VirtioEntropyDeviceConfiguration{
entropyConfig,
})
vmConfig.entropyDevicesConfiguration = append(vmConfig.entropyDevicesConfiguration, entropyConfig)

return nil
}
Expand All @@ -259,41 +262,43 @@ func setRawMode(f *os.File) error {
return unix.IoctlSetTermios(int(f.Fd()), unix.TIOCSETA, attr)
}

func (dev *VirtioSerial) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error {
if dev.LogFile != "" {
log.Infof("Adding virtio-serial device (logFile: %s)", dev.LogFile)
}
if dev.UsesStdio {
log.Infof("Adding stdio console")
}

func (dev *VirtioSerial) toVz() (*vz.VirtioConsoleDeviceSerialPortConfiguration, error) {
var serialPortAttachment vz.SerialPortAttachment
var err error
if dev.UsesStdio {
if err := setRawMode(os.Stdin); err != nil {
return err
return nil, err
}
serialPortAttachment, err = vz.NewFileHandleSerialPortAttachment(os.Stdin, os.Stdout)
} else {
serialPortAttachment, err = vz.NewFileSerialPortAttachment(dev.LogFile, false)
}
if err != nil {
return err
return nil, err
}

return vz.NewVirtioConsoleDeviceSerialPortConfiguration(serialPortAttachment)

}
func (dev *VirtioSerial) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error {
if dev.LogFile != "" {
log.Infof("Adding virtio-serial device (logFile: %s)", dev.LogFile)
}
if dev.UsesStdio {
log.Infof("Adding stdio console")
}

consoleConfig, err := vz.NewVirtioConsoleDeviceSerialPortConfiguration(serialPortAttachment)
consoleConfig, err := dev.toVz()
if err != nil {
return err
}
vmConfig.SetSerialPortsVirtualMachineConfiguration([]*vz.VirtioConsoleDeviceSerialPortConfiguration{
consoleConfig,
})
vmConfig.serialPortsConfiguration = append(vmConfig.serialPortsConfiguration, consoleConfig)

return nil
}

func (dev *VirtioVsock) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConfiguration) error {
if len(vmConfig.SocketDevices()) != 0 {
if len(vmConfig.socketDevicesConfiguration) != 0 {
log.Debugf("virtio-vsock device already present, not adding a second one")
return nil
}
Expand All @@ -302,7 +307,7 @@ func (dev *VirtioVsock) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineConf
if err != nil {
return err
}
vmConfig.SetSocketDevicesVirtualMachineConfiguration([]vz.SocketDeviceConfiguration{vzdev})
vmConfig.socketDevicesConfiguration = append(vmConfig.socketDevicesConfiguration, vzdev)

return nil
}
Expand Down Expand Up @@ -354,7 +359,7 @@ func (dev *USBMassStorage) AddToVirtualMachineConfig(vmConfig *vzVirtualMachineC
return err
}
log.Infof("Adding USB mass storage device (imagePath: %s)", dev.ImagePath)
vmConfig.storageDeviceConfiguration = append(vmConfig.storageDeviceConfiguration, storageDeviceConfig)
vmConfig.storageDevicesConfiguration = append(vmConfig.storageDevicesConfiguration, storageDeviceConfig)

return nil
}
Expand Down
24 changes: 20 additions & 4 deletions pkg/vf/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ import (

type vzVirtualMachineConfiguration struct {
*vz.VirtualMachineConfiguration
storageDeviceConfiguration []vz.StorageDeviceConfiguration
directorySharingDeviceConfiguration []vz.DirectorySharingDeviceConfiguration
storageDevicesConfiguration []vz.StorageDeviceConfiguration
directorySharingDevicesConfiguration []vz.DirectorySharingDeviceConfiguration
keyboardConfiguration []vz.KeyboardConfiguration
pointingDevicesConfiguration []vz.PointingDeviceConfiguration
graphicsDevicesConfiguration []vz.GraphicsDeviceConfiguration
networkDevicesConfiguration []*vz.VirtioNetworkDeviceConfiguration
entropyDevicesConfiguration []*vz.VirtioEntropyDeviceConfiguration
serialPortsConfiguration []*vz.VirtioConsoleDeviceSerialPortConfiguration
socketDevicesConfiguration []vz.SocketDeviceConfiguration
}

func newVzVirtualMachineConfiguration(vm *config.VirtualMachine) (*vzVirtualMachineConfiguration, error) {
Expand Down Expand Up @@ -40,8 +47,17 @@ func ToVzVirtualMachineConfig(vm *config.VirtualMachine) (*vz.VirtualMachineConf
return nil, err
}
}
vzVMConfig.SetStorageDevicesVirtualMachineConfiguration(vzVMConfig.storageDeviceConfiguration)
vzVMConfig.SetDirectorySharingDevicesVirtualMachineConfiguration(vzVMConfig.directorySharingDeviceConfiguration)
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
// https://developer.apple.com/documentation/virtualization/vzvirtiosocketdeviceconfiguration?language=objc
vzVMConfig.SetSocketDevicesVirtualMachineConfiguration(vzVMConfig.socketDevicesConfiguration)

if vm.Timesync != nil && vm.Timesync.VsockPort != 0 {
// automatically add the vsock device we'll need for communication over VsockPort
Expand Down

0 comments on commit a5db53d

Please sign in to comment.