diff --git a/app/model.go b/app/model.go index 873437d..1ca4640 100644 --- a/app/model.go +++ b/app/model.go @@ -87,6 +87,10 @@ func (host *Host) RebuildVM(vmid uint) error { instance.RebuildNet(netid) } + for deviceid := range instance.configHostPCIs { + instance.RebuildDevice(*host, deviceid) + } + return nil } @@ -139,6 +143,45 @@ func (instance *Instance) RebuildNet(netid string) error { return nil } +func (instance *Instance) RebuildDevice(host Host, deviceid string) error { + instanceDevice, ok := instance.configHostPCIs[deviceid] + if !ok { // if device does not exist + return fmt.Errorf("%s not found in devices", deviceid) + } + + hostDeviceBusID := strings.Split(instanceDevice, ",")[0] + + instanceDeviceBusID, err := strconv.ParseUint(strings.TrimPrefix(deviceid, "hostpci"), 10, 64) + if err != nil { + return err + } + + if DeviceBusIDIsSuperDevice(hostDeviceBusID) { + hostSuperDevice := host.Hardware[hostDeviceBusID] + subDevices := []*HostDevice{} + for _, v := range hostSuperDevice.Devices { + subDevices = append(subDevices, v) + } + instance.Device[uint(instanceDeviceBusID)] = &InstanceDevice{ + Device: subDevices, + PCIE: strings.Contains(instanceDevice, "pcie=1"), + } + } else { + _, hostSubdeviceBusID, err := SplitDeviceBusID(hostDeviceBusID) + if err != nil { + return err + } + instance.Device[uint(instanceDeviceBusID)] = &InstanceDevice{ + Device: []*HostDevice{ + host.Hardware[hostDeviceBusID].Devices[hostSubdeviceBusID], + }, + PCIE: strings.Contains(instanceDevice, "pcie=1"), + } + } + + return nil +} + func (cluster Cluster) String() string { r := "" for _, host := range cluster.Hosts { @@ -192,6 +235,9 @@ func (i Instance) String() string { for k, v := range i.Net { r += fmt.Sprintf("\t\t\tnet%d: %s\n", k, v) } + for k, v := range i.Device { + r += fmt.Sprintf("\t\t\thostpci%d: %s\n", k, v) + } return r } else { r := fmt.Sprintf("CT, Name: %s, Cores: %d, Memory: %d, Swap: %d\n", i.Name, i.Cores, i.Memory, i.Swap) @@ -212,3 +258,11 @@ func (v Volume) String() string { func (n Net) String() string { return fmt.Sprintf("rate: %d, vlan: %d", n.Rate, n.VLAN) } + +func (d InstanceDevice) String() string { + r := "" + for _, v := range d.Device { + r += fmt.Sprintf("%s:%s ", v.SubVendorName, v.SubDeviceName) + } + return r +} diff --git a/app/proxmox.go b/app/proxmox.go index fdc45c7..603c06d 100644 --- a/app/proxmox.go +++ b/app/proxmox.go @@ -138,7 +138,7 @@ func (host Host) VirtualMachine(VMID uint) (Instance, error) { } config := vm.VirtualMachineConfig - config.HostPCIs = config.MergeHostPCIs() + instance.configHostPCIs = config.MergeHostPCIs() instance.configNets = config.MergeNets() instance.configDisks = MergeVMDisksAndUnused(config) @@ -186,6 +186,7 @@ func (host Host) Container(VMID uint) (Instance, error) { } config := ct.ContainerConfig + instance.configHostPCIs = make(map[string]string) instance.configNets = config.MergeNets() instance.configDisks = MergeCTDisksAndUnused(config) diff --git a/app/types.go b/app/types.go index acab2fc..00dbc18 100644 --- a/app/types.go +++ b/app/types.go @@ -2,7 +2,7 @@ package app import "github.com/luthermonson/go-proxmox" -type Resource struct { // number of virtual cores (usually threads) +type Resource struct { Reserved uint64 Free uint64 Total uint64 @@ -26,18 +26,19 @@ const ( ) type Instance struct { - Type InstanceType - Name string - Proctype string - Cores uint64 - Memory uint64 - Swap uint64 - Volume map[string]*Volume - Net map[uint]*Net - Device map[uint]*InstanceDevice - config interface{} - configDisks map[string]string - configNets map[string]string + Type InstanceType + Name string + Proctype string + Cores uint64 + Memory uint64 + Swap uint64 + Volume map[string]*Volume + Net map[uint]*Net + Device map[uint]*InstanceDevice + config interface{} + configDisks map[string]string + configNets map[string]string + configHostPCIs map[string]string proxmox.ContainerInterface } diff --git a/app/utils.go b/app/utils.go index 980e56b..e03cae6 100644 --- a/app/utils.go +++ b/app/utils.go @@ -35,21 +35,6 @@ func GetConfig(configPath string) Config { return config } -// finds the first substring r in s such that s = ... a r b ... -func FindSubstringBetween(s string, a string, b string) (string, error) { - x := strings.Split(s, a) - if len(x) <= 2 { - return "", fmt.Errorf("%s not found in %s", a, s) - } - - y := strings.Split(x[1], b) - if len(y) <= 2 { - return "", fmt.Errorf("%s not found in %s", b, s) - } - - return y[0], nil -} - // returns if a device pcie bus id is a super device or subsystem device // // subsystem devices always has the format xxxx:yy.z, whereas super devices have the format xxxx:yy