better libvirt xml processing

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-10-25 04:30:35 -05:00
parent 9518e70d7a
commit fb722a3dc9
3 changed files with 63 additions and 65 deletions

View File

@ -31,17 +31,11 @@ func addDomainDroplet(domcfg *libvirtxml.Domain) (*DropletT, error) {
me.droplets = append(me.droplets, d) me.droplets = append(me.droplets, d)
me.changed = true me.changed = true
if updateDroplet(d, domcfg) { err := updateDroplet(d, domcfg)
if me.changed { if err != nil {
log.Info("updateDroplet() worked. droplet changed")
} else {
log.Verbose("updateDroplet() worked. nothing changed")
}
} else {
log.Info("updateDroplet() failed for", d.pb.Hostname) log.Info("updateDroplet() failed for", d.pb.Hostname)
return d, errors.New("update failed for " + domcfg.Name) return d, errors.New("update failed for " + domcfg.Name)
} }
log.Info("added new droplet", domcfg.Name, domcfg.UUID) log.Info("added new droplet", domcfg.Name, domcfg.UUID)
dumpNonStandardXML(domcfg) dumpNonStandardXML(domcfg)
return d, nil return d, nil
@ -87,19 +81,23 @@ func findDomain(domcfg *libvirtxml.Domain) (*DropletT, error) {
return found, nil return found, nil
} }
func updateDroplet(d *DropletT, domcfg *libvirtxml.Domain) bool { func updateDroplet(d *DropletT, domcfg *libvirtxml.Domain) error {
var ok bool = true var alle []*pb.Event
if d == nil { if d == nil {
return false return errors.New("d == nil")
} }
if domcfg == nil { if domcfg == nil {
return false return errors.New("domcfg == nil")
} }
if !updateMemory(d, domcfg) { e, err := updateMemory(d, domcfg)
if err != nil {
log.Info("updateMemory() failed") log.Info("updateMemory() failed")
ok = false return err
}
if e != nil {
alle = append(alle, e)
} }
// update arch & machine // update arch & machine
@ -107,12 +105,12 @@ func updateDroplet(d *DropletT, domcfg *libvirtxml.Domain) bool {
// OS Type: &{Arch:x86_64 Machine:pc-i440fx-5.2 Type:hvm} // OS Type: &{Arch:x86_64 Machine:pc-i440fx-5.2 Type:hvm}
t := domcfg.OS.Type t := domcfg.OS.Type
if d.pb.QemuArch != t.Arch { if d.pb.QemuArch != t.Arch {
alle = append(alle, NewChangeEvent(d.pb, "Droplet.QemuArch", d.pb.QemuArch, t.Arch))
d.pb.QemuArch = t.Arch d.pb.QemuArch = t.Arch
me.changed = true
} }
if d.pb.QemuMachine != t.Machine { if d.pb.QemuMachine != t.Machine {
alle = append(alle, NewChangeEvent(d.pb, "Droplet.QemuMachine", d.pb.QemuMachine, t.Machine))
d.pb.QemuMachine = t.Machine d.pb.QemuMachine = t.Machine
me.changed = true
} }
} }
@ -120,8 +118,8 @@ func updateDroplet(d *DropletT, domcfg *libvirtxml.Domain) bool {
if d.pb.Cpus != int64(domcfg.VCPU.Value) { if d.pb.Cpus != int64(domcfg.VCPU.Value) {
// fmt.Printf("cpus changed. VCPU = %+v\n", domcfg.VCPU) // fmt.Printf("cpus changed. VCPU = %+v\n", domcfg.VCPU)
fmt.Printf("cpus changed. from %d to %d\n", d.pb.Cpus, domcfg.VCPU.Value) fmt.Printf("cpus changed. from %d to %d\n", d.pb.Cpus, domcfg.VCPU.Value)
alle = append(alle, NewChangeEvent(d.pb, "Droplet.Cpus", d.pb.Cpus, domcfg.VCPU.Value))
d.pb.Cpus = int64(domcfg.VCPU.Value) d.pb.Cpus = int64(domcfg.VCPU.Value)
me.changed = true
} }
// update spice port // update spice port
@ -140,7 +138,7 @@ func updateDroplet(d *DropletT, domcfg *libvirtxml.Domain) bool {
// print out, but ignore the port number // print out, but ignore the port number
d.pb.SpicePort = int64(s.Port) d.pb.SpicePort = int64(s.Port)
fmt.Printf("Spice Port set to = %d\n", s.Port) fmt.Printf("Spice Port set to = %d\n", s.Port)
me.changed = true alle = append(alle, NewChangeEvent(d.pb, "Droplet.SpicePort", d.pb.SpicePort, s.Port))
} }
} }
} }
@ -149,55 +147,63 @@ func updateDroplet(d *DropletT, domcfg *libvirtxml.Domain) bool {
// check type // check type
if domcfg.Type != "kvm" { if domcfg.Type != "kvm" {
fmt.Printf("not kvm. Virt type == %s\n", domcfg.Type) fmt.Printf("not kvm. Virt type == %s\n", domcfg.Type)
ok = false return errors.New("not kvm")
} }
if !updateNetwork(d, domcfg) { if !updateNetwork(d, domcfg) {
log.Info("updateNetwork() failed") log.Info("updateNetwork() failed")
ok = false return errors.New("updateNetwork() failed")
} }
if !updateDisk(d, domcfg) { if !updateDisk(d, domcfg) {
log.Info("updateDisk() failed") return errors.New("updateDisk() failed")
ok = false
} }
return ok
if alle == nil {
log.Info("libvirt xml import worked. nothing changed", domcfg.Name)
return nil
}
log.Info("libvirt xml import worked. droplet changed", domcfg.Name)
// log.Info("all change events", alle)
me.changed = true
// append each change event
for _, e := range alle {
me.events.Events = append(me.events.Events, e)
}
return nil
} }
// returns false if something went wrong // returns false if something went wrong
func updateMemory(d *DropletT, domcfg *libvirtxml.Domain) bool { func updateMemory(d *DropletT, domcfg *libvirtxml.Domain) (*pb.Event, error) {
if (d == nil) || (domcfg == nil) { if (d == nil) || (domcfg == nil) {
return false return nil, errors.New("domcfg == nil")
} }
if domcfg.Memory == nil { if domcfg.Memory == nil {
return true // nothing to do. libvirt xml file didn't define memory size
return nil, nil
} }
var m int64 = 0 var m int64 = 0
switch domcfg.Memory.Unit {
// check memory case "KiB":
if domcfg.Memory.Unit == "KiB" {
m = int64(domcfg.Memory.Value * 1024) m = int64(domcfg.Memory.Value * 1024)
} case "MiB":
if domcfg.Memory.Unit == "MiB" {
m = int64(domcfg.Memory.Value * 1024 * 1024) m = int64(domcfg.Memory.Value * 1024 * 1024)
} case "GiB":
if domcfg.Memory.Unit == "GiB" {
m = int64(domcfg.Memory.Value * 1024 * 1024 * 1024) m = int64(domcfg.Memory.Value * 1024 * 1024 * 1024)
default:
fmt.Println("Unknown Memory Unit", domcfg.Memory.Unit)
return nil, errors.New("Unknown Memory Unit " + domcfg.Memory.Unit)
} }
if e := d.SetMemory(m); e != nil { e := d.SetMemory(m)
if e != nil {
fmt.Printf("Memory changed %s to %d %s\n", pb.HumanFormatBytes(d.pb.Memory), domcfg.Memory.Value, domcfg.Memory.Unit) fmt.Printf("Memory changed %s to %d %s\n", pb.HumanFormatBytes(d.pb.Memory), domcfg.Memory.Value, domcfg.Memory.Unit)
d.pb.Memory = m d.pb.Memory = m
me.changed = true // me.changed = true
return true
} else {
// nothing changed
return true
} }
fmt.Println("Unknown Memory Unit", domcfg.Memory.Unit) return e, nil
return false
} }
// returns false if something went wrong // returns false if something went wrong

