From 63e750ce89e98fdc1fad7f1cb6a10c798cfc94b2 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Thu, 24 Oct 2024 15:14:47 -0500 Subject: cleanup help Signed-off-by: Jeff Carr --- addDroplet.go | 4 +- argv.go | 19 +++++--- config.go | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configfiles.go | 139 --------------------------------------------------------- main.go | 5 ++- xml.go | 1 + 6 files changed, 160 insertions(+), 147 deletions(-) create mode 100644 config.go delete mode 100644 configfiles.go diff --git a/addDroplet.go b/addDroplet.go index d9912c9..be08460 100644 --- a/addDroplet.go +++ b/addDroplet.go @@ -70,6 +70,8 @@ func findDomain(domcfg *libvirtxml.Domain) (*DropletT, error) { } if d.pb.Uuid == domcfg.UUID { if d.pb.Hostname != domcfg.Name { + fmt.Println("protobuf has: UUID and Name:", d.pb.Uuid, d.pb.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") } @@ -224,7 +226,7 @@ func updateNetwork(d *DropletT, domcfg *libvirtxml.Domain) bool { // fmt.Printf("source: %+v\n", iface.Source) macs = append(macs, iface.MAC.Address) } else { - fmt.Printf("Interface: %s, MAC Address: not available\n", iface.Target.Dev) + fmt.Printf("Interface Target: %+v, MAC Address not available\n", iface.Target) } } diff --git a/argv.go b/argv.go index 4b06219..739c4b8 100644 --- a/argv.go +++ b/argv.go @@ -11,14 +11,14 @@ import "go.wit.com/log" var argv args type args struct { - Xml []string `arg:"--add-xml" help:"add libvirt xml files"` - CfgDir string `arg:"--dir" help:"defaults to ~/.config/virtigo/"` - Hosts []string `arg:"--hosts" help:"hosts to connect to"` + 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"` - Uptime bool `arg:"--uptime" default:"true" help:"allow uptime checks for things like Kuma"` Daemon bool `arg:"--daemon" help:"run in daemon mode"` - Save bool `arg:"--save" default:"false" help:"save xml changes to the protobuf values"` } +// 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 ` @@ -27,6 +27,15 @@ virtigo will help control your cluster of hypervisiors 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: + + curl http://virtigo.wit.com/start?www.wit.com + +Import your existing libvirt xml files with: + + virtigo --libvirt ~/mymachines/*.xml --save ` } diff --git a/config.go b/config.go new file mode 100644 index 0000000..220db76 --- /dev/null +++ b/config.go @@ -0,0 +1,139 @@ +package main + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "time" + + pb "go.wit.com/lib/protobuf/virtbuf" + "go.wit.com/log" +) + +var ErrorNoFile error = errors.New("missing file") +var ErrorParseJSON error = errors.New("invalid json") +var ErrorParseXML error = errors.New("invalid xml") + +// something is wrong somewhere and sometimes the +// protobuf json files get written out with garbage +func cfgfile() { + err := readConfigFile("virtigo.json") + if err == nil { + return + } + if err == ErrorParseJSON { + os.Exit(-1) + } + err = readConfigFile("virtigo.json.last") + if err == nil { + log.Info("read json failed", err) + os.Exit(-1) + } + if err == ErrorNoFile { + log.Info("no config file created yet", err) + os.Exit(-1) + } +} + +func readConfigFile(filename string) error { + me.cluster = new(pb.Cluster) + fullname := filepath.Join(os.Getenv("VIRTIGO_HOME"), filename) + pfile, err := os.ReadFile(fullname) + if err != nil { + log.Info("open config file :", err) + return err + } + err = me.cluster.UnmarshalJSON(pfile) + if err != nil { + log.Info("read json failed", err) + os.Exit(-1) + return err + } + + // initialize each hypervisor + for _, pbh := range me.cluster.Hypervisors { + h := findHypervisor(pbh.Hostname) + if h != nil { + continue + } + // this is a new unknown droplet (not in the config file) + h = new(HyperT) + h.pb = pbh + + h.lastpoll = time.Now() + + me.hypers = append(me.hypers, h) + log.Log(EVENT, "config new hypervisors", h.pb.Hostname) + } + + // initialize values for each droplet + for _, pbd := range me.cluster.Droplets { + d := findDroplet(pbd.Hostname) + if d != nil { + continue + } + // this is a new unknown droplet (not in the config file) + d = new(DropletT) + d.pb = pbd + me.droplets = append(me.droplets, d) + log.Log(EVENT, "config new droplet", d.pb.Hostname, d.pb.StartState, d.pb.PreferredHypervisor) + } + + return nil +} + +func writeConfigFile() { + // Get the current time + now := time.Now() + + // Format the time to match your desired format: YYYY.MM.DD.HHMMSS + timestamp := now.Format("2006.01.02.150405") + + filename := "virtigo.json.new." + timestamp + if !writeConfigFileTmp(filename) { + log.Println("config file write error") + os.Exit(-1) + } + + origname := filepath.Join(os.Getenv("VIRTIGO_HOME"), "virtigo.json") + newname := filepath.Join(os.Getenv("VIRTIGO_HOME"), "virtigo.json.old") + err := os.Rename(origname, newname) + if err != nil { + log.Printf("rename fail: %s", err) + os.Exit(-1) + } + + if !writeConfigFileTmp("virtigo.json") { + log.Println("config file write error") + os.Exit(-1) + } +} + +func writeConfigFileTmp(filename string) bool { + fullname := filepath.Join(os.Getenv("VIRTIGO_HOME"), filename) + cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666) + defer cfgfile.Close() + if err != nil { + log.Info("open config file :", err) + return false + } + json := me.cluster.FormatJSON() + fmt.Fprintln(cfgfile, json) + log.Info("Write:", fullname, "OK") + return true +} + +func writeConfigFileDroplets() { + fullname := filepath.Join(os.Getenv("VIRTIGO_HOME"), "droplets.text") + cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666) + defer cfgfile.Close() + if err != nil { + log.Info("open config file :", err) + return + } + // text := me.cluster.Droplets.FormatTEXT() + text := me.cluster.FormatTEXT() + fmt.Fprintln(cfgfile, text) + log.Info("Write:", fullname, "OK") +} diff --git a/configfiles.go b/configfiles.go deleted file mode 100644 index 220db76..0000000 --- a/configfiles.go +++ /dev/null @@ -1,139 +0,0 @@ -package main - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "time" - - pb "go.wit.com/lib/protobuf/virtbuf" - "go.wit.com/log" -) - -var ErrorNoFile error = errors.New("missing file") -var ErrorParseJSON error = errors.New("invalid json") -var ErrorParseXML error = errors.New("invalid xml") - -// something is wrong somewhere and sometimes the -// protobuf json files get written out with garbage -func cfgfile() { - err := readConfigFile("virtigo.json") - if err == nil { - return - } - if err == ErrorParseJSON { - os.Exit(-1) - } - err = readConfigFile("virtigo.json.last") - if err == nil { - log.Info("read json failed", err) - os.Exit(-1) - } - if err == ErrorNoFile { - log.Info("no config file created yet", err) - os.Exit(-1) - } -} - -func readConfigFile(filename string) error { - me.cluster = new(pb.Cluster) - fullname := filepath.Join(os.Getenv("VIRTIGO_HOME"), filename) - pfile, err := os.ReadFile(fullname) - if err != nil { - log.Info("open config file :", err) - return err - } - err = me.cluster.UnmarshalJSON(pfile) - if err != nil { - log.Info("read json failed", err) - os.Exit(-1) - return err - } - - // initialize each hypervisor - for _, pbh := range me.cluster.Hypervisors { - h := findHypervisor(pbh.Hostname) - if h != nil { - continue - } - // this is a new unknown droplet (not in the config file) - h = new(HyperT) - h.pb = pbh - - h.lastpoll = time.Now() - - me.hypers = append(me.hypers, h) - log.Log(EVENT, "config new hypervisors", h.pb.Hostname) - } - - // initialize values for each droplet - for _, pbd := range me.cluster.Droplets { - d := findDroplet(pbd.Hostname) - if d != nil { - continue - } - // this is a new unknown droplet (not in the config file) - d = new(DropletT) - d.pb = pbd - me.droplets = append(me.droplets, d) - log.Log(EVENT, "config new droplet", d.pb.Hostname, d.pb.StartState, d.pb.PreferredHypervisor) - } - - return nil -} - -func writeConfigFile() { - // Get the current time - now := time.Now() - - // Format the time to match your desired format: YYYY.MM.DD.HHMMSS - timestamp := now.Format("2006.01.02.150405") - - filename := "virtigo.json.new." + timestamp - if !writeConfigFileTmp(filename) { - log.Println("config file write error") - os.Exit(-1) - } - - origname := filepath.Join(os.Getenv("VIRTIGO_HOME"), "virtigo.json") - newname := filepath.Join(os.Getenv("VIRTIGO_HOME"), "virtigo.json.old") - err := os.Rename(origname, newname) - if err != nil { - log.Printf("rename fail: %s", err) - os.Exit(-1) - } - - if !writeConfigFileTmp("virtigo.json") { - log.Println("config file write error") - os.Exit(-1) - } -} - -func writeConfigFileTmp(filename string) bool { - fullname := filepath.Join(os.Getenv("VIRTIGO_HOME"), filename) - cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666) - defer cfgfile.Close() - if err != nil { - log.Info("open config file :", err) - return false - } - json := me.cluster.FormatJSON() - fmt.Fprintln(cfgfile, json) - log.Info("Write:", fullname, "OK") - return true -} - -func writeConfigFileDroplets() { - fullname := filepath.Join(os.Getenv("VIRTIGO_HOME"), "droplets.text") - cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666) - defer cfgfile.Close() - if err != nil { - log.Info("open config file :", err) - return - } - // text := me.cluster.Droplets.FormatTEXT() - text := me.cluster.FormatTEXT() - fmt.Fprintln(cfgfile, text) - log.Info("Write:", fullname, "OK") -} diff --git a/main.go b/main.go index c942f27..7522435 100644 --- a/main.go +++ b/main.go @@ -24,9 +24,10 @@ func main() { fullpath := filepath.Join(homeDir, ".config/virtigo") os.Setenv("VIRTIGO_HOME", fullpath) } - pp := arg.MustParse(&argv) + var pp *arg.Parser + pp = arg.MustParse(&argv) - if !argv.Uptime { + if pp == nil { pp.WriteHelp(os.Stdout) os.Exit(0) } diff --git a/xml.go b/xml.go index b100b14..2584a54 100644 --- a/xml.go +++ b/xml.go @@ -96,6 +96,7 @@ func readXml(filename string) (*libvirtxml.Domain, error) { } if domcfg.Name != hostname { + log.Info("ERROR: filename:", filename) log.Info("ERROR: domcfg.Name != name", domcfg.Name, hostname) log.Info("ERROR: xml filenames must match the xml name") os.Exit(-1) -- cgit v1.2.3