From e94b4d6626fafb20da118eb8b17e661928c2b5da Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Sat, 12 Oct 2024 12:45:43 -0500 Subject: [PATCH] first basic check to tell if the cluster is healthy Signed-off-by: Jeff Carr --- configfiles.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ http.go | 29 +++++++++++++++++++++++++++-- main.go | 2 ++ poll.go | 36 +++++++++++++++++++++--------------- structs.go | 10 ++++++---- 5 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 configfiles.go diff --git a/configfiles.go b/configfiles.go new file mode 100644 index 0000000..b7999c5 --- /dev/null +++ b/configfiles.go @@ -0,0 +1,46 @@ +package main + +import ( + "os" + "path/filepath" + "strings" + + "go.wit.com/log" +) + +func readConfigFile(filename string) { + // fmt.Fprintln(w, "GOT TEST?") + homeDir, _ := os.UserHomeDir() + fullname := filepath.Join(homeDir, ".config/virtigo/", filename) + pfile, err := os.ReadFile(fullname) + if err != nil { + log.Info("No config file :", err) + // w.Write(pfile) + return + } + + f := string(pfile) + for _, line := range strings.Split(f, "\n") { + fields := strings.Fields(line) + if len(fields) < 1 { + continue + } + name := fields[0] + d := findDroplet(name) + if d == nil { + // this is a new unknown droplet (not in the config file) + d = new(DropletT) + d.Hostname = name + if len(fields) < 2 || fields[1] != "ON" { + d.State = "OFF" + } else { + d.State = "ON" + } + me.droplets = append(me.droplets, d) + log.Log(EVENT, "NEW CONFIG DROPLET", d.Hostname, d.State) + } else { + log.Info("not sure what to do here. duplicate", name, "in config file") + } + + } +} diff --git a/http.go b/http.go index e4c9401..772d358 100644 --- a/http.go +++ b/http.go @@ -6,8 +6,8 @@ import ( "strings" "time" - "go.wit.com/log" "go.wit.com/lib/gui/shell" + "go.wit.com/log" ) // remove '?' part and trailing '/' @@ -30,7 +30,8 @@ func okHandler(w http.ResponseWriter, r *http.Request) { return } - if tmp == "/vms" { + // list all the droplets + if tmp == "/droplets" { for _, d := range me.droplets { dur := time.Since(d.lastpoll) // Calculate the elapsed time fmt.Fprintln(w, d.Hostname, d.hname, shell.FormatDuration(dur)) @@ -38,6 +39,30 @@ func okHandler(w http.ResponseWriter, r *http.Request) { return } + // is the cluster running what it should? + if tmp == "/good" { + var good = true + for _, d := range me.droplets { + if d.State != "ON" { + continue + } + dur := time.Since(d.lastpoll) // Calculate the elapsed time + if d.CurrentState != "ON" { + fmt.Fprintln(w, "BAD STATE ", d.Hostname, "State =", d.State, "CurrentState =", d.CurrentState, shell.FormatDuration(dur)) + good = false + } else { + dur := time.Since(d.lastpoll) // Calculate the elapsed time + fmt.Fprintln(w, "GOOD STATE ON", d.Hostname, d.hname, shell.FormatDuration(dur)) + } + } + if good { + fmt.Fprintln(w, "GOOD=true") + } else { + fmt.Fprintln(w, "GOOD=false") + } + return + } + if tmp == "/favicon.ico" { writeFile(w, "ipv6.png") return diff --git a/main.go b/main.go index d04d9eb..0964846 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,8 @@ func main() { os.Exit(0) } + readConfigFile("droplets") + log.Info("create cluser for", argv.Hosts) for _, s := range argv.Hosts { me.names = append(me.names, s) diff --git a/poll.go b/poll.go index 5e9fdb0..e0a8a28 100644 --- a/poll.go +++ b/poll.go @@ -10,7 +10,7 @@ import ( func (h HyperT) pollHypervisor() { url := "http://" + h.Hostname + ":2520/vms" - log.Log(INFO, "wget url =", url) + log.Log(POLL, "wget url =", url) s := shell.Wget(url) if s == nil { return @@ -30,30 +30,36 @@ func (h HyperT) pollHypervisor() { name := fields[1] if state == "ON" { log.Log(POLL, h.Hostname, "STATE:", state, "HOST:", name, "rest:", fields[2:]) - var found = false - for _, d := range me.droplets { - if d.Hostname == name { - log.Log(INFO, "ALREADY RECORDED", d.Hostname) - found = true - d.lastpoll = time.Now() - // log.Info("ALREADY RECORDED", d.Hostname, d.lastpoll) - if d.hname != h.Hostname { - log.Log(EVENT, "DROPLET", d.Hostname, "MOVED FROM", d.hname, "TO", d.Hostname) - } - + d := findDroplet(name) + if d != nil { + log.Log(INFO, "ALREADY RECORDED", d.Hostname) + d.lastpoll = time.Now() + d.CurrentState = "ON" + // log.Info("ALREADY RECORDED", d.Hostname, d.lastpoll) + if d.hname != h.Hostname { + log.Log(EVENT, "DROPLET", d.Hostname, "MOVED FROM", d.hname, "TO", d.Hostname) d.hname = h.Hostname } - } - if found { continue } - var d = new(DropletT) + // this is a new unknown droplet (not in the config file) + d = new(DropletT) d.Hostname = name d.hname = h.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.Info("i, s =", hostname, i, s) } + +func findDroplet(name string) *DropletT { + for _, d := range me.droplets { + if d.Hostname == name { + return d + } + } + return nil +} diff --git a/structs.go b/structs.go index c747661..e39b8ce 100644 --- a/structs.go +++ b/structs.go @@ -32,8 +32,10 @@ type HyperT struct { // 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) - 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 + Hostname string // the name of the virtual machine. should be unique (probably enforce this forever) + State string // what the state of the droplet is SUPPOSED TO BE + CurrentState string // what the state of the droplet is ACTUALLY IS + 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 }