diff options
| author | Jeff Carr <[email protected]> | 2024-10-27 04:53:39 -0500 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2024-10-27 04:53:39 -0500 |
| commit | 212b582060107d8e64ca9dbe8e194cc922e460fa (patch) | |
| tree | 00948d77892ca8ec5aa65a4754d0f9b0fda3853b /start.go | |
| parent | d948581300ecea1b5407662be9e812ddf237e6cf (diff) | |
sets unique spice port and saves config filesv0.2
Signed-off-by: Jeff Carr <[email protected]>
Diffstat (limited to 'start.go')
| -rw-r--r-- | start.go | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/start.go b/start.go new file mode 100644 index 0000000..556c2d0 --- /dev/null +++ b/start.go @@ -0,0 +1,106 @@ +package main + +// validates the droplet information +// finds a hypervisor +// attempts to start the virtual machine + +import ( + "errors" + "fmt" + "math/rand" + "time" + + "go.wit.com/lib/gui/shell" + pb "go.wit.com/lib/protobuf/virtbuf" +) + +// for now, because sometimes this should write to stdout and +// sometimes to http socket, it returns a string +func Start(name string) (string, error) { + var result string + + // lookup the droplet by name + d := findDroplet(name) + if d == nil { + result = "can't start unknown droplet: " + name + return result, errors.New(result) + } + + // validate the droplet + if err := ValidateDroplet(d); err != nil { + result = "ValidateDroplet() failed droplet " + d.Hostname + return result, err + } + + // is the droplet already on? + if d.CurrentState == pb.DropletState_ON { + result = "EVENT start droplet " + d.Hostname + " is already ON" + return result, errors.New(result) + } + + // how long has the cluster been stable? + // wait until it is stable. use this to throttle droplet starts + dur := time.Since(me.unstable) + result = fmt.Sprintln("should start droplet", name, "here. grid stable for:", shell.FormatDuration(dur)) + if dur < me.unstableTimeout { + tmp := shell.FormatDuration(me.unstableTimeout) + result += "grid is still too unstable (unstable timeout = " + tmp + ")" + return result, errors.New("grid is still unstable") + } + + // make the list of hypervisors that are active and can start new droplets + var pool []*HyperT + for _, h := range me.hypers { + // this droplet is set to use this and only this hypervisor + if d.ForceHypervisor == h.pb.Hostname { + ok, b := h.start(d) + if ok { + return result + b, nil + } + return result + b, errors.New("start " + name + " on hypervisor " + h.pb.Hostname) + } + + // skip hypervisors marked inactive + if h.pb.Active != true { + result += fmt.Sprintln("hypervisor is inactive:", name, "for", h.pb.Hostname, h.pb.Active) + continue + } + + // the config file says this droplet should run on this hypervisor + // attempt to start the droplet here. use this even if the hypervisor is inactive? + if d.PreferredHypervisor == h.pb.Hostname { + ok, b := h.start(d) + if ok { + return result + b, nil + } + return result + b, errors.New("start " + name + " on hypervisor " + h.pb.Hostname) + } + + result += fmt.Sprintln("hypervisor ready:", name, "for", h.pb.Hostname, h.pb.Active) + 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) + result += fmt.Sprintln("pool has", len(pool), "members", "rand =", n) + h := pool[n] + + // update/resend the search directories to the hypervisor + result += fmt.Sprintln("h.sendDirs() HERE") + result += fmt.Sprintln("h.sendDirs() HERE") + h.sendDirs() + + ok, output := h.start(d) + if ok { + return result + output, nil + } + return result + output, errors.New("start " + name + " on hypervisor " + h.pb.Hostname) +} |