View File

@ -59,7 +59,7 @@ func convertToString(x any) string {
} }
// Wrapping the int into a protobuf message // Wrapping the int into a protobuf message
func NewChangeEvent(d *pb.Droplet, origval any, newval any) *pb.Event { func NewChangeEvent(d *pb.Droplet, fname string, origval any, newval any) *pb.Event {
var e *pb.Event var e *pb.Event
e = new(pb.Event) e = new(pb.Event)
@ -70,7 +70,9 @@ func NewChangeEvent(d *pb.Droplet, origval any, newval any) *pb.Event {
// this also works, but it's a bit overkill // this also works, but it's a bit overkill
// e.NewAny = convertToAnypb(newval) // e.NewAny = convertToAnypb(newval)
me.events.Events = append(me.events.Events, e) // me.events.Events = append(me.events.Events, e)
// stuff := me.events.FormatJSON()
// log.Info("events:", stuff)
return e return e
} }
@ -79,18 +81,12 @@ func (d *DropletT) SetMemory(b int64) *pb.Event {
oldm := pb.HumanFormatBytes(d.pb.Memory) oldm := pb.HumanFormatBytes(d.pb.Memory)
newm := pb.HumanFormatBytes(b) newm := pb.HumanFormatBytes(b)
if d.pb.Memory == b { if d.pb.Memory == b {
log.Info("droplet", d.pb.Hostname, "memory unchanged", oldm, "to", newm) // log.Info("droplet", d.pb.Hostname, "memory unchanged", oldm, "to", newm)
return nil return nil
} }
log.Info("droplet", d.pb.Hostname, "memory change from", oldm, "to", newm) log.Info("droplet", d.pb.Hostname, "memory change from", oldm, "to", newm)
var e *pb.Event return NewChangeEvent(d.pb, "Droplet.Memory", d.pb.Memory, b)
e = NewChangeEvent(d.pb, d.pb.Memory, b)
e.FieldName = "Droplet.Memory"
stuff := me.events.FormatJSON()
log.Info("events:", stuff)
return e
} }
// update the droplet memory // update the droplet memory

