add volume_id and net_id vaues for volumes and nets,
add boot order for instances
This commit is contained in:
73
app/model.go
73
app/model.go
@@ -3,7 +3,6 @@ package app
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -179,6 +178,10 @@ func (host *Node) RebuildInstance(instancetype InstanceType, vmid uint) error {
|
|||||||
instance.RebuildDevice(host, deviceid)
|
instance.RebuildDevice(host, deviceid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if instance.Type == VM {
|
||||||
|
instance.RebuildBoot()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +195,7 @@ func (instance *Instance) RebuildVolume(host *Node, volid string) error {
|
|||||||
|
|
||||||
voltype := AnyPrefixes(volid, VolumeTypes)
|
voltype := AnyPrefixes(volid, VolumeTypes)
|
||||||
volume.Type = voltype
|
volume.Type = voltype
|
||||||
|
volume.Volume_ID = VolumeID(volid)
|
||||||
instance.Volumes[VolumeID(volid)] = volume
|
instance.Volumes[VolumeID(volid)] = volume
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -200,17 +203,14 @@ func (instance *Instance) RebuildVolume(host *Node, volid string) error {
|
|||||||
|
|
||||||
func (instance *Instance) RebuildNet(netid string) error {
|
func (instance *Instance) RebuildNet(netid string) error {
|
||||||
net := instance.configNets[netid]
|
net := instance.configNets[netid]
|
||||||
idnum, err := strconv.ParseUint(strings.TrimPrefix(netid, "net"), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
netinfo, err := GetNetInfo(net)
|
netinfo, err := GetNetInfo(net)
|
||||||
|
netinfo.Net_ID = NetID(netid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.Nets[NetID(idnum)] = netinfo
|
instance.Nets[NetID(netid)] = netinfo
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -222,23 +222,64 @@ func (instance *Instance) RebuildDevice(host *Node, deviceid string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hostDeviceBusID := DeviceID(strings.Split(instanceDevice, ",")[0])
|
hostDeviceBusID := DeviceID(strings.Split(instanceDevice, ",")[0])
|
||||||
|
instanceDeviceBusID := DeviceID(deviceid)
|
||||||
idbid, err := strconv.ParseUint(strings.TrimPrefix(deviceid, "hostpci"), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
instanceDeviceBusID := InstanceDeviceID(idbid)
|
|
||||||
|
|
||||||
if DeviceBusIDIsSuperDevice(hostDeviceBusID) {
|
if DeviceBusIDIsSuperDevice(hostDeviceBusID) {
|
||||||
instance.Devices[InstanceDeviceID(instanceDeviceBusID)] = host.Devices[DeviceID(hostDeviceBusID)]
|
instance.Devices[DeviceID(instanceDeviceBusID)] = host.Devices[DeviceBus(hostDeviceBusID)]
|
||||||
for _, function := range instance.Devices[InstanceDeviceID(instanceDeviceBusID)].Functions {
|
for _, function := range instance.Devices[DeviceID(instanceDeviceBusID)].Functions {
|
||||||
function.Reserved = true
|
function.Reserved = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// sub function assignment not supported yet
|
// sub function assignment not supported yet
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.Devices[InstanceDeviceID(instanceDeviceBusID)].Value = instanceDevice
|
instance.Devices[DeviceID(instanceDeviceBusID)].Device_ID = DeviceID(deviceid)
|
||||||
|
instance.Devices[DeviceID(instanceDeviceBusID)].Value = instanceDevice
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (instance *Instance) RebuildBoot() {
|
||||||
|
instance.Boot = BootOrder{}
|
||||||
|
|
||||||
|
eligibleBoot := map[string]bool{}
|
||||||
|
for k := range instance.Volumes {
|
||||||
|
eligiblePrefix := AnyPrefixes(string(k), []string{"sata", "scsi", "ide"})
|
||||||
|
if eligiblePrefix != "" {
|
||||||
|
eligibleBoot[string(k)] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k := range instance.Nets {
|
||||||
|
eligibleBoot[string(k)] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println(eligibleBoot)
|
||||||
|
|
||||||
|
x := strings.Split(instance.configBoot, "order=") // should be a;b;c;d ...
|
||||||
|
if len(x) == 2 {
|
||||||
|
y := strings.Split(x[1], ";")
|
||||||
|
for _, bootTarget := range y {
|
||||||
|
_, isEligible := eligibleBoot[bootTarget]
|
||||||
|
if val, ok := instance.Volumes[VolumeID(bootTarget)]; ok && isEligible { // if the item is eligible and is in volumes
|
||||||
|
instance.Boot.Enabled = append(instance.Boot.Enabled, val)
|
||||||
|
eligibleBoot[bootTarget] = false
|
||||||
|
} else if val, ok := instance.Nets[NetID(bootTarget)]; ok && isEligible { // if the item is eligible and is in nets
|
||||||
|
instance.Boot.Enabled = append(instance.Boot.Enabled, val)
|
||||||
|
eligibleBoot[bootTarget] = false
|
||||||
|
} else {
|
||||||
|
log.Printf("Encountered non-eligible boot target %s in instance %s\n", bootTarget, instance.Name)
|
||||||
|
eligibleBoot[bootTarget] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for bootTarget, isEligible := range eligibleBoot {
|
||||||
|
if val, ok := instance.Volumes[VolumeID(bootTarget)]; ok && isEligible { // if the item is eligible and is in volumes
|
||||||
|
instance.Boot.Disabled = append(instance.Boot.Disabled, val)
|
||||||
|
} else if val, ok := instance.Nets[NetID(bootTarget)]; ok && isEligible { // if the item is eligible and is in nets
|
||||||
|
instance.Boot.Disabled = append(instance.Boot.Disabled, val)
|
||||||
|
} else {
|
||||||
|
log.Printf("Encountered non-eligible boot target %s in instance %s\n", bootTarget, instance.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -15,6 +15,14 @@ type ProxmoxClient struct {
|
|||||||
client *proxmox.Client
|
client *proxmox.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PVEDevice struct { // used only for requests to PVE
|
||||||
|
ID string `json:"id"`
|
||||||
|
Device_Name string `json:"device_name"`
|
||||||
|
Vendor_Name string `json:"vendor_name"`
|
||||||
|
Subsystem_Device_Name string `json:"subsystem_device_name"`
|
||||||
|
Subsystem_Vendor_Name string `json:"subsystem_vendor_name"`
|
||||||
|
}
|
||||||
|
|
||||||
func NewClient(url string, token string, secret string) ProxmoxClient {
|
func NewClient(url string, token string, secret string) ProxmoxClient {
|
||||||
HTTPClient := http.Client{
|
HTTPClient := http.Client{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
@@ -59,7 +67,7 @@ func (pve ProxmoxClient) Nodes() ([]string, error) {
|
|||||||
// Gets a Node's resources but does not recursively expand instances
|
// Gets a Node's resources but does not recursively expand instances
|
||||||
func (pve ProxmoxClient) Node(nodeName string) (*Node, error) {
|
func (pve ProxmoxClient) Node(nodeName string) (*Node, error) {
|
||||||
host := Node{}
|
host := Node{}
|
||||||
host.Devices = make(map[DeviceID]*Device)
|
host.Devices = make(map[DeviceBus]*Device)
|
||||||
host.Instances = make(map[InstanceID]*Instance)
|
host.Instances = make(map[InstanceID]*Instance)
|
||||||
|
|
||||||
node, err := pve.client.Node(context.Background(), nodeName)
|
node, err := pve.client.Node(context.Background(), nodeName)
|
||||||
@@ -78,11 +86,11 @@ func (pve ProxmoxClient) Node(nodeName string) (*Node, error) {
|
|||||||
if len(x) != 2 { // this should always be true, but skip if not
|
if len(x) != 2 { // this should always be true, but skip if not
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
deviceid := DeviceID(x[0])
|
deviceid := DeviceBus(x[0])
|
||||||
functionid := FunctionID(x[1])
|
functionid := FunctionID(x[1])
|
||||||
if _, ok := host.Devices[deviceid]; !ok {
|
if _, ok := host.Devices[deviceid]; !ok {
|
||||||
host.Devices[deviceid] = &Device{
|
host.Devices[deviceid] = &Device{
|
||||||
Device_ID: deviceid,
|
Device_Bus: deviceid,
|
||||||
Device_Name: device.Device_Name,
|
Device_Name: device.Device_Name,
|
||||||
Vendor_Name: device.Vendor_Name,
|
Vendor_Name: device.Vendor_Name,
|
||||||
Functions: make(map[FunctionID]*Function),
|
Functions: make(map[FunctionID]*Function),
|
||||||
@@ -130,6 +138,7 @@ func (host *Node) VirtualMachine(VMID uint) (*Instance, error) {
|
|||||||
instance.configHostPCIs = config.MergeHostPCIs()
|
instance.configHostPCIs = config.MergeHostPCIs()
|
||||||
instance.configNets = config.MergeNets()
|
instance.configNets = config.MergeNets()
|
||||||
instance.configDisks = MergeVMDisksAndUnused(config)
|
instance.configDisks = MergeVMDisksAndUnused(config)
|
||||||
|
instance.configBoot = config.Boot
|
||||||
|
|
||||||
instance.pveconfig = config
|
instance.pveconfig = config
|
||||||
instance.Type = VM
|
instance.Type = VM
|
||||||
@@ -140,7 +149,7 @@ func (host *Node) VirtualMachine(VMID uint) (*Instance, error) {
|
|||||||
instance.Memory = uint64(vm.VirtualMachineConfig.Memory) * MiB
|
instance.Memory = uint64(vm.VirtualMachineConfig.Memory) * MiB
|
||||||
instance.Volumes = make(map[VolumeID]*Volume)
|
instance.Volumes = make(map[VolumeID]*Volume)
|
||||||
instance.Nets = make(map[NetID]*Net)
|
instance.Nets = make(map[NetID]*Net)
|
||||||
instance.Devices = make(map[InstanceDeviceID]*Device)
|
instance.Devices = make(map[DeviceID]*Device)
|
||||||
|
|
||||||
return &instance, nil
|
return &instance, nil
|
||||||
}
|
}
|
||||||
|
58
app/types.go
58
app/types.go
@@ -18,7 +18,7 @@ type Node struct {
|
|||||||
Cores uint64 `json:"cores"`
|
Cores uint64 `json:"cores"`
|
||||||
Memory uint64 `json:"memory"`
|
Memory uint64 `json:"memory"`
|
||||||
Swap uint64 `json:"swap"`
|
Swap uint64 `json:"swap"`
|
||||||
Devices map[DeviceID]*Device `json:"devices"`
|
Devices map[DeviceBus]*Device `json:"devices"`
|
||||||
Instances map[InstanceID]*Instance `json:"instances"`
|
Instances map[InstanceID]*Instance `json:"instances"`
|
||||||
pvenode *proxmox.Node
|
pvenode *proxmox.Node
|
||||||
}
|
}
|
||||||
@@ -33,19 +33,21 @@ const (
|
|||||||
|
|
||||||
type Instance struct {
|
type Instance struct {
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
Type InstanceType `json:"type"`
|
Type InstanceType `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Proctype string `json:"cpu"`
|
Proctype string `json:"cpu"`
|
||||||
Cores uint64 `json:"cores"`
|
Cores uint64 `json:"cores"`
|
||||||
Memory uint64 `json:"memory"`
|
Memory uint64 `json:"memory"`
|
||||||
Swap uint64 `json:"swap"`
|
Swap uint64 `json:"swap"`
|
||||||
Volumes map[VolumeID]*Volume `json:"volumes"`
|
Volumes map[VolumeID]*Volume `json:"volumes"`
|
||||||
Nets map[NetID]*Net `json:"nets"`
|
Nets map[NetID]*Net `json:"nets"`
|
||||||
Devices map[InstanceDeviceID]*Device `json:"devices"`
|
Devices map[DeviceID]*Device `json:"devices"`
|
||||||
|
Boot BootOrder `json:"boot"`
|
||||||
pveconfig any
|
pveconfig any
|
||||||
configDisks map[string]string
|
configDisks map[string]string
|
||||||
configNets map[string]string
|
configNets map[string]string
|
||||||
configHostPCIs map[string]string
|
configHostPCIs map[string]string
|
||||||
|
configBoot string
|
||||||
}
|
}
|
||||||
|
|
||||||
var VolumeTypes = []string{
|
var VolumeTypes = []string{
|
||||||
@@ -59,32 +61,27 @@ var VolumeTypes = []string{
|
|||||||
|
|
||||||
type VolumeID string
|
type VolumeID string
|
||||||
type Volume struct {
|
type Volume struct {
|
||||||
Type string `json:"type"`
|
Volume_ID VolumeID `json:"volume_id"`
|
||||||
Storage string `json:"storage"`
|
Type string `json:"type"`
|
||||||
Format string `json:"format"`
|
Storage string `json:"storage"`
|
||||||
Size uint64 `json:"size"`
|
Format string `json:"format"`
|
||||||
File string `json:"file"`
|
Size uint64 `json:"size"`
|
||||||
|
File string `json:"file"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetID uint64
|
type NetID string
|
||||||
type Net struct {
|
type Net struct {
|
||||||
Value string `json:"value"`
|
Net_ID NetID `json:"net_id"`
|
||||||
Rate uint64 `json:"rate"`
|
Value string `json:"value"`
|
||||||
VLAN uint64 `json:"vlan"`
|
Rate uint64 `json:"rate"`
|
||||||
}
|
VLAN uint64 `json:"vlan"`
|
||||||
|
|
||||||
type PVEDevice struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Device_Name string `json:"device_name"`
|
|
||||||
Vendor_Name string `json:"vendor_name"`
|
|
||||||
Subsystem_Device_Name string `json:"subsystem_device_name"`
|
|
||||||
Subsystem_Vendor_Name string `json:"subsystem_vendor_name"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeviceID string
|
type DeviceID string
|
||||||
type InstanceDeviceID uint64
|
type DeviceBus string
|
||||||
type Device struct {
|
type Device struct {
|
||||||
Device_ID DeviceID `json:"device_id"`
|
Device_ID DeviceID `json:"device_id"`
|
||||||
|
Device_Bus DeviceBus `json:"device_bus"`
|
||||||
Device_Name string `json:"device_name"`
|
Device_Name string `json:"device_name"`
|
||||||
Vendor_Name string `json:"vendor_name"`
|
Vendor_Name string `json:"vendor_name"`
|
||||||
Functions map[FunctionID]*Function `json:"functions"`
|
Functions map[FunctionID]*Function `json:"functions"`
|
||||||
@@ -99,3 +96,8 @@ type Function struct {
|
|||||||
Vendor_Name string `json:"subsystem_vendor_name"`
|
Vendor_Name string `json:"subsystem_vendor_name"`
|
||||||
Reserved bool `json:"reserved"`
|
Reserved bool `json:"reserved"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BootOrder struct {
|
||||||
|
Enabled []any `json:"enabled"`
|
||||||
|
Disabled []any `json:"disabled"`
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user