package virtbuf import ( "fmt" "time" "github.com/google/uuid" "go.wit.com/log" ) // can the json protobuf output use a string and have a type handler // to convert it back to int64? func SetGB(gb int) int64 { return int64(gb * 1024 * 1024 * 1024) } func SetMB(mb int) int64 { return int64(mb * 1024 * 1024) } func (x *Hypervisor) SetMemoryGB(gb int) { x.Memory = int64(gb * 1024 * 1024 * 1024) } func (x *Hypervisor) GetMemoryPrintable() string { i := x.Memory / (1024 * 1024 * 1024) return fmt.Sprintf("%d GB", i) } func (all *Droplets) oldFindDroplet(name string) *Droplet { for _, d := range all.Droplets { if d.Hostname == name { return d } } return nil } func (c *Cluster) FindDropletByName(name string) *Droplet { for _, d := range c.Droplets { if d.Hostname == name { return d } } return nil } func (c *Cluster) FindHypervisorByName(name string) *Hypervisor { for _, h := range c.Hypervisors { if h.Hostname == name { return h } } return nil } func (c *Cluster) AddHypervisor(hostname string, cpus int, mem int) *Hypervisor { h := c.FindHypervisorByName(hostname) if h != nil { return h } // Generate a new UUID id := uuid.New() h = &Hypervisor{ Uuid: id.String(), Hostname: hostname, Cpus: int64(cpus), Comment: "this is a fake hypervisor", } if cpus < 0 { h.Cpus = 1 } h.SetMemoryGB(mem * 32) c.Hypervisors = append(c.Hypervisors, h) return h } func (c *Cluster) AddDroplet(uuid string, hostname string, cpus int, mem int) *Droplet { d := c.FindDropletByName(hostname) if d != nil { return d } d = &Droplet{ Uuid: uuid, Hostname: hostname, Cpus: int64(cpus), } if cpus < 0 { d.Cpus = 1 } d.Memory = SetGB(mem * 32) c.Droplets = append(c.Droplets, d) return d } // This isn't for the marketing department // so this isn't going to use 'MiB' and 'GiB' func HumanFormatBytes(b int64) string { if b < 2000 { return fmt.Sprintf("%d B", b) } kb := int(b / 1024) if kb < 2000 { return fmt.Sprintf("%d KB", kb) } mb := int(b / (1024 * 1024)) if mb < 2000 { return fmt.Sprintf("%d MB", mb) } gb := int(b / (1024 * 1024 * 1024)) if gb < 2000 { return fmt.Sprintf("%d GB", gb) } tb := int(b / (1024 * 1024 * 1024 * 1024)) return fmt.Sprintf("%d TB", tb) } func (c *Cluster) BlankFields() { for _, d := range c.Droplets { d.Current = nil } } func (epb *Events) AppendEvent(e *Event) { epb.Events = append(epb.Events, e) } func (c *Cluster) ClusterStable() (bool, string) { last := time.Since(c.Unstable.AsTime()) if last > c.UnstableTimeout.AsDuration() { // the cluster has not been stable for 133 seconds log.Warn("clusterReady() is stable for ", FormatDuration(c.UnstableTimeout.AsDuration()), " secs") return true, fmt.Sprintln("clusterReady() is stable ", FormatDuration(c.UnstableTimeout.AsDuration()), " secs") } log.Warn("clusterReady() is unstable for", FormatDuration(last)) return false, "clusterReady() is unstable for " + FormatDuration(last) } // check the cluster and droplet to make sure it's ready to start func (c *Cluster) DropletReady(d *Droplet) (bool, string) { if c == nil { return false, "cluster == nil" } if d == nil { return false, "droplet == nil" } if d.Current == nil { return false, "droplet.Current == nil" } // can't start already started droplet if d.Current.State == DropletState_ON { return false, "EVENT start droplet is already ON" } if d.Current.State != DropletState_OFF { return false, "EVENT start droplet is not OFF state = " + string(d.Current.State) } if d.Current.StartAttempts > 2 { // reason := "EVENT start droplet has already been started " + d.starts + " times" return false, fmt.Sprintln("EVENT start droplet has already been started ", d.Current.StartAttempts, " times") } return true, "" }