start from the command line works

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-10-15 11:02:34 -05:00
parent aa6b142b7c
commit 1c77ec7e63
6 changed files with 86 additions and 14 deletions

View File

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

View File

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

View File

@ -23,8 +23,46 @@ func (h *HyperT) RestartDaemon() {
me.killcount += 1
}
func (h *HyperT) Start(d *DropletT) {
url := "http://" + h.Hostname + ":2520/start?" + d.Hostname
s := shell.Wget(url)
log.Info("EVENT start droplet", url, s)
// 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) {
if ! clusterReady() {
return
}
if ! d.dropletReady() {
return
}
url := "http://" + h.Hostname + ":2520/start?start=" + d.Hostname
s := shell.Wget(url)
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()
}

26
http.go
View File

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

View File

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

View File

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