adding more libvirtxml migrations
This commit is contained in:
parent
de93204e3d
commit
3862e3d4e9
4
go.mod
4
go.mod
@ -5,8 +5,9 @@ go 1.22.1
|
||||
require (
|
||||
github.com/a-h/templ v0.2.598
|
||||
github.com/go-chi/chi/v5 v5.0.12
|
||||
github.com/jaypipes/pcidb v1.0.0
|
||||
github.com/wcharczuk/go-chart/v2 v2.1.1
|
||||
gopkg.in/ffmt.v1 v1.5.6
|
||||
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81
|
||||
libvirt.org/go/libvirt v1.10001.0
|
||||
libvirt.org/go/libvirtxml v1.10001.0
|
||||
)
|
||||
@ -14,7 +15,6 @@ require (
|
||||
require (
|
||||
github.com/blend/go-sdk v1.20220411.3 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/jaypipes/pcidb v1.0.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.0.0 // indirect
|
||||
golang.org/x/image v0.11.0 // indirect
|
||||
)
|
||||
|
4
go.sum
4
go.sum
@ -17,6 +17,8 @@ github.com/wcharczuk/go-chart/v2 v2.1.1/go.mod h1:CyCAUt2oqvfhCl6Q5ZvAZwItgpQKZO
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc=
|
||||
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
|
||||
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@ -47,8 +49,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/ffmt.v1 v1.5.6 h1:4Bu3riZp5sAIXW2T/18JM9BkwJLodurXFR0f7PXp+cw=
|
||||
gopkg.in/ffmt.v1 v1.5.6/go.mod h1:LssvGOZFiBGoBcobkTqnyh+uN1VzIRoibW+c0JI/Ha4=
|
||||
libvirt.org/go/libvirt v1.10001.0 h1:lEVDNE7xfzmZXiDEGIS8NvJSuaz11OjRXw+ufbQEtPY=
|
||||
libvirt.org/go/libvirt v1.10001.0/go.mod h1:1WiFE8EjZfq+FCVog+rvr1yatKbKZ9FaFMZgEqxEJqQ=
|
||||
libvirt.org/go/libvirtxml v1.10001.0 h1:r9WBs24r3mxIG3/hAMRRwDMy4ZaPHmhHjw72o/ceXic=
|
||||
|
282
lib/host/lib.go
282
lib/host/lib.go
@ -11,9 +11,6 @@ import (
|
||||
"sync"
|
||||
|
||||
"git.staur.ca/stobbsm/clustvirt/lib/guest"
|
||||
"git.staur.ca/stobbsm/clustvirt/lib/secret"
|
||||
"git.staur.ca/stobbsm/clustvirt/lib/storagepool"
|
||||
"git.staur.ca/stobbsm/clustvirt/lib/storagevol"
|
||||
"libvirt.org/go/libvirt"
|
||||
"libvirt.org/go/libvirtxml"
|
||||
)
|
||||
@ -37,23 +34,23 @@ type Host struct {
|
||||
// Secure indicates if the connection is secure
|
||||
Secure bool
|
||||
// HostInfo provides basic HW information about a host
|
||||
HostInfo libvirtxml.CapsHost
|
||||
HostInfo *libvirtxml.CapsHost
|
||||
// NodeMemory provides basic memory information about the Host
|
||||
NodeMemory NodeMemoryInfo
|
||||
NodeMemory *NodeMemoryInfo
|
||||
// VMList is the list of virtual machines available to the host
|
||||
VMList []libvirtxml.Domain
|
||||
VMList []*libvirtxml.Domain
|
||||
// NetIfList is the list of network interfaces on the host
|
||||
NetIfFList []libvirtxml.Interface
|
||||
NetIfFList []*libvirtxml.Interface
|
||||
// NetworkList is the list of defined networks on the host
|
||||
NetworkList []libvirtxml.Network
|
||||
NetworkList []*libvirtxml.Network
|
||||
// DeviceList is the list of devices on the host
|
||||
DeviceList []libvirtxml.NodeDevice
|
||||
DeviceList []*libvirtxml.NodeDevice
|
||||
// SecretList provides a list of secrets available to the host
|
||||
SecretList []libvirtxml.Secret
|
||||
SecretList []*libvirtxml.Secret
|
||||
// StoragePoolList provides the list of stoarge ppols available to the host
|
||||
StoragePoolList []libvirtxml.StoragePool
|
||||
StoragePoolList []*libvirtxml.StoragePool
|
||||
// VolumeList is the list of volumes available on the host
|
||||
VolumeList []libvirtxml.StorageVolume
|
||||
VolumeList []*libvirtxml.StorageVolume
|
||||
|
||||
uri *URI
|
||||
conn *libvirt.Connect
|
||||
@ -128,13 +125,14 @@ func (h *Host) getInfo() {
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
infoFuncs := []func(){
|
||||
h.getDevicesInfo,
|
||||
// h.getDomainInfo,
|
||||
h.getIfaceInfo,
|
||||
h.hostInfo,
|
||||
h.memoryInfo,
|
||||
h.getStoragePools,
|
||||
h.getNetsInfo,
|
||||
h.getNodeInfo,
|
||||
// h.getSecretsInfo,
|
||||
// h.getStoragePools,
|
||||
h.getIfaceInfo,
|
||||
h.getDevicesInfo,
|
||||
h.getDomainInfo,
|
||||
h.getSecretsInfo,
|
||||
}
|
||||
|
||||
for _, f := range infoFuncs {
|
||||
@ -148,159 +146,40 @@ func (h *Host) getInfo() {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (h *Host) getStoragePools() {
|
||||
spools, err := h.conn.ListAllStoragePools(0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if len(spools) > 0 {
|
||||
h.StoragePoolList = make([]StoragePoolInfo, len(spools))
|
||||
for i, s := range spools {
|
||||
if h.StoragePoolList[i].XML, err = s.GetXMLDesc(0); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if h.StoragePoolList[i].Name, err = s.GetName(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if h.StoragePoolList[i].UUID, err = s.GetUUID(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if h.StoragePoolList[i].Active, err = s.IsActive(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if h.StoragePoolList[i].Persistent, err = s.IsPersistent(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if h.StoragePoolList[i].AutoStart, err = s.GetAutostart(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
spInfo, err := s.GetInfo()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
h.StoragePoolList[i].State = storagepool.StoragePoolStateMap[spInfo.State]
|
||||
h.StoragePoolList[i].Capacity = spInfo.Capacity
|
||||
h.StoragePoolList[i].Allocation = spInfo.Allocation
|
||||
h.StoragePoolList[i].Available = spInfo.Available
|
||||
|
||||
spoolXML := &libvirtxml.StoragePool{}
|
||||
if err = spoolXML.Unmarshal(h.StoragePoolList[i].XML); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
h.StoragePoolList[i].Type = spoolXML.Type
|
||||
for _, t := range storagepool.NetTypes {
|
||||
if h.StoragePoolList[i].Type == t {
|
||||
h.StoragePoolList[i].IsNet = true
|
||||
h.StoragePoolList[i].HAEnabled = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
svols, err := s.ListAllStorageVolumes(0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if len(svols) > 0 {
|
||||
h.StoragePoolList[i].Volumes = make([]VolumeInfo, len(svols))
|
||||
for j, sv := range svols {
|
||||
if h.StoragePoolList[i].Volumes[j].Name, err = sv.GetName(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if h.StoragePoolList[i].Volumes[j].Key, err = sv.GetKey(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if h.StoragePoolList[i].Volumes[j].Path, err = sv.GetPath(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
svInfo, err := sv.GetInfo() // Type, Capacity, Allocation
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
h.StoragePoolList[i].Volumes[j].Type = storagevol.StorageVolTypeMap[svInfo.Type]
|
||||
h.StoragePoolList[i].Volumes[j].Capacity = svInfo.Capacity
|
||||
h.StoragePoolList[i].Volumes[j].Allocation = svInfo.Allocation
|
||||
if h.StoragePoolList[i].Volumes[j].XML, err = sv.GetXMLDesc(0); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
sv.Free()
|
||||
}
|
||||
}
|
||||
|
||||
s.Free()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Host) getSecretsInfo() {
|
||||
nsecrets, err := h.conn.ListAllSecrets(0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if len(nsecrets) > 0 {
|
||||
h.SecretList = make([]SecretInfo, len(nsecrets))
|
||||
for i, s := range nsecrets {
|
||||
if h.SecretList[i].XML, err = s.GetXMLDesc(0); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
stype, err := s.GetUsageType()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
h.SecretList[i].Type = secret.SecretUsageTypeMap[stype]
|
||||
|
||||
s.Free()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Host) getNodeInfo() {
|
||||
func (h *Host) hostInfo() {
|
||||
var err error
|
||||
h.AvailableCPUTypes, err = h.conn.GetCPUModelNames("x86_64", 0)
|
||||
if err != nil {
|
||||
log.Println("Error getting cpu model names", err)
|
||||
}
|
||||
|
||||
ni, err := h.conn.GetNodeInfo()
|
||||
rawxml, err := h.conn.GetCapabilities()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Printf("error getting host capabilities XML: %s", err)
|
||||
}
|
||||
h.HostInfo.Model = ni.Model
|
||||
h.HostInfo.Memory = ni.Memory
|
||||
h.HostInfo.Cpus = ni.Cpus
|
||||
h.HostInfo.MHz = ni.MHz
|
||||
h.HostInfo.Nodes = ni.Nodes
|
||||
h.HostInfo.Sockets = ni.Sockets
|
||||
h.HostInfo.Cores = ni.Cores
|
||||
h.HostInfo.Threads = ni.Threads
|
||||
xmldoc := &libvirtxml.Caps{}
|
||||
if err = xmldoc.Unmarshal(rawxml); err != nil {
|
||||
log.Printf("error parsing host capabilities XML: %s", err)
|
||||
}
|
||||
h.HostInfo = &xmldoc.Host
|
||||
h.SystemHostName, err = h.conn.GetHostname()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if h.SystemHostName == "" {
|
||||
log.Println("error getting system host name: %s", err)
|
||||
} else {
|
||||
h.SystemHostName = h.HostName
|
||||
}
|
||||
h.LibVersion, err = h.conn.GetLibVersion()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
h.FreeMemory, err = h.conn.GetFreeMemory()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Host) memoryInfo() {
|
||||
mi, err := h.conn.GetMemoryStats(libvirt.NODE_MEMORY_STATS_ALL_CELLS, 0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
h.NodeMemory.Total = mi.Total
|
||||
h.NodeMemory.Free = mi.Free
|
||||
h.NodeMemory.Buffers = mi.Buffers
|
||||
h.NodeMemory.Cached = mi.Cached
|
||||
|
||||
h.StorageCapabilities, err = h.conn.GetStoragePoolCapabilities(0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
h.NodeMemory = &NodeMemoryInfo{
|
||||
Total: mi.Total,
|
||||
Free: mi.Free,
|
||||
Buffers: mi.Buffers,
|
||||
Cached: mi.Cached,
|
||||
}
|
||||
|
||||
h.SysInfo, err = h.conn.GetSysinfo(0)
|
||||
@ -322,6 +201,101 @@ func (h *Host) getNodeInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Host) getStoragePools() {
|
||||
// Get list of all storage pools on the host
|
||||
spools, err := h.conn.ListAllStoragePools(0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if len(spools) > 0 {
|
||||
h.StoragePoolList = make([]*libvirtxml.StoragePool, len(spools))
|
||||
for i, s := range spools {
|
||||
// run in a function to allow defer s.Free()
|
||||
func() {
|
||||
defer s.Free()
|
||||
// Get the XML represenation of each storage pool, parse it with libvirtxml
|
||||
rawxml, err := s.GetXMLDesc(0)
|
||||
if err != nil {
|
||||
log.Println("error getting storage pool xml: %s", err)
|
||||
return
|
||||
}
|
||||
xmldoc := &libvirtxml.StoragePool{}
|
||||
err = xmldoc.Unmarshal(rawxml)
|
||||
if err != nil {
|
||||
log.Println("error parsing storage pool XML: %s", err)
|
||||
return
|
||||
}
|
||||
h.StoragePoolList[i] = xmldoc
|
||||
|
||||
// Get list of all storage volumes in the current storage pool
|
||||
svols, err := s.ListAllStorageVolumes(0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if len(svols) > 0 {
|
||||
// define temporary variable to hold slice of StorageVolume, that can
|
||||
// either be appended to the existing slice, or used in place of the newly
|
||||
// defined slice
|
||||
tvl := make([]*libvirtxml.StorageVolume, len(svols))
|
||||
for j, sv := range svols {
|
||||
// run in a function so I can defer the sv.Free() call
|
||||
func() {
|
||||
defer sv.Free()
|
||||
rawxml, err = sv.GetXMLDesc(0)
|
||||
if err != nil {
|
||||
log.Printf("error getting XML from storage volume: %s", err)
|
||||
return
|
||||
}
|
||||
xmldoc := &libvirtxml.StorageVolume{}
|
||||
err = xmldoc.Unmarshal(rawxml)
|
||||
if err != nil {
|
||||
log.Printf("error parsing storage volume XML: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
tvl[j] = xmldoc
|
||||
}()
|
||||
}
|
||||
// Append the contents of tvl to h.VolumeList
|
||||
if h.VolumeList == nil {
|
||||
h.VolumeList = []*libvirtxml.StorageVolume{}
|
||||
}
|
||||
// Only append if the temporary storage volume isn't nil
|
||||
for _, tsv := range tvl {
|
||||
if tsv != nil {
|
||||
h.VolumeList = append(h.VolumeList, tsv)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Host) getSecretsInfo() {
|
||||
nsecrets, err := h.conn.ListAllSecrets(0)
|
||||
if err != nil {
|
||||
log.Printf("error loading secrets from host: %s", err)
|
||||
}
|
||||
if len(nsecrets) > 0 {
|
||||
h.SecretList = make([]*libvirtxml.Secret, len(nsecrets))
|
||||
for i, s := range nsecrets {
|
||||
func() {
|
||||
defer s.Free()
|
||||
rawxml, err := s.GetXMLDesc(0)
|
||||
if err != nil {
|
||||
log.Printf("error getting secret XML", err)
|
||||
}
|
||||
xmldoc := &libvirtxml.Secret{}
|
||||
if err = xmldoc.Unmarshal(rawxml); err != nil {
|
||||
log.Printf("error parsing secret XML: %s", err)
|
||||
}
|
||||
h.SecretList[i] = xmldoc
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Host) getDomainInfo() {
|
||||
// getDomainInfo
|
||||
doms, err := h.conn.ListAllDomains(0)
|
||||
|
Loading…
Reference in New Issue
Block a user