20
main.go
View File

@ -52,6 +52,7 @@ func main() {
// sanity check the droplets // sanity check the droplets
checkDroplets() checkDroplets()
// ok tracks if all the libvirt xml files imported ok
var ok bool = true var ok bool = true
for _, filename := range argv.Xml { for _, filename := range argv.Xml {
domcfg, err := readXml(filename) domcfg, err := readXml(filename)
@ -79,19 +80,18 @@ func main() {
} }
} else { } else {
// this droplet is already here // this droplet is already here
if updateDroplet(d, domcfg) { err := updateDroplet(d, domcfg)
if me.changed { if err != nil {
log.Info("updateDroplet() worked. droplet changed") log.Info("updateDroplet() error", d.pb.Hostname, err)
} else {
log.Info(filename, "nothing changed")
}
} else {
log.Info("updateDroplet() failed for", d.pb.Hostname)
ok = false ok = false
} }
} }
} }
if len(argv.Xml) != 0 { if len(argv.Xml) != 0 {
if !ok {
log.Info("importing xml files had errors")
os.Exit(-1)
}
if me.changed { if me.changed {
if argv.Save { if argv.Save {
writeConfigFile() writeConfigFile()
@ -100,10 +100,6 @@ func main() {
log.Info("Not saving changes (use --save to save)") log.Info("Not saving changes (use --save to save)")
} }
} }
if !ok {
log.Info("adding xml files failed")
os.Exit(-1)
}
os.Exit(0) os.Exit(0)
} }