diff --git a/configfiles.go b/configfiles.go index 58d83aa..927f328 100644 --- a/configfiles.go +++ b/configfiles.go @@ -11,10 +11,8 @@ import ( "go.wit.com/log" ) -var cluster *pb.Cluster - func readConfigFile() { - cluster = new(pb.Cluster) + me.cluster = new(pb.Cluster) homeDir, _ := os.UserHomeDir() fullname := filepath.Join(homeDir, ".config/virtigo.json") pfile, err := os.ReadFile(fullname) @@ -22,7 +20,7 @@ func readConfigFile() { log.Info("open config file :", err) return } - err = cluster.UnmarshalJSON(pfile) + err = me.cluster.UnmarshalJSON(pfile) if err != nil { log.Info("create json failed", err) return @@ -37,7 +35,7 @@ func writeConfigFile() { log.Info("open config file :", err) return } - json := cluster.FormatJSON() + json := me.cluster.FormatJSON() fmt.Fprintln(cfgfile, json) } @@ -63,7 +61,6 @@ func readDropletFile(filename string) { if d == nil { // this is a new unknown droplet (not in the config file) d = new(DropletT) - d.Hostname = name if len(fields) > 1 && fields[1] != "ON" { d.ConfigState = "OFF" } else { @@ -72,9 +69,9 @@ func readDropletFile(filename string) { if len(fields) >= 3 { d.hyperPreferred = fields[2] } + d.pb = me.cluster.AddDroplet(name, 16, 256) me.droplets = append(me.droplets, d) - log.Log(EVENT, "config new droplet", d.Hostname, d.ConfigState, d.hyperPreferred) - cluster.AddDroplet(d.Hostname, 16, 256) + log.Log(EVENT, "config new droplet", d.pb.Hostname, d.ConfigState, d.hyperPreferred) } else { log.Info("not sure what to do here. duplicate droplet", name, "in config file") } @@ -118,14 +115,13 @@ func addHypervisor(name string) *HyperT { } log.Log(EVENT, "config new hypervisor", name) h = new(HyperT) - h.Hostname = name h.Autoscan = true h.Delay = 5 * time.Second h.lastpoll = time.Now() h.Scan = func() { h.pollHypervisor() } + h.pb = me.cluster.AddHypervisor(name, 16, 256) me.hypers = append(me.hypers, h) - cluster.AddHypervisor(name, 16, 256) return h } diff --git a/event.go b/event.go index 5c26b5d..05f8c7f 100644 --- a/event.go +++ b/event.go @@ -14,14 +14,14 @@ func (d *DropletT) Start() { } func (h *HyperT) RestartDaemon() { - url := "http://" + h.Hostname + ":2520/kill" + url := "http://" + h.pb.Hostname + ":2520/kill" s := shell.Wget(url) log.Info("EVENT RestartDaemon", url, s) h.lastpoll = time.Now() h.killcount += 1 dur := time.Since(h.lastpoll) // Calculate the elapsed time - log.Info("KILLED DAEMON", h.Hostname, shell.FormatDuration(dur), "curl", url) + log.Info("KILLED DAEMON", h.pb.Hostname, shell.FormatDuration(dur), "curl", url) me.killcount += 1 // mark the cluster as unstable so droplet starts can be throttled @@ -63,7 +63,7 @@ func (h *HyperT) Start(d *DropletT) (bool, string) { return false, result } - url := "http://" + h.Hostname + ":2520/start?start=" + d.Hostname + url := "http://" + h.pb.Hostname + ":2520/start?start=" + d.pb.Hostname s := shell.Wget(url) result = "EVENT start droplet url: " + url + "\n" result += "EVENT start droplet response: " + s.String() @@ -100,8 +100,8 @@ func Start(name string) (bool, string) { // make the list of hypervisors that are active and can start new droplets var pool []*HyperT for _, h := range me.hypers { - result += fmt.Sprintln("could start droplet on", name, "on", h.Hostname, h.Active) - if d.hyperPreferred == h.Hostname { + result += fmt.Sprintln("could start droplet on", name, "on", h.pb.Hostname, h.Active) + if d.hyperPreferred == h.pb.Hostname { // the config file says this droplet should run on this hypervisor a, b := h.Start(d) return a, result + b diff --git a/http.go b/http.go index 81266cc..158d346 100644 --- a/http.go +++ b/http.go @@ -28,10 +28,10 @@ func okHandler(w http.ResponseWriter, r *http.Request) { } dur := time.Since(d.lastpoll) // Calculate the elapsed time if d.CurrentState != "ON" { - fmt.Fprintln(w, "BAD STATE ", d.Hostname, d.hname, "(", d.ConfigState, "vs", d.CurrentState, ")", shell.FormatDuration(dur)) + fmt.Fprintln(w, "BAD STATE ", d.pb.Hostname, d.hname, "(", d.ConfigState, "vs", d.CurrentState, ")", shell.FormatDuration(dur)) } else { dur := time.Since(d.lastpoll) // Calculate the elapsed time - fmt.Fprintln(w, "GOOD STATE ON", d.Hostname, d.hname, shell.FormatDuration(dur)) + fmt.Fprintln(w, "GOOD STATE ON", d.pb.Hostname, d.hname, shell.FormatDuration(dur)) } } return @@ -51,20 +51,20 @@ func okHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, s) } for _, h := range me.hypers { - url := "http://" + h.Hostname + ":2520/kill" + url := "http://" + h.pb.Hostname + ":2520/kill" dur := time.Since(h.lastpoll) // Calculate the elapsed time if dur > 90*time.Second { h.RestartDaemon() continue } if h.killcount != 0 { - log.Info("KILL count =", h.killcount, "FOR", h.Hostname, dur, "curl", url) + log.Info("KILL count =", h.killcount, "FOR", h.pb.Hostname, dur, "curl", url) } if h.killcount > 10 { - log.Info("KILL count is greater than 10 for host", h.Hostname, dur, "curl", url) + log.Info("KILL count is greater than 10 for host", h.pb.Hostname, dur, "curl", url) } // l := shell.FormatDuration(dur) - // log.Warn("HOST =", h.Hostname, "Last poll =", l) + // log.Warn("HOST =", h.pb.Hostname, "Last poll =", l) //if d.ConfigState != "ON" { // continue //} diff --git a/main.go b/main.go index 8ffc1ae..a1de774 100644 --- a/main.go +++ b/main.go @@ -54,7 +54,7 @@ func main() { log.Info("droplet is unknown:", argv.Start) os.Exit(0) } - log.Info("start droplet here:", d.Hostname) + log.Info("start droplet here:", d.pb.Hostname) domcfg := makeStandardXml(d) fmt.Printf("Virt type %s\n", domcfg.Type) @@ -78,7 +78,7 @@ func main() { macs = getMacs(domcfg) fmt.Printf("Virt mac addr:%s\n", macs) - qcow := "/home/nfs/" + d.Hostname + ".qcow2" + qcow := "/home/nfs/" + d.pb.Hostname + ".qcow2" setSimpleDisk(domcfg, qcow) writeoutXml(domcfg, "blahcarr") @@ -87,7 +87,7 @@ func main() { // start the watchdog polling for each hypervisor for _, h := range me.hypers { - log.Info("starting polling on", h.Hostname) + log.Info("starting polling on", h.pb.Hostname) go h.NewWatchdog() } diff --git a/poll.go b/poll.go index 276332b..cf39378 100644 --- a/poll.go +++ b/poll.go @@ -10,7 +10,7 @@ import ( ) func (h *HyperT) pollHypervisor() { - url := "http://" + h.Hostname + ":2520/vms" + url := "http://" + h.pb.Hostname + ":2520/vms" log.Log(POLL, "wget url =", url) s := shell.Wget(url) if s == nil { @@ -30,26 +30,26 @@ func (h *HyperT) pollHypervisor() { state := fields[0] name := fields[1] if state == "ON" { - log.Log(POLL, h.Hostname, "STATE:", state, "HOST:", name, "rest:", fields[2:]) + log.Log(POLL, h.pb.Hostname, "STATE:", state, "HOST:", name, "rest:", fields[2:]) d := findDroplet(name) if d == nil { // this is a new unknown droplet (not in the config file) d = new(DropletT) - d.Hostname = name - d.hname = h.Hostname + d.pb.Hostname = name + d.hname = h.pb.Hostname d.lastpoll = time.Now() d.CurrentState = "ON" me.droplets = append(me.droplets, d) - log.Log(EVENT, name, "IS NEW. ADDED ON", h.Hostname) + log.Log(EVENT, name, "IS NEW. ADDED ON", h.pb.Hostname) } - log.Log(INFO, "ALREADY RECORDED", d.Hostname) + log.Log(INFO, "ALREADY RECORDED", d.pb.Hostname) // update the status to ON and the last polled value d.CurrentState = "ON" d.lastpoll = time.Now() // this means the droplet is still where it was before - if d.hname == h.Hostname { + if d.hname == h.pb.Hostname { continue } @@ -58,15 +58,15 @@ func (h *HyperT) pollHypervisor() { // but this is the first time it's shown up as running // this should mean a droplet is running where the config file says it probably should be running - if d.hyperPreferred == h.Hostname { - log.Log(EVENT, "new droplet", d.Hostname, "(matches config hypervisor", h.Hostname+")") - d.hname = h.Hostname + if d.hyperPreferred == h.pb.Hostname { + log.Log(EVENT, "new droplet", d.pb.Hostname, "(matches config hypervisor", h.pb.Hostname+")") + d.hname = h.pb.Hostname continue } - log.Log(EVENT, "new droplet", d.Hostname, "on", h.Hostname, "(in config file without preferred hypervisor)") + log.Log(EVENT, "new droplet", d.pb.Hostname, "on", h.pb.Hostname, "(in config file without preferred hypervisor)") } - d.hname = h.Hostname + d.hname = h.pb.Hostname } continue } @@ -76,7 +76,7 @@ func (h *HyperT) pollHypervisor() { func findDroplet(name string) *DropletT { for _, d := range me.droplets { - if d.Hostname == name { + if d.pb.Hostname == name { return d } } @@ -85,7 +85,7 @@ func findDroplet(name string) *DropletT { func findHypervisor(name string) *HyperT { for _, h := range me.hypers { - if h.Hostname == name { + if h.pb.Hostname == name { return h } } @@ -110,19 +110,19 @@ func clusterHealthy() (bool, string) { } dur := time.Since(d.lastpoll) // Calculate the elapsed time if d.CurrentState == "" { - // log.Info("SKIP. hostname has not been polled yet", d.Hostname, d.hname) + // log.Info("SKIP. hostname has not been polled yet", d.pb.Hostname, d.hname) unknown += 1 - unknownList = append(unknownList, d.Hostname) + unknownList = append(unknownList, d.pb.Hostname) continue } if d.CurrentState != "ON" { - log.Info("BAD STATE", d.ConfigState, d.Hostname, d.hname, "CurrentState =", d.CurrentState, shell.FormatDuration(dur)) + log.Info("BAD STATE", d.ConfigState, d.pb.Hostname, d.hname, "CurrentState =", d.CurrentState, shell.FormatDuration(dur)) good = false failed += 1 } else { dur := time.Since(d.lastpoll) // Calculate the elapsed time if dur > time.Minute { - log.Info("GOOD STATE MISSING", d.Hostname, d.hname, shell.FormatDuration(dur)) + log.Info("GOOD STATE MISSING", d.pb.Hostname, d.hname, shell.FormatDuration(dur)) good = false d.CurrentState = "MISSING" failed += 1 @@ -135,7 +135,7 @@ func clusterHealthy() (bool, string) { continue } working += 1 - // log.Info("GOOD STATE ON", d.Hostname, d.hname, "dur =", l) + // log.Info("GOOD STATE ON", d.pb.Hostname, d.hname, "dur =", l) } } var summary string = "(" diff --git a/structs.go b/structs.go index 3128810..d67f7c0 100644 --- a/structs.go +++ b/structs.go @@ -1,6 +1,10 @@ package main -import "time" +import ( + "time" + + pb "go.wit.com/lib/protobuf/virtbuf" +) var me virtigoT @@ -16,6 +20,7 @@ func (b *virtigoT) Enable() { // this app's variables type virtigoT struct { + cluster *pb.Cluster names []string hypers []*HyperT droplets []*DropletT @@ -25,24 +30,24 @@ type virtigoT struct { // the stuff that is needed for a hypervisor type HyperT struct { - Hostname string // the hypervisor hostname - Active bool // is allowed to start new droplets - Scan func() // the function to run to scan the hypervisor - Autoscan bool // to scan or not to scan - Delay time.Duration // how often to poll the hypervisor - Dog *time.Ticker // the watchdog timer itself - lastpoll time.Time // the last time the hypervisor polled + pb *pb.Hypervisor // the Hypervisor protobuf + Active bool // is allowed to start new droplets + Scan func() // the function to run to scan the hypervisor + Autoscan bool // to scan or not to scan + Delay time.Duration // how often to poll the hypervisor + Dog *time.Ticker // the watchdog timer itself + lastpoll time.Time // the last time the hypervisor polled killcount int } // the stuff that is needed for a hypervisor type DropletT struct { - Hostname string // the name of the virtual machine. should be unique (probably enforce this forever) - ConfigState string // what the state of the droplet is SUPPOSED TO BE - CurrentState string // what the state of the droplet is ACTUALLY IS - hyperPreferred string // the hypervisor to prefer to run the droplet on - hname string // the hypervisor it's currently running on - h *HyperT // the hypervisor it's currently running on - lastpoll time.Time // the last time the droplet was seen running - starts int // how many times a start event has been attempted + pb *pb.Droplet // the Droplet protobuf + ConfigState string // what the state of the droplet is SUPPOSED TO BE + CurrentState string // what the state of the droplet is ACTUALLY IS + hyperPreferred string // the hypervisor to prefer to run the droplet on + hname string // the hypervisor it's currently running on + h *HyperT // the hypervisor it's currently running on + lastpoll time.Time // the last time the droplet was seen running + starts int // how many times a start event has been attempted } diff --git a/watchdog.go b/watchdog.go index df32b8d..b778ea4 100644 --- a/watchdog.go +++ b/watchdog.go @@ -31,7 +31,7 @@ func (h *HyperT) NewWatchdog() { fmt.Println("Done!") return case t := <-h.Dog.C: - log.Log(POLL, "Watchdog() ticked", h.Hostname, "Current time: ", t) + log.Log(POLL, "Watchdog() ticked", h.pb.Hostname, "Current time: ", t) h.Scan() } } diff --git a/xml.go b/xml.go index 3fc012f..04c3076 100644 --- a/xml.go +++ b/xml.go @@ -11,7 +11,7 @@ import ( ) func makeStandardXml(d *DropletT) *libvirtxml.Domain { - log.Info("create new xml file for:", d.Hostname) + log.Info("create new xml file for:", d.pb.Hostname) domcfg := &libvirtxml.Domain{} addDefaults(domcfg, "standard.x86") @@ -19,7 +19,7 @@ func makeStandardXml(d *DropletT) *libvirtxml.Domain { addDefaults(domcfg, "network") addDefaults(domcfg, "spice") addDefaults(domcfg, "qcow") - addDefaults(domcfg, d.Hostname) + addDefaults(domcfg, d.pb.Hostname) return domcfg }