start from the command line works
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
aa6b142b7c
commit
1c77ec7e63
3
Makefile
3
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:
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
46
event.go
46
event.go
|
@ -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
26
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
|
||||
}
|
||||
|
||||
|
|
4
poll.go
4
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)
|
||||
|
|
14
structs.go
14
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue