diff --git a/addDroplet.go b/addDroplet.go deleted file mode 100644 index 6396c60..0000000 --- a/addDroplet.go +++ /dev/null @@ -1,394 +0,0 @@ -// Copyright 2024 WIT.COM Inc Licensed GPL 3.0 - -package main - -import ( - "encoding/xml" - "errors" - "fmt" - - "github.com/google/uuid" - pb "go.wit.com/lib/protobuf/virtbuf" - "go.wit.com/lib/virtigoxml" - "go.wit.com/log" - "libvirt.org/go/libvirtxml" -) - -// import a libvirt xml file -func addDomainDroplet(domcfg *libvirtxml.Domain) (*pb.Droplet, []*pb.Event, error) { - var alle []*pb.Event - if domcfg == nil { - return nil, alle, errors.New("domcfg == nil") - } - - d, err := findDomain(domcfg) - if err != nil { - return nil, alle, err - } - if d == nil { - d = me.cluster.AddDroplet(domcfg.UUID, domcfg.Name, 2, 2*1024*1024) - d.StartState = pb.DropletState_OFF - d.CurrentState = pb.DropletState_UNKNOWN - - // if the domcfg doesn't have a uuid, make a new one here - if d.Uuid == "" { - u := uuid.New() - d.Uuid = u.String() - } - } - - alle, err = updateDroplet(d, domcfg) - if err != nil { - log.Info("updateDroplet() failed for", d.Hostname) - return d, alle, errors.New("update failed for " + domcfg.Name) - } - log.Info("added new droplet", domcfg.Name, domcfg.UUID) - virtigoxml.DumpNonStandardXML(domcfg) - return d, alle, nil -} - -func findDomain(domcfg *libvirtxml.Domain) (*pb.Droplet, error) { - var found *pb.Droplet - if domcfg == nil { - return nil, errors.New("domcfg == nil") - } - - for _, d := range me.cluster.Droplets { - if d.Hostname == domcfg.Name { - if d.Uuid != domcfg.UUID { - if domcfg.UUID == "" { - // ignore blank or nonexistent UUID's - // todo: check to see if the uuid already exists ? - domcfg.UUID = d.Uuid - } else { - fmt.Println("Will Change UUID from", d.Uuid, "to", domcfg.UUID, "for hostname", d.Hostname) - d.Uuid = domcfg.UUID - me.changed = true - } - } - if found == nil { - found = d - } else { - fmt.Println("FOUND TWICE", d.Uuid, domcfg.Name, domcfg.UUID) - return d, errors.New("Found Twice") - } - - } - if d.Uuid == domcfg.UUID { - if d.Hostname != domcfg.Name { - fmt.Println("protobuf has: UUID and Name:", d.Uuid, d.Hostname) - fmt.Println("libvirt has: UUID and Name:", domcfg.UUID, domcfg.Name) - fmt.Println("FOUND UUID WITH MIS-MATCHED NAME", domcfg.Name, domcfg.UUID) - return d, errors.New("UUID with mis-matched names") - } - } - } - - return found, nil -} - -func updateDroplet(d *pb.Droplet, domcfg *libvirtxml.Domain) ([]*pb.Event, error) { - var alle []*pb.Event - - if d == nil { - return alle, errors.New("d == nil") - } - if domcfg == nil { - return alle, errors.New("domcfg == nil") - } - - e, err := updateMemory(d, domcfg) - if err != nil { - log.Info("updateMemory() failed") - return alle, err - } - if e != nil { - alle = append(alle, e) - } - - // update arch & machine - if (domcfg.OS != nil) && (domcfg.OS.Type != nil) { - // OS Type: &{Arch:x86_64 Machine:pc-i440fx-5.2 Type:hvm} - t := domcfg.OS.Type - if d.QemuArch != t.Arch { - e := d.NewChangeEvent("Droplet.QemuArch", d.QemuArch, t.Arch) - alle = append(alle, e) - d.QemuArch = t.Arch - } - if d.QemuMachine != t.Machine { - e := d.NewChangeEvent("Droplet.QemuMachine", d.QemuMachine, t.Machine) - alle = append(alle, e) - d.QemuMachine = t.Machine - } - } - - // check cpus - if d.Cpus != int64(domcfg.VCPU.Value) { - // fmt.Printf("cpus changed. VCPU = %+v\n", domcfg.VCPU) - fmt.Printf("cpus changed. from %d to %d\n", d.Cpus, domcfg.VCPU.Value) - alle = append(alle, d.NewChangeEvent("Droplet.Cpus", d.Cpus, domcfg.VCPU.Value)) - d.Cpus = int64(domcfg.VCPU.Value) - } - - // update spice port - if domcfg.Devices.Graphics != nil { - for _, g := range domcfg.Devices.Graphics { - if g.Spice == nil { - continue - } - var s *libvirtxml.DomainGraphicSpice - s = g.Spice - // fmt.Printf("Spice: %d %+v %s\n", i, s, s.AutoPort) - if s.AutoPort == "yes" { - // should ignore either way - } else { - if d.SpicePort != int64(s.Port) { - // print out, but ignore the port number - d.SpicePort = int64(s.Port) - fmt.Printf("Spice Port set to = %d\n", s.Port) - alle = append(alle, d.NewChangeEvent("Droplet.SpicePort", d.SpicePort, s.Port)) - } - } - } - } - - // check type - if domcfg.Type != "kvm" { - fmt.Printf("not kvm. Virt type == %s\n", domcfg.Type) - return alle, errors.New("not kvm") - } - - nete, err := updateNetwork(d, domcfg) - if err != nil { - log.Info("updateNetwork() failed", err) - return alle, err - } - - for _, e := range nete { - alle = append(alle, e) - } - - nete, err = updateDisk(d, domcfg) - if err != nil { - return alle, err - } - - for _, e := range nete { - alle = append(alle, e) - } - - if alle == nil { - log.Info("libvirt xml import worked. nothing changed", domcfg.Name) - return alle, nil - } - log.Info("libvirt xml import worked. droplet changed", domcfg.Name) - - // append each change event - for _, e := range alle { - me.cluster.Events = append(me.cluster.Events, e) - } - return alle, nil -} - -// returns false if something went wrong -func updateMemory(d *pb.Droplet, domcfg *libvirtxml.Domain) (*pb.Event, error) { - if (d == nil) || (domcfg == nil) { - return nil, errors.New("domcfg == nil") - } - - if domcfg.Memory == nil { - // nothing to do. libvirt xml file didn't define memory size - return nil, nil - } - - var m int64 = 0 - switch domcfg.Memory.Unit { - case "KiB": - m = int64(domcfg.Memory.Value * 1024) - case "MiB": - m = int64(domcfg.Memory.Value * 1024 * 1024) - case "GiB": - 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) - } - e := d.SetMemory(m) - if e != nil { - fmt.Printf("Memory changed %s to %d %s\n", pb.HumanFormatBytes(d.Memory), domcfg.Memory.Value, domcfg.Memory.Unit) - d.Memory = m - // me.changed = true - } - return e, nil -} - -func updateNetwork(d *pb.Droplet, domcfg *libvirtxml.Domain) ([]*pb.Event, error) { - var allEvents []*pb.Event - if (d == nil) || (domcfg == nil) { - return nil, errors.New("domcfg == nil") - } - - // mac address & bridge name - var macs map[string]string - macs = make(map[string]string) - // Iterate over the network interfaces and print the MAC addresses - for _, iface := range domcfg.Devices.Interfaces { - var hwaddr string - var brname string - // fmt.Printf("iface: %+v\n", iface) - // fmt.Printf("MAC: %+v\n", iface.MAC) - // fmt.Printf("Source: %+v\n", iface.Source) - // fmt.Printf("Bridge: %+v\n", iface.Source.Bridge) - // fmt.Printf("Model: %+v\n", iface.Model) - if iface.MAC != nil { - // iface.MAC.Address = "aa:bb:aa:bb:aa:ff" - // log.Info("Interface:", iface.Target, "MAC Address:", iface.MAC.Address) - // fmt.Printf("source: %+v\n", iface.Source) - hwaddr = iface.MAC.Address - } - if iface.Source == nil { - // fmt.Printf("non-standard network: %+v\n", iface) - updatedXML, _ := xml.MarshalIndent(domcfg.Devices.Interfaces, "", " ") - log.Info("Non-Standard Network XML Start") - fmt.Println(string(updatedXML)) - log.Info("Non-Standard Network XML End") - return nil, errors.New("non-standard network. source == nil") - } - - if iface.Source.Bridge == nil { - if hwaddr == "" { - fmt.Printf("non-standard network: %+v\n", iface) - updatedXML, _ := xml.MarshalIndent(domcfg.Devices.Interfaces, "", " ") - log.Info("Non-Standard Network XML Start") - fmt.Println(string(updatedXML)) - log.Info("Non-Standard Network XML End") - return nil, errors.New("bridge is nil and no mac address") - } - brname = "" - } else { - if iface.Source.Bridge.Bridge == "" { - if hwaddr == "" { - fmt.Printf("non-standard network: %+v\n", iface) - fmt.Printf("iface.Mac: %+v\n", iface) - updatedXML, _ := xml.MarshalIndent(domcfg.Devices.Interfaces, "", " ") - log.Info("Non-Standard Network XML Start") - fmt.Println(string(updatedXML)) - log.Info("Non-Standard Network XML End") - return nil, errors.New("bridge is blank and no mac address") - } - brname = iface.Source.Bridge.Bridge - } - } - // log.Info("network has bridge:", iface.Source.Bridge.Bridge) - if hwaddr == "" { - hwaddr = "generate " + domcfg.Name - log.Info("need to generate mac addr for bridge:", brname) - // return nil, errors.New("need to generate mac addr for bridge: " + brname) - } - macs[hwaddr] = brname - } - - for mac, brname := range macs { - var found bool = false - // log.Info("XML has mac address:", mac, brname) - for _, eth := range d.Networks { - if eth.Mac == mac { - // log.Info("OKAY. FOUND ETH:", eth.Mac, eth.Name, brname) - found = true - if brname == "" { - // if new bridge name is blank, keep the old one - brname = eth.Name - } - if eth.Name != brname { - if argv.IgnoreBr { - log.Info("network was:", eth.Mac, eth.Name) - log.Info("network now:", eth.Mac, brname) - log.Info("ignoring network change (--xml-ignore-net)") - } else { - return nil, errors.New("bridge name changed") - } - } - } - } - if !found { - if virtigoxml.CheckUniqueMac(me.cluster, mac) { - } else { - log.Info("droplet", d.Hostname, "duplicate mac address", mac) - return nil, errors.New("duplicate mac address") - } - var eth *pb.Network - eth = new(pb.Network) - eth.Mac = mac - if brname == "" { - brname = "worldbr" - } - eth.Name = brname - d.Networks = append(d.Networks, eth) - allEvents = append(allEvents, d.NewChangeEvent("Droplet NewNetwork", "", mac+" "+brname)) - } - } - - log.Verbose("mac addrs:", macs) - return allEvents, nil -} - -/* from vm3-with-nvme-1.5GB-sec.xml - - - - - - -
- -*/ - -// returns false if something went wrong -func updateDisk(d *pb.Droplet, domcfg *libvirtxml.Domain) ([]*pb.Event, error) { - var alle []*pb.Event - - if (d == nil) || (domcfg == nil) { - return nil, errors.New("domcfg == nil") - } - for _, disk := range domcfg.Devices.Disks { - var t *libvirtxml.DomainDiskSourceFile - t = disk.Source.File - if t == nil { - fmt.Println("disk.Source.File == nil") - continue - } - filename := t.File - if filename == "" { - fmt.Println("No disk source file found.") - continue - } - - e, err := virtigoxml.InsertFilename(me.cluster, d, filename) - if err != nil { - return alle, err - } - if e == nil { - continue - } - alle = append(alle, e) - - /* - var found bool = false - for _, disk := range d.Disks { - if disk.Filename == filename { - log.Verbose("OKAY. FOUND filename", filename) - found = true - } - } - if !found { - var disk *pb.Disk - disk = new(pb.Disk) - disk.Filename = filename - d.Disks = append(d.Disks, disk) - log.Info("New filename", filename) - me.changed = true - } - */ - } - return alle, nil -} diff --git a/main.go b/main.go index b3ef4f8..b0eb414 100644 --- a/main.go +++ b/main.go @@ -86,7 +86,7 @@ func main() { } // this is a new droplet. add it to the cluster log.Info("Add XML Droplet here", domcfg.Name) - _, newe, err := addDomainDroplet(domcfg) + _, newe, err := virtigoxml.AddDomainDroplet(me.cluster, domcfg) if err != nil { log.Info("addDomainDroplet() error", filename) log.Info("addDomainDroplet() error", err) diff --git a/start.go b/start.go index e6c0b58..9a19bad 100644 --- a/start.go +++ b/start.go @@ -25,7 +25,7 @@ func newStart(start string) { newAddXml(domcfg, "spice") newAddXml(domcfg, "qcow") - virtigoxml.StartDropletXml(d, domcfg, start) + virtigoxml.StartDropletXml(me.cluster, d, domcfg, start) } func newAddXml(domcfg *libvirtxml.Domain, filename string) error {