summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--add.go33
-rw-r--r--change.go36
-rw-r--r--droplet.proto2
-rw-r--r--human.go157
-rw-r--r--time.go64
5 files changed, 196 insertions, 96 deletions
diff --git a/add.go b/add.go
index 6813aa8..d4bd08a 100644
--- a/add.go
+++ b/add.go
@@ -22,11 +22,6 @@ 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 {
@@ -111,7 +106,7 @@ func (c *NewCluster) AddDropletLocal(name string, hypername string) *Droplet {
d := &Droplet{
Hostname: name,
}
- d.LocalOnly = hypername
+ d.LocalOnly = "yes on: " + hypername
d.Current = new(Current)
d.Current.Hypervisor = hypername
d.StartState = DropletState_OFF
@@ -121,32 +116,6 @@ func (c *NewCluster) AddDropletLocal(name string, hypername string) *Droplet {
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 *NewCluster) BlankFields() {
loop := c.DropletsAll() // get the list of droplets
for loop.Scan() {
diff --git a/change.go b/change.go
index dc77b0c..04c5b20 100644
--- a/change.go
+++ b/change.go
@@ -49,6 +49,14 @@ func convertToString(x any) string {
return fmt.Sprintf("%d", x.(int))
case uint:
return fmt.Sprintf("%d", x.(uint))
+ case *DropletState:
+ var s *DropletState
+ s = x.(*DropletState)
+ return s.String()
+ case DropletState:
+ var s DropletState
+ s = x.(DropletState)
+ return s.String()
case bool:
if x.(bool) {
return "true"
@@ -128,6 +136,34 @@ func (d *Droplet) SetCpus(b int64) {
log.Info("Set the number of cpus for the droplet", b)
}
+// update the droplet memory
+func (d *Droplet) SetState(newState DropletState) {
+ if d.Current == nil {
+ d.Current = new(Current)
+ }
+ if d.Current.State == newState {
+ // nothing has changed
+ return
+ }
+ switch newState {
+ case DropletState_ON:
+ d.Current.OnSince = timestamppb.New(time.Now())
+ d.Current.OffSince = nil
+ case DropletState_OFF:
+ d.Current.OffSince = timestamppb.New(time.Now())
+ d.Current.OnSince = nil
+ default:
+ // zero on OnSince to indicate something hickup'd?
+ // not sure if this should be done here. probably trust qemu dom0 instead
+ // but I can't do that right now so for now this will work
+ d.Current.OnSince = timestamppb.New(time.Now())
+ d.Current.OffSince = timestamppb.New(time.Now())
+ }
+ d.Current.State = newState
+ d.NewChangeEvent("STATE", d.Current.State, newState)
+ log.Info("Droplet", d.Hostname, "changed state from", d.Current.State, "to", newState)
+}
+
// records an event that the droplet changed state (aka turned on, turned off, etc)
func (c *NewCluster) ChangeDropletState(d *Droplet, newState DropletState) error {
if c == nil {
diff --git a/droplet.proto b/droplet.proto
index f52fa7f..dd1b30a 100644
--- a/droplet.proto
+++ b/droplet.proto
@@ -44,6 +44,8 @@ message Current {
string full_xml = 4; // the full libvirt xml to import
google.protobuf.Timestamp last_poll = 5; // the last time we heard anything from this droplet
string image_url = 6; // url to the image
+ google.protobuf.Timestamp off_since = 7; // when the droplet was turned off
+ google.protobuf.Timestamp on_since = 8; // when the droplet was turned on
}
message Archive {
diff --git a/human.go b/human.go
new file mode 100644
index 0000000..c6a2fbc
--- /dev/null
+++ b/human.go
@@ -0,0 +1,157 @@
+package virtbuf
+
+// mostly just functions related to making STDOUT
+// more readable by us humans
+
+// also function shortcuts the do limited formatting (haha, who remembers COBOL?)
+// so reporting tables of the status of what droplets and hypervisors
+// are in text columns and rows that can be easily read in a terminal
+
+import (
+ "fmt"
+ "strings"
+ "time"
+)
+
+func oldGetDurationStamp(t time.Time) string {
+ // Get the current time
+ currentTime := time.Now()
+
+ // Calculate the duration between t current time
+ duration := currentTime.Sub(t)
+
+ return FormatDuration(duration)
+}
+
+// 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 FormatDuration(d time.Duration) string {
+ result := ""
+
+ // check if it's more than a year
+ years := int(d.Hours()) / (24 * 365)
+ if years > 0 {
+ result += fmt.Sprintf("%dy", years)
+ return result
+ }
+
+ // check if it's more than a day
+ days := int(d.Hours()) / 24
+ if days > 0 {
+ result += fmt.Sprintf("%dd", days)
+ return result
+ }
+
+ // check if it's more than an hour
+ hours := int(d.Hours()) % 24
+ if hours > 0 {
+ result += fmt.Sprintf("%dh", hours)
+ return result
+ }
+
+ // check if it's more than a minute
+ minutes := int(d.Minutes()) % 60
+ if minutes > 0 {
+ result += fmt.Sprintf("%dm", minutes)
+ return result
+ }
+
+ // check if it's more than a second
+ seconds := int(d.Seconds()) % 60
+ if seconds > 0 {
+ result += fmt.Sprintf("%ds", seconds)
+ return result
+ }
+
+ // report in milliseconds
+ ms := int(d.Milliseconds())
+ if ms > 100 {
+ // todo: print .3s, etc ?
+ return fmt.Sprintf("%1.2fs", seconds/1000)
+ }
+ if ms > 0 {
+ result += fmt.Sprintf("%dms", ms)
+ }
+
+ // totally not necessary but wth
+ var t time.Duration
+ t = time.Duration(ms) * time.Millisecond
+ nanos := d - t
+ result += fmt.Sprintf("%dnanos", nanos)
+ return result
+}
+
+
+func (d *Droplet) SprintHeader() string {
+ header := fmt.Sprintf("%-3.3s %-9.9s %-20.20s", d.Current.State, d.Current.Hypervisor, d.Hostname)
+
+ if d.Current == nil {
+ d.Current = new(Current)
+ }
+
+ switch d.Current.State {
+ case DropletState_ON:
+ dur := time.Since(d.Current.OnSince.AsTime()) // time since 'ON'
+ header += " (on :" + FormatDuration(dur) + ")"
+ case DropletState_OFF:
+ // everything is as it should be with this vm
+ dur := time.Since(d.Current.OffSince.AsTime()) // time since 'OFF'
+ header += " (off:" + FormatDuration(dur) + ")"
+ default:
+ dur := time.Since(d.Current.OffSince.AsTime()) // use 'OFF' here?
+ header += " (???:" + FormatDuration(dur) + ")"
+ }
+ return header
+}
+
+func (d *Droplet) SprintDumpHeader() string {
+ var macs []string
+ for _, n := range d.Networks {
+ macs = append(macs, n.Mac)
+ }
+
+ // this line in golang could replace 80 lines of COBOL
+ header := fmt.Sprintf("%-4.4s%20s %-8s", d.Current.State, strings.Join(macs, " "), d.Current.Hypervisor)
+
+ if d.Current == nil {
+ d.Current = new(Current)
+ }
+
+ switch d.Current.State {
+ case DropletState_ON:
+ dur := time.Since(d.Current.OnSince.AsTime()) // time since 'ON'
+ header += " (on :" + FormatDuration(dur) + ")"
+ case DropletState_OFF:
+ // everything is as it should be with this vm
+ dur := time.Since(d.Current.OffSince.AsTime()) // time since 'OFF'
+ header += " (off:" + FormatDuration(dur) + ")"
+ default:
+ dur := time.Since(d.Current.OffSince.AsTime()) // use 'OFF' here?
+ header += " (???:" + FormatDuration(dur) + ")"
+ }
+ return header
+}
diff --git a/time.go b/time.go
deleted file mode 100644
index 28f4098..0000000
--- a/time.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package virtbuf
-
-import (
- "fmt"
- "time"
-)
-
-func FormatDuration(d time.Duration) string {
- result := ""
-
- // check if it's more than a year
- years := int(d.Hours()) / (24 * 365)
- if years > 0 {
- result += fmt.Sprintf("%dy ", years)
- return result
- }
-
- // check if it's more than a day
- days := int(d.Hours()) / 24
- if days > 0 {
- result += fmt.Sprintf("%dd ", days)
- return result
- }
-
- // check if it's more than an hour
- hours := int(d.Hours()) % 24
- if hours > 0 {
- result += fmt.Sprintf("%dh ", hours)
- return result
- }
-
- // check if it's more than a minute
- minutes := int(d.Minutes()) % 60
- if minutes > 0 {
- result += fmt.Sprintf("%dm ", minutes)
- return result
- }
-
- // check if it's more than a second
- seconds := int(d.Seconds()) % 60
- if seconds > 0 {
- result += fmt.Sprintf("%ds", seconds)
- return result
- }
-
- // report in milliseconds
- ms := int(d.Milliseconds())
- if ms > 100 {
- // todo: print .3s, etc ?
- return fmt.Sprintf("%1.2fs", seconds/1000)
- }
- result += fmt.Sprintf("%dms", ms)
- return result
-}
-
-func GetDurationStamp(t time.Time) string {
- // Get the current time
- currentTime := time.Now()
-
- // Calculate the duration between t current time
- duration := currentTime.Sub(t)
-
- return FormatDuration(duration)
-}