add --daemon
This commit is contained in:
parent
3cd1f64d15
commit
8eda4cf2da
1
argv.go
1
argv.go
|
@ -15,6 +15,7 @@ type args struct {
|
||||||
Droplet *DropletCmd `arg:"subcommand:droplet" help:"send events to a droplet"`
|
Droplet *DropletCmd `arg:"subcommand:droplet" help:"send events to a droplet"`
|
||||||
Config string `arg:"env:VIRTIGO_HOME" help:"defaults to ~/.config/virtigo/"`
|
Config string `arg:"env:VIRTIGO_HOME" help:"defaults to ~/.config/virtigo/"`
|
||||||
Server string `arg:"env:VIRTIGO_SERVER" help:"what virtigo cluster to connect to"`
|
Server string `arg:"env:VIRTIGO_SERVER" help:"what virtigo cluster to connect to"`
|
||||||
|
Daemon bool `arg:"--daemon" help:"run as a daemon"`
|
||||||
Verbose bool `arg:"--verbose" help:"talk more"`
|
Verbose bool `arg:"--verbose" help:"talk more"`
|
||||||
Port int `arg:"--port" default:"8080" help:"allow droplet events via http"`
|
Port int `arg:"--port" default:"8080" help:"allow droplet events via http"`
|
||||||
Xml []string `arg:"--libvirt" help:"import qemu xml files: --libvirt /etc/libvirt/qemu/*.xml"`
|
Xml []string `arg:"--libvirt" help:"import qemu xml files: --libvirt /etc/libvirt/qemu/*.xml"`
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
// Copyright 2024 WIT.COM Inc Licensed GPL 3.0
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.wit.com/lib/protobuf/virtpb"
|
||||||
|
"go.wit.com/lib/virtigolib"
|
||||||
|
"go.wit.com/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func doDaemon() error {
|
||||||
|
// set defaults
|
||||||
|
me.unstable = time.Now() // initialize the grid as unstable
|
||||||
|
me.changed = false
|
||||||
|
me.hmap = make(map[*virtpb.Hypervisor]*HyperT)
|
||||||
|
|
||||||
|
// how long a droplet can be missing until it's declared dead
|
||||||
|
me.unstableTimeout = 17 * time.Second
|
||||||
|
me.missingDropletTimeout = time.Minute // not sure the difference between these values
|
||||||
|
|
||||||
|
// how often to poll the hypervisors
|
||||||
|
me.hyperPollDelay = 5 * time.Second
|
||||||
|
|
||||||
|
// how long the cluster must be stable before new droplets can be started
|
||||||
|
me.clusterStableDuration = 37 * time.Second
|
||||||
|
|
||||||
|
me.cluster = virtpb.InitCluster()
|
||||||
|
if err := me.cluster.ConfigLoad(); err != nil {
|
||||||
|
log.Info("config load error", err)
|
||||||
|
log.Info("")
|
||||||
|
log.Info("You have never run this before")
|
||||||
|
log.Info("init example cloud here")
|
||||||
|
log.Sleep(2)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
loop := me.cluster.DropletsAll() // get the list of droplets
|
||||||
|
for loop.Scan() {
|
||||||
|
d := loop.Next()
|
||||||
|
if d == nil {
|
||||||
|
fmt.Println("d == nil")
|
||||||
|
return fmt.Errorf("d == nil")
|
||||||
|
}
|
||||||
|
fmt.Println("Droplet UUID:", d.Uuid)
|
||||||
|
if d.Current == nil {
|
||||||
|
d.Current = new(virtpb.Current)
|
||||||
|
}
|
||||||
|
d.SetState(virtpb.DropletState_OFF)
|
||||||
|
log.Info("droplet", d.Hostname)
|
||||||
|
}
|
||||||
|
hmm := "pihole.wit.com"
|
||||||
|
d := me.cluster.FindDropletByName(hmm)
|
||||||
|
if d == nil {
|
||||||
|
log.Info("did not find found droplet", hmm)
|
||||||
|
} else {
|
||||||
|
log.Info("found droplet", d.Hostname, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
var newEvents []*virtpb.Event
|
||||||
|
|
||||||
|
// sanity check the cluster & droplets
|
||||||
|
if _, _, err := ValidateDroplets(); err != nil {
|
||||||
|
log.Info("todo: add flag to ignore. for now, fix problems in the config file.")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newe, err := ValidateDiskFilenames()
|
||||||
|
if err != nil {
|
||||||
|
log.Info(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// this is a new droplet. add it to the cluster
|
||||||
|
for _, e := range newe {
|
||||||
|
newEvents = append(newEvents, e)
|
||||||
|
}
|
||||||
|
ValidateUniqueFilenames()
|
||||||
|
|
||||||
|
for _, filename := range argv.Xml {
|
||||||
|
domcfg, err := virtigolib.ReadXml(filename)
|
||||||
|
if err != nil {
|
||||||
|
// parsing the libvirt xml file failed
|
||||||
|
log.Info("error:", filename, err)
|
||||||
|
log.Info("readXml() error", filename)
|
||||||
|
log.Info("readXml() error", err)
|
||||||
|
log.Info("libvirt XML will have to be fixed by hand")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// this is a new droplet. add it to the cluster
|
||||||
|
log.Info("Add XML Droplet here", domcfg.Name)
|
||||||
|
_, newe, err := virtigolib.AddDomainDroplet(me.cluster, domcfg)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("addDomainDroplet() error", filename)
|
||||||
|
log.Info("addDomainDroplet() error", err)
|
||||||
|
log.Info("libvirt XML will have to be fixed by hand")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, e := range newe {
|
||||||
|
newEvents = append(newEvents, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, e := range newEvents {
|
||||||
|
log.Info(i, "Event:", e.Droplet, e.FieldName, "orig:", e.OrigVal, "new:", e.NewVal)
|
||||||
|
me.changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if me.changed {
|
||||||
|
if err := me.cluster.ConfigSave(); err != nil {
|
||||||
|
log.Info("configsave error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info("XML changes saved in protobuf config")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if len(argv.Xml) != 0 {
|
||||||
|
log.Info("No XML changes found")
|
||||||
|
return fmt.Errorf("No XML changes found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize each hypervisor
|
||||||
|
for _, pbh := range me.cluster.H.Hypervisors {
|
||||||
|
// this is a new unknown droplet (not in the config file)
|
||||||
|
var h *HyperT
|
||||||
|
h = new(HyperT)
|
||||||
|
h.pb = pbh
|
||||||
|
h.lastDroplets = make(map[string]time.Time)
|
||||||
|
h.lastpoll = time.Now()
|
||||||
|
|
||||||
|
me.hmap[pbh] = h
|
||||||
|
me.hypers = append(me.hypers, h)
|
||||||
|
log.Log(EVENT, "config new hypervisors", h.pb.Hostname)
|
||||||
|
}
|
||||||
|
|
||||||
|
// start the watchdog polling for each hypervisor
|
||||||
|
for _, h := range me.hypers {
|
||||||
|
log.Info("starting polling on", h.pb.Hostname)
|
||||||
|
|
||||||
|
// start a watchdog on each hypervisor
|
||||||
|
go h.NewWatchdog()
|
||||||
|
}
|
||||||
|
|
||||||
|
var cloud *virtigolib.CloudManager
|
||||||
|
cloud = virtigolib.NewCloud()
|
||||||
|
found, _ := cloud.FindDropletByName("www.wit.com")
|
||||||
|
if found == nil {
|
||||||
|
log.Info("d == nil")
|
||||||
|
} else {
|
||||||
|
log.Info("d == ", found)
|
||||||
|
}
|
||||||
|
|
||||||
|
startHTTP()
|
||||||
|
return nil
|
||||||
|
}
|
4
doGui.go
4
doGui.go
|
@ -130,6 +130,10 @@ func drawWindow(win *gadgets.GenericWindow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUptimeGui(uptime string) {
|
func updateUptimeGui(uptime string) {
|
||||||
|
if me.status == nil {
|
||||||
|
// gui is not initialized
|
||||||
|
return
|
||||||
|
}
|
||||||
me.status.SetLabel(uptime)
|
me.status.SetLabel(uptime)
|
||||||
|
|
||||||
datestamp := time.Now().Format("2006-01-02 15:04:03")
|
datestamp := time.Now().Format("2006-01-02 15:04:03")
|
||||||
|
|
2
http.go
2
http.go
|
@ -31,7 +31,7 @@ func okHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
if route == "/uptime" {
|
if route == "/uptime" {
|
||||||
ok, s := uptimeCheck()
|
ok, s := uptimeCheck()
|
||||||
fmt.Fprint(w, s)
|
fmt.Fprintln(w, s)
|
||||||
// log.Info(s)
|
// log.Info(s)
|
||||||
updateUptimeGui(s)
|
updateUptimeGui(s)
|
||||||
if ok {
|
if ok {
|
||||||
|
|
237
main.go
237
main.go
|
@ -4,17 +4,14 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"fmt"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"go.wit.com/dev/alexflint/arg"
|
"go.wit.com/dev/alexflint/arg"
|
||||||
"go.wit.com/gui"
|
"go.wit.com/gui"
|
||||||
"go.wit.com/lib/protobuf/virtpb"
|
"go.wit.com/lib/protobuf/virtpb"
|
||||||
"go.wit.com/lib/virtigolib"
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -101,143 +98,151 @@ func main() {
|
||||||
me.admin.doAdminGui()
|
me.admin.doAdminGui()
|
||||||
okExit("admin close")
|
okExit("admin close")
|
||||||
}
|
}
|
||||||
os.Exit(-1)
|
|
||||||
|
|
||||||
// set defaults
|
/*
|
||||||
me.unstable = time.Now() // initialize the grid as unstable
|
// set defaults
|
||||||
me.changed = false
|
me.unstable = time.Now() // initialize the grid as unstable
|
||||||
me.hmap = make(map[*virtpb.Hypervisor]*HyperT)
|
me.changed = false
|
||||||
|
me.hmap = make(map[*virtpb.Hypervisor]*HyperT)
|
||||||
|
|
||||||
// how long a droplet can be missing until it's declared dead
|
// how long a droplet can be missing until it's declared dead
|
||||||
me.unstableTimeout = 17 * time.Second
|
me.unstableTimeout = 17 * time.Second
|
||||||
me.missingDropletTimeout = time.Minute // not sure the difference between these values
|
me.missingDropletTimeout = time.Minute // not sure the difference between these values
|
||||||
|
|
||||||
// how often to poll the hypervisors
|
// how often to poll the hypervisors
|
||||||
me.hyperPollDelay = 5 * time.Second
|
me.hyperPollDelay = 5 * time.Second
|
||||||
|
|
||||||
// how long the cluster must be stable before new droplets can be started
|
// how long the cluster must be stable before new droplets can be started
|
||||||
me.clusterStableDuration = 37 * time.Second
|
me.clusterStableDuration = 37 * time.Second
|
||||||
|
|
||||||
me.cluster = virtpb.InitCluster()
|
me.cluster = virtpb.InitCluster()
|
||||||
if err := me.cluster.ConfigLoad(); err != nil {
|
if err := me.cluster.ConfigLoad(); err != nil {
|
||||||
log.Info("config load error", err)
|
log.Info("config load error", err)
|
||||||
log.Info("")
|
log.Info("")
|
||||||
log.Info("You have never run this before")
|
log.Info("You have never run this before")
|
||||||
log.Info("init example cloud here")
|
log.Info("init example cloud here")
|
||||||
log.Sleep(2)
|
log.Sleep(2)
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
|
|
||||||
loop := me.cluster.DropletsAll() // get the list of droplets
|
|
||||||
for loop.Scan() {
|
|
||||||
d := loop.Next()
|
|
||||||
if d == nil {
|
|
||||||
fmt.Println("d == nil")
|
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
fmt.Println("Droplet UUID:", d.Uuid)
|
|
||||||
if d.Current == nil {
|
loop := me.cluster.DropletsAll() // get the list of droplets
|
||||||
d.Current = new(virtpb.Current)
|
for loop.Scan() {
|
||||||
|
d := loop.Next()
|
||||||
|
if d == nil {
|
||||||
|
fmt.Println("d == nil")
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
|
fmt.Println("Droplet UUID:", d.Uuid)
|
||||||
|
if d.Current == nil {
|
||||||
|
d.Current = new(virtpb.Current)
|
||||||
|
}
|
||||||
|
d.SetState(virtpb.DropletState_OFF)
|
||||||
|
log.Info("droplet", d.Hostname)
|
||||||
|
}
|
||||||
|
hmm := "pihole.wit.com"
|
||||||
|
d := me.cluster.FindDropletByName(hmm)
|
||||||
|
if d == nil {
|
||||||
|
log.Info("did not find found droplet", hmm)
|
||||||
|
} else {
|
||||||
|
log.Info("found droplet", d.Hostname, d)
|
||||||
}
|
}
|
||||||
d.SetState(virtpb.DropletState_OFF)
|
|
||||||
log.Info("droplet", d.Hostname)
|
|
||||||
}
|
|
||||||
hmm := "pihole.wit.com"
|
|
||||||
d := me.cluster.FindDropletByName(hmm)
|
|
||||||
if d == nil {
|
|
||||||
log.Info("did not find found droplet", hmm)
|
|
||||||
} else {
|
|
||||||
log.Info("found droplet", d.Hostname, d)
|
|
||||||
}
|
|
||||||
|
|
||||||
var newEvents []*virtpb.Event
|
var newEvents []*virtpb.Event
|
||||||
|
|
||||||
// sanity check the cluster & droplets
|
// sanity check the cluster & droplets
|
||||||
if _, _, err := ValidateDroplets(); err != nil {
|
if _, _, err := ValidateDroplets(); err != nil {
|
||||||
log.Info("todo: add flag to ignore. for now, fix problems in the config file.")
|
log.Info("todo: add flag to ignore. for now, fix problems in the config file.")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
newe, err := ValidateDiskFilenames()
|
newe, err := ValidateDiskFilenames()
|
||||||
if err != nil {
|
|
||||||
log.Info(err)
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
// this is a new droplet. add it to the cluster
|
|
||||||
for _, e := range newe {
|
|
||||||
newEvents = append(newEvents, e)
|
|
||||||
}
|
|
||||||
ValidateUniqueFilenames()
|
|
||||||
|
|
||||||
for _, filename := range argv.Xml {
|
|
||||||
domcfg, err := virtigolib.ReadXml(filename)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// parsing the libvirt xml file failed
|
log.Info(err)
|
||||||
log.Info("error:", filename, err)
|
|
||||||
log.Info("readXml() error", filename)
|
|
||||||
log.Info("readXml() error", err)
|
|
||||||
log.Info("libvirt XML will have to be fixed by hand")
|
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
// this is a new droplet. add it to the cluster
|
// this is a new droplet. add it to the cluster
|
||||||
log.Info("Add XML Droplet here", domcfg.Name)
|
|
||||||
_, newe, err := virtigolib.AddDomainDroplet(me.cluster, domcfg)
|
|
||||||
if err != nil {
|
|
||||||
log.Info("addDomainDroplet() error", filename)
|
|
||||||
log.Info("addDomainDroplet() error", err)
|
|
||||||
log.Info("libvirt XML will have to be fixed by hand")
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
for _, e := range newe {
|
for _, e := range newe {
|
||||||
newEvents = append(newEvents, e)
|
newEvents = append(newEvents, e)
|
||||||
}
|
}
|
||||||
}
|
ValidateUniqueFilenames()
|
||||||
for i, e := range newEvents {
|
|
||||||
log.Info(i, "Event:", e.Droplet, e.FieldName, "orig:", e.OrigVal, "new:", e.NewVal)
|
|
||||||
me.changed = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if me.changed {
|
for _, filename := range argv.Xml {
|
||||||
if err := me.cluster.ConfigSave(); err != nil {
|
domcfg, err := virtigolib.ReadXml(filename)
|
||||||
log.Info("configsave error", err)
|
if err != nil {
|
||||||
os.Exit(-1)
|
// parsing the libvirt xml file failed
|
||||||
|
log.Info("error:", filename, err)
|
||||||
|
log.Info("readXml() error", filename)
|
||||||
|
log.Info("readXml() error", err)
|
||||||
|
log.Info("libvirt XML will have to be fixed by hand")
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
|
// this is a new droplet. add it to the cluster
|
||||||
|
log.Info("Add XML Droplet here", domcfg.Name)
|
||||||
|
_, newe, err := virtigolib.AddDomainDroplet(me.cluster, domcfg)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("addDomainDroplet() error", filename)
|
||||||
|
log.Info("addDomainDroplet() error", err)
|
||||||
|
log.Info("libvirt XML will have to be fixed by hand")
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
|
for _, e := range newe {
|
||||||
|
newEvents = append(newEvents, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, e := range newEvents {
|
||||||
|
log.Info(i, "Event:", e.Droplet, e.FieldName, "orig:", e.OrigVal, "new:", e.NewVal)
|
||||||
|
me.changed = true
|
||||||
}
|
}
|
||||||
log.Info("XML changes saved in protobuf config")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
if len(argv.Xml) != 0 {
|
|
||||||
log.Info("No XML changes found")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize each hypervisor
|
if me.changed {
|
||||||
for _, pbh := range me.cluster.H.Hypervisors {
|
if err := me.cluster.ConfigSave(); err != nil {
|
||||||
// this is a new unknown droplet (not in the config file)
|
log.Info("configsave error", err)
|
||||||
var h *HyperT
|
os.Exit(-1)
|
||||||
h = new(HyperT)
|
}
|
||||||
h.pb = pbh
|
log.Info("XML changes saved in protobuf config")
|
||||||
h.lastDroplets = make(map[string]time.Time)
|
os.Exit(0)
|
||||||
h.lastpoll = time.Now()
|
}
|
||||||
|
if len(argv.Xml) != 0 {
|
||||||
|
log.Info("No XML changes found")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
me.hmap[pbh] = h
|
// initialize each hypervisor
|
||||||
me.hypers = append(me.hypers, h)
|
for _, pbh := range me.cluster.H.Hypervisors {
|
||||||
log.Log(EVENT, "config new hypervisors", h.pb.Hostname)
|
// this is a new unknown droplet (not in the config file)
|
||||||
}
|
var h *HyperT
|
||||||
|
h = new(HyperT)
|
||||||
|
h.pb = pbh
|
||||||
|
h.lastDroplets = make(map[string]time.Time)
|
||||||
|
h.lastpoll = time.Now()
|
||||||
|
|
||||||
// start the watchdog polling for each hypervisor
|
me.hmap[pbh] = h
|
||||||
for _, h := range me.hypers {
|
me.hypers = append(me.hypers, h)
|
||||||
log.Info("starting polling on", h.pb.Hostname)
|
log.Log(EVENT, "config new hypervisors", h.pb.Hostname)
|
||||||
|
}
|
||||||
|
|
||||||
// start a watchdog on each hypervisor
|
// start the watchdog polling for each hypervisor
|
||||||
go h.NewWatchdog()
|
for _, h := range me.hypers {
|
||||||
}
|
log.Info("starting polling on", h.pb.Hostname)
|
||||||
|
|
||||||
var cloud *virtigolib.CloudManager
|
// start a watchdog on each hypervisor
|
||||||
cloud = virtigolib.NewCloud()
|
go h.NewWatchdog()
|
||||||
found, _ := cloud.FindDropletByName("www.wit.com")
|
}
|
||||||
if found == nil {
|
|
||||||
log.Info("d == nil")
|
var cloud *virtigolib.CloudManager
|
||||||
} else {
|
cloud = virtigolib.NewCloud()
|
||||||
log.Info("d == ", found)
|
found, _ := cloud.FindDropletByName("www.wit.com")
|
||||||
|
if found == nil {
|
||||||
|
log.Info("d == nil")
|
||||||
|
} else {
|
||||||
|
log.Info("d == ", found)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if argv.Daemon {
|
||||||
|
if err := doDaemon(); err != nil {
|
||||||
|
badExit(err)
|
||||||
|
}
|
||||||
|
okExit("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// sit here
|
// sit here
|
||||||
|
|
Loading…
Reference in New Issue