diff options
| -rw-r--r-- | addDroplet.go | 12 | ||||
| -rw-r--r-- | argv.go | 24 | ||||
| -rw-r--r-- | config.go | 12 | ||||
| -rw-r--r-- | main.go | 3 | ||||
| -rw-r--r-- | structs.go | 1 | ||||
| -rw-r--r-- | validate.go | 70 |
6 files changed, 108 insertions, 14 deletions
diff --git a/addDroplet.go b/addDroplet.go index be08460..dd625fb 100644 --- a/addDroplet.go +++ b/addDroplet.go @@ -56,9 +56,15 @@ func findDomain(domcfg *libvirtxml.Domain) (*DropletT, error) { for _, d := range me.droplets { if d.pb.Hostname == domcfg.Name { if d.pb.Uuid != domcfg.UUID { - fmt.Println("CHANGED UUID", d.pb.Uuid, domcfg.UUID) - d.pb.Uuid = domcfg.UUID - me.changed = true + if domcfg.UUID == "" { + // ignore blank or nonexistent UUID's + // todo: check to see if the uuid already exists ? + domcfg.UUID = d.pb.Uuid + } else { + fmt.Println("Will Change UUID from", d.pb.Uuid, "to", domcfg.UUID, "for hostname", d.pb.Hostname) + d.pb.Uuid = domcfg.UUID + me.changed = true + } } if found == nil { found = d @@ -11,31 +11,33 @@ import "go.wit.com/log" var argv args type args struct { - Xml []string `arg:"--libvirt" help:"add current xml files: --libvirt /etc/libvirt/qemu/*.xml"` - Save bool `arg:"--save" default:"false" help:"save config protobuf after libvirt file import"` - Config string `arg:"--config" help:"defaults to ~/.config/virtigo/"` - Port int `arg:"--port" default:"8080" help:"allow droplet events via http"` - Daemon bool `arg:"--daemon" help:"run in daemon mode"` + Xml []string `arg:"--libvirt" help:"import qemu xml files: --libvirt /etc/libvirt/qemu/*.xml"` + Save bool `arg:"--save" default:"false" help:"save protobuf config after import"` + Config string `arg:"env:VIRTIGO_HOME" help:"defaults to ~/.config/virtigo/"` + Port int `arg:"--port" default:"8080" help:"allow droplet events via http"` + Daemon bool `arg:"--daemon" help:"run in daemon mode"` + } + // Uptime bool `arg:"--uptime" default:"true" help:"allow uptime checks for things like Kuma"` // Hosts []string `arg:"--hosts" help:"hosts to connect to"` func (a args) Description() string { return ` -virtigo will help control your cluster of hypervisiors + virtigo will help control your cluster This maintains a master list of all your vm's (aka 'droplets') in your homelab cloud. You can import libvirt xml files. This app talks to your hypervisors via the virtigod daemon. -Runs a http server so you can control your virtual machines with things like: -start virtual machines with: +Import your existing libvirt xml files with: - curl http://virtigo.wit.com/start?www.wit.com + virtigo --libvirt /etc/libvirt/qemu/*.xml --save -Import your existing libvirt xml files with: +This runs a http server so you can control your virtual machines. +For example to start a vm called 'www.wit.com' your cluster 'foo.bar.com': - virtigo --libvirt ~/mymachines/*.xml --save + curl http://foo.bar.com/start?www.wit.com ` } @@ -1,5 +1,17 @@ package main +/* + All the information is defined by protobuf files + + The config files written out by default into + ~/.config/virtigo/ + + protobuf definitions are by nature non-relational + so each protobuf is written out as a seperate file. + + This seems like the simpilist way to handle this. +*/ + import ( "errors" "fmt" @@ -43,6 +43,9 @@ func main() { cfgfile() + // sanity check the droplets + checkDroplets() + var ok bool = true for _, filename := range argv.Xml { domcfg, err := readXml(filename) @@ -22,6 +22,7 @@ func (b *virtigoT) Enable() { // this app's variables type virtigoT struct { cluster *pb.Cluster + events *pb.Events names []string hypers []*HyperT droplets []*DropletT diff --git a/validate.go b/validate.go new file mode 100644 index 0000000..337422d --- /dev/null +++ b/validate.go @@ -0,0 +1,70 @@ +package main + +/* + validate / sanity check / consistancy check the data + + here is some code to do smart things like: + + * check mac addresses are unique + * check uuid's are unique + * double check filenames are unique + * return a unique mac address + * return a unique uuid + +*/ + +import ( + "os" + + "github.com/google/uuid" + + "go.wit.com/log" +) + +func checkDroplets() bool { + // uuid map to check for duplicates + var umap map[string]string + umap = make(map[string]string) + + // mac address map to check for duplicates + var macs map[string]string + macs = make(map[string]string) + + for _, d := range me.cluster.Droplets { + // Generate a new UUID + if d.Uuid == "" { + u := uuid.New() + d.Uuid = u.String() + } + + // seconds, ok := timeZone[tz]; ok { + if _, ok := umap[d.Uuid]; ok { + // UUID already exists + log.Info("duplicate UUID", d.Uuid, umap[d.Uuid]) + log.Info("duplicate UUID", d.Uuid, d.Hostname) + os.Exit(-1) + } + umap[d.Uuid] = d.Hostname + + for _, n := range d.Networks { + // log.Println("network:", n.Mac, d.Uuid, d.Hostname) + if _, ok := macs[n.Mac]; ok { + // UUID already exists + log.Info("duplicate MAC", n.Mac, macs[n.Mac], umap[macs[n.Mac]]) + log.Info("duplicate MAC", n.Mac, d.Hostname) + os.Exit(-1) + } + macs[n.Mac] = d.Uuid + } + } + + for u, hostname := range umap { + log.Println("uuid:", u, "hostname:", hostname) + } + + for mac, uuid := range macs { + log.Println("mac:", mac, "uuid", uuid, "hostname:", umap[uuid]) + } + + return false +} |
