Skip to content

Commit

Permalink
feat: Full Qemu PCI support (#376)
Browse files Browse the repository at this point in the history
* feat: Full Qemu PCI support

* fix: prefix added to empty string
  • Loading branch information
Tinyblargon authored Nov 21, 2024
1 parent fd54e35 commit 222002b
Show file tree
Hide file tree
Showing 7 changed files with 1,631 additions and 63 deletions.
67 changes: 15 additions & 52 deletions proxmox/config_qemu.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package proxmox

import (
"bytes"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -55,7 +54,7 @@ type ConfigQemu struct {
QemuIso string `json:"qemuiso,omitempty"` // DEPRECATED use Iso *IsoFile instead
QemuKVM *bool `json:"kvm,omitempty"`
QemuOs string `json:"ostype,omitempty"`
QemuPCIDevices QemuDevices `json:"hostpci,omitempty"` // TODO should be a struct
PciDevices QemuPciDevices `json:"pci_devices,omitempty"`
QemuPxe bool `json:"pxe,omitempty"`
QemuUnusedDisks QemuDevices `json:"unused,omitempty"` // TODO should be a struct
USBs QemuUSBs `json:"usbs,omitempty"`
Expand Down Expand Up @@ -118,9 +117,6 @@ func (config *ConfigQemu) defaults() {
if config.QemuOs == "" {
config.QemuOs = "other"
}
if config.QemuPCIDevices == nil {
config.QemuPCIDevices = QemuDevices{}
}
if config.QemuUnusedDisks == nil {
config.QemuUnusedDisks = QemuDevices{}
}
Expand Down Expand Up @@ -267,7 +263,9 @@ func (config ConfigQemu) mapToAPI(currentConfig ConfigQemu, version Version) (re
itemsToDelete += config.USBs.mapToAPI(currentConfig.USBs, params)
}

config.CreateQemuPCIsParams(params)
if config.PciDevices != nil {
itemsToDelete += config.PciDevices.mapToAPI(currentConfig.PciDevices, params)
}

if itemsToDelete != "" {
params["delete"] = strings.TrimPrefix(itemsToDelete, ",")
Expand Down Expand Up @@ -425,37 +423,11 @@ func (ConfigQemu) mapToStruct(vmr *VmRef, params map[string]interface{}) (*Confi
}

config.Networks = QemuNetworkInterfaces{}.mapToSDK(params)
config.PciDevices = QemuPciDevices{}.mapToSDK(params)
config.Serials = SerialInterfaces{}.mapToSDK(params)

config.USBs = QemuUSBs{}.mapToSDK(params)

// hostpci
hostPCInames := []string{}

for k := range params {
if hostPCIname := rxPCIName.FindStringSubmatch(k); len(hostPCIname) > 0 {
hostPCInames = append(hostPCInames, hostPCIname[0])
}
}

if len(hostPCInames) > 0 {
config.QemuPCIDevices = QemuDevices{}
for _, hostPCIname := range hostPCInames {
hostPCIConfStr := params[hostPCIname]
hostPCIConfList := strings.Split(hostPCIConfStr.(string), ",")
id := rxPCIName.FindStringSubmatch(hostPCIname)
hostPCIID, _ := strconv.Atoi(id[0])
hostPCIConfMap := QemuDevice{
"id": hostPCIID,
}
hostPCIConfMap.readDeviceConfig(hostPCIConfList)
// And device config to usbs map.
if len(hostPCIConfMap) > 0 {
config.QemuPCIDevices[hostPCIID] = hostPCIConfMap
}
}
}

// efidisk
if efidisk, isSet := params["efidisk0"].(string); isSet {
efiDiskConfMap := ParsePMConf(efidisk, "volume")
Expand Down Expand Up @@ -672,6 +644,11 @@ func (config ConfigQemu) Validate(current *ConfigQemu, version Version) (err err
return
}
}
if config.PciDevices != nil {
if err = config.PciDevices.Validate(nil); err != nil {
return
}
}
if config.TPM != nil {
if err = config.TPM.Validate(nil); err != nil {
return
Expand All @@ -698,6 +675,11 @@ func (config ConfigQemu) Validate(current *ConfigQemu, version Version) (err err
return
}
}
if config.PciDevices != nil {
if err = config.PciDevices.Validate(current.PciDevices); err != nil {
return
}
}
if config.TPM != nil {
if err = config.TPM.Validate(current.TPM); err != nil {
return
Expand Down Expand Up @@ -799,7 +781,6 @@ var (
rxUnusedDiskName = regexp.MustCompile(`^(unused)\d+`)
rxNicName = regexp.MustCompile(`net\d+`)
rxMpName = regexp.MustCompile(`mp\d+`)
rxPCIName = regexp.MustCompile(`hostpci\d+`)
)

func NewConfigQemuFromApi(vmr *VmRef, client *Client) (config *ConfigQemu, err error) {
Expand Down Expand Up @@ -1087,24 +1068,6 @@ func (c ConfigQemu) CreateQemuEfiParams(params map[string]interface{}) {
}
}

// Create parameters for each PCI Device
func (c ConfigQemu) CreateQemuPCIsParams(params map[string]interface{}) {
// For new style with multi pci device.
for pciConfID, pciConfMap := range c.QemuPCIDevices {
qemuPCIName := "hostpci" + strconv.Itoa(pciConfID)
var pcistring bytes.Buffer
for elem := range pciConfMap {
pcistring.WriteString(elem)
pcistring.WriteString("=")
pcistring.WriteString(fmt.Sprintf("%v", pciConfMap[elem]))
pcistring.WriteString(",")
}

// Add back to Qemu prams.
params[qemuPCIName] = strings.TrimSuffix(pcistring.String(), ",")
}
}

func (p QemuDeviceParam) createDeviceParam(
deviceConfMap QemuDevice,
ignoredKeys []string,
Expand Down
Loading

0 comments on commit 222002b

Please sign in to comment.