diff options
| author | Jeff Carr <[email protected]> | 2025-04-21 08:16:32 -0500 | 
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2025-04-21 20:54:33 -0500 | 
| commit | 8eda4cf2da93f736512f2c8ec7f2cc13c47b1345 (patch) | |
| tree | abaa19334da8ab1d170013069f1d67cb76f885fe | |
| parent | 3cd1f64d15465160770794187ca632953fdd4c86 (diff) | |
add --daemon
| -rw-r--r-- | argv.go | 1 | ||||
| -rw-r--r-- | doDaemon.go | 154 | ||||
| -rw-r--r-- | doGui.go | 4 | ||||
| -rw-r--r-- | http.go | 2 | ||||
| -rw-r--r-- | main.go | 237 | 
5 files changed, 281 insertions, 117 deletions
@@ -15,6 +15,7 @@ type args struct {  	Droplet  *DropletCmd `arg:"subcommand:droplet"                   help:"send events to a droplet"`  	Config   string      `arg:"env:VIRTIGO_HOME"                     help:"defaults to ~/.config/virtigo/"`  	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"`  	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"` diff --git a/doDaemon.go b/doDaemon.go new file mode 100644 index 0000000..2a82b48 --- /dev/null +++ b/doDaemon.go @@ -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 +} @@ -130,6 +130,10 @@ func drawWindow(win *gadgets.GenericWindow) {  }  func updateUptimeGui(uptime string) { +	if me.status == nil { +		// gui is not initialized +		return +	}  	me.status.SetLabel(uptime)  	datestamp := time.Now().Format("2006-01-02 15:04:03") @@ -31,7 +31,7 @@ func okHandler(w http.ResponseWriter, r *http.Request) {  	}  	if route == "/uptime" {  		ok, s := uptimeCheck() -		fmt.Fprint(w, s) +		fmt.Fprintln(w, s)  		// log.Info(s)  		updateUptimeGui(s)  		if ok { @@ -4,17 +4,14 @@ package main  import (  	"embed" -	"fmt"  	"net/url"  	"os"  	"path/filepath" -	"time"  	"github.com/google/uuid"  	"go.wit.com/dev/alexflint/arg"  	"go.wit.com/gui"  	"go.wit.com/lib/protobuf/virtpb" -	"go.wit.com/lib/virtigolib"  	"go.wit.com/log"  ) @@ -101,143 +98,151 @@ func main() {  		me.admin.doAdminGui()  		okExit("admin close")  	} -	os.Exit(-1) -	// set defaults -	me.unstable = time.Now() // initialize the grid as unstable -	me.changed = false -	me.hmap = make(map[*virtpb.Hypervisor]*HyperT) +	/* +		// 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 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 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 +		// 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) -		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") +		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)  			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) -	} -	var newEvents []*virtpb.Event +		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) +			} +			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) +		} -	// 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.") -		os.Exit(0) -	} -	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() +		var newEvents []*virtpb.Event -	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") -			os.Exit(-1) +		// 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.") +			os.Exit(0)  		} -		// 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) +		newe, err := ValidateDiskFilenames()  		if err != nil { -			log.Info("addDomainDroplet() error", filename) -			log.Info("addDomainDroplet() error", err) -			log.Info("libvirt XML will have to be fixed by hand") +			log.Info(err)  			os.Exit(-1)  		} +		// this is a new droplet. add it to the cluster  		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 -	} +		ValidateUniqueFilenames() -	if me.changed { -		if err := me.cluster.ConfigSave(); err != nil { -			log.Info("configsave error", err) -			os.Exit(-1) +		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") +				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 +		} + +		if me.changed { +			if err := me.cluster.ConfigSave(); err != nil { +				log.Info("configsave error", err) +				os.Exit(-1) +			} +			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)  		} -		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 -	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() +		// 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) -	} +			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 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() -	} +			// 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) +		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) +		} +	*/ + +	if argv.Daemon { +		if err := doDaemon(); err != nil { +			badExit(err) +		} +		okExit("")  	}  	// sit here  | 
