summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2024-10-15 11:02:34 -0500
committerJeff Carr <[email protected]>2024-10-15 11:02:34 -0500
commit1c77ec7e63355cab48564a9fb49f34f55b5f0b15 (patch)
tree8d081863ea226465827f9d266b0e701da216220e
parentaa6b142b7c156b8f1925eb4af10b0b371263a129 (diff)
start from the command line works
Signed-off-by: Jeff Carr <[email protected]>
-rw-r--r--Makefile3
-rw-r--r--configfiles.go7
-rw-r--r--event.go42
-rw-r--r--http.go26
-rw-r--r--poll.go4
-rw-r--r--structs.go14
6 files changed, 84 insertions, 12 deletions
diff --git a/Makefile b/Makefile
index 3443eda..ad8f8b2 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,8 @@ all:
./virtigo --hosts farm01 farm02 farm03
start:
- curl --silent http://localhost:8080/start?start=jcarr
+ curl --silent http://localhost:8080/start?start=rdate.wit.com
+ @#curl --silent http://localhost:8080/start?start=jcarr
@# ./virtigo --start jcarr
curl-uptime:
diff --git a/configfiles.go b/configfiles.go
index b23cb0d..1bdf153 100644
--- a/configfiles.go
+++ b/configfiles.go
@@ -32,13 +32,16 @@ func readDropletFile(filename string) {
// this is a new unknown droplet (not in the config file)
d = new(DropletT)
d.Hostname = name
- if len(fields) < 2 || fields[1] != "ON" {
+ if len(fields) > 1 && fields[1] != "ON" {
d.State = "OFF"
} else {
d.State = "ON"
}
+ if len(fields) >= 3 {
+ d.hyperPreferred = fields[2]
+ }
me.droplets = append(me.droplets, d)
- log.Log(EVENT, "NEW CONFIG DROPLET", d.Hostname, d.State)
+ log.Log(EVENT, "NEW CONFIG DROPLET", d.Hostname, d.State, d.hyperPreferred)
} else {
log.Info("not sure what to do here. duplicate droplet", name, "in config file")
}
diff --git a/event.go b/event.go
index ee4bef0..2956b0e 100644
--- a/event.go
+++ b/event.go
@@ -23,8 +23,46 @@ func (h *HyperT) RestartDaemon() {
me.killcount += 1
}
+// checks if the cluster is ready and stable
+func clusterReady() bool {
+ last := time.Since(me.unstable)
+ if last > 133*time.Second {
+ // the cluster has not been stable for 133 seconds
+ log.Warn("clusterReady() is stable for 133s")
+ return true
+ }
+ log.Warn("clusterReady() is unstable for", shell.FormatDuration(last))
+ return false
+}
+
+func (d *DropletT) dropletReady() bool {
+ if d.CurrentState == "ON" {
+ log.Warn("EVENT start droplet is already ON")
+ return false
+ }
+ if d.starts > 2 {
+ log.Warn("EVENT start droplet has already been started", d.starts, "times")
+ return false
+ }
+ return true
+}
+
func (h *HyperT) Start(d *DropletT) {
- url := "http://" + h.Hostname + ":2520/start?" + d.Hostname
+ if ! clusterReady() {
+ return
+ }
+ if ! d.dropletReady() {
+ return
+ }
+
+ url := "http://" + h.Hostname + ":2520/start?start=" + d.Hostname
s := shell.Wget(url)
- log.Info("EVENT start droplet", url, s)
+ log.Warn("EVENT start droplet url:", url)
+ log.Warn("EVENT start droplet response:", s)
+
+ // increment the counter for a start attempt working
+ d.starts += 1
+
+ // mark the cluster as unstable so droplet starts can be throttled
+ me.unstable = time.Now()
}
diff --git a/http.go b/http.go
index 5f5297a..e998203 100644
--- a/http.go
+++ b/http.go
@@ -2,6 +2,7 @@ package main
import (
"fmt"
+ "math/rand"
"net/http"
"strings"
"time"
@@ -98,10 +99,35 @@ func okHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "can't start unknown droplet", start)
return
}
+
+ // make the list of hypervisors that are active and can start new droplets
+ var pool []*HyperT
for _, h := range me.hypers {
fmt.Fprintln(w, "could start droplet on", start, "on", h.Hostname, h.Active)
+ if d.hyperPreferred == h.Hostname {
+ // the config file says this droplet should run on this hypervisor
+ h.Start(d)
+ return
+ }
+ if h.Active != true {
+ continue
+ }
+ pool = append(pool, h)
}
+ // left here as an example of how to actually do random numbers
+ // it's complete mathematical chaos. Randomness is simple when
+ // human interaction occurs -- which is exactly what happens most
+ // of the time. most random shit is bullshit. all you really need
+ // is exactly this to make sure the random functions work as they
+ // should. Probably, just use this everywhere in all cases. --jcarr
+ rand.Seed(time.Now().UnixNano())
+ a := 0
+ b := len(pool)
+ n := a + rand.Intn(b-a)
+ fmt.Fprintln(w, "pool has", len(pool), "members", "rand =", n)
+ h := pool[n]
+ h.Start(d)
return
}
diff --git a/poll.go b/poll.go
index 1497509..bc3ea49 100644
--- a/poll.go
+++ b/poll.go
@@ -87,6 +87,7 @@ func clusterHealthy() (bool, string) {
var failed int
var missing int
var unknown int
+ var unknownList []string
for _, d := range me.droplets {
total += 1
@@ -97,6 +98,7 @@ func clusterHealthy() (bool, string) {
if d.CurrentState == "" {
// log.Info("SKIP. hostname has not been polled yet", d.Hostname, d.hname)
unknown += 1
+ unknownList = append(unknownList, d.Hostname)
continue
}
if d.CurrentState != "ON" {
@@ -129,7 +131,7 @@ func clusterHealthy() (bool, string) {
summary += fmt.Sprintf("missing = %d ", missing)
}
if unknown > 0 {
- summary += fmt.Sprintf("unknown = %d ", unknown)
+ summary += fmt.Sprintf("unknown = %d ", unknown, unknownList)
}
if failed > 0 {
summary += fmt.Sprintf("failed = %d ", failed)
diff --git a/structs.go b/structs.go
index ca77a7c..80f493b 100644
--- a/structs.go
+++ b/structs.go
@@ -37,10 +37,12 @@ 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)
- 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
+ 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
+ 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
}