start migration to protobufs

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-10-22 17:27:24 -05:00
parent 3b64d342d2
commit 673bcc6cc9
8 changed files with 63 additions and 62 deletions

View File

@ -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
}

View File

@ -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

12
http.go
View File

@ -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
//}

View File

@ -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()
}

38
poll.go
View File

@ -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 = "("

View File

@ -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
}

View File

@ -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()
}
}

4
xml.go
View File

@ -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
}