2024-11-01 00:41:34 -05:00
|
|
|
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 (
|
2024-11-01 04:09:41 -05:00
|
|
|
"errors"
|
2024-11-01 00:41:34 -05:00
|
|
|
"fmt"
|
2024-11-01 04:09:41 -05:00
|
|
|
"net/http"
|
2024-11-01 00:41:34 -05:00
|
|
|
"strings"
|
|
|
|
"time"
|
2024-11-01 04:09:41 -05:00
|
|
|
|
|
|
|
"go.wit.com/log"
|
2024-11-01 00:41:34 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
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 {
|
|
|
|
if d.Current == nil {
|
|
|
|
d.Current = new(Current)
|
|
|
|
}
|
2024-11-01 08:45:52 -05:00
|
|
|
header := fmt.Sprintf("%-3.3s %-9.9s %-20.20s", d.Current.State, d.Current.Hypervisor, d.Hostname)
|
2024-11-01 00:41:34 -05:00
|
|
|
|
|
|
|
switch d.Current.State {
|
|
|
|
case DropletState_ON:
|
2024-11-01 02:01:11 -05:00
|
|
|
var dur string
|
|
|
|
if d.Current.OnSince != nil {
|
|
|
|
dur = ""
|
|
|
|
} else {
|
|
|
|
t := time.Since(d.Current.OnSince.AsTime()) // time since 'OFF'
|
|
|
|
dur = FormatDuration(t)
|
|
|
|
}
|
|
|
|
header += fmt.Sprintf(" (on :%3s)", dur)
|
2024-11-01 00:41:34 -05:00
|
|
|
case DropletState_OFF:
|
2024-11-01 02:01:11 -05:00
|
|
|
var dur string
|
|
|
|
if d.Current.OffSince != nil {
|
|
|
|
dur = ""
|
|
|
|
} else {
|
|
|
|
t := time.Since(d.Current.OffSince.AsTime()) // time since 'OFF'
|
|
|
|
dur = FormatDuration(t)
|
|
|
|
}
|
|
|
|
header += fmt.Sprintf(" (off:%3s)", dur)
|
2024-11-01 00:41:34 -05:00
|
|
|
default:
|
2024-11-01 02:01:11 -05:00
|
|
|
header += fmt.Sprintf(" (?? :%3s)", "")
|
2024-11-01 00:41:34 -05:00
|
|
|
}
|
|
|
|
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:
|
2024-11-01 02:01:11 -05:00
|
|
|
var dur string
|
|
|
|
if d.Current.OnSince != nil {
|
|
|
|
dur = ""
|
|
|
|
} else {
|
|
|
|
t := time.Since(d.Current.OnSince.AsTime()) // time since 'ON'
|
|
|
|
dur = FormatDuration(t)
|
|
|
|
}
|
|
|
|
header += fmt.Sprintf(" (on :%3s)", dur)
|
2024-11-01 00:41:34 -05:00
|
|
|
case DropletState_OFF:
|
2024-11-01 02:01:11 -05:00
|
|
|
var dur string
|
|
|
|
if d.Current.OffSince != nil {
|
|
|
|
dur = ""
|
|
|
|
} else {
|
|
|
|
t := time.Since(d.Current.OffSince.AsTime()) // time since 'OFF'
|
|
|
|
dur = FormatDuration(t)
|
|
|
|
}
|
|
|
|
header += fmt.Sprintf(" (off:%3s)", dur)
|
2024-11-01 00:41:34 -05:00
|
|
|
default:
|
2024-11-01 02:01:11 -05:00
|
|
|
header += fmt.Sprintf(" (?? :%3s)", "")
|
2024-11-01 00:41:34 -05:00
|
|
|
}
|
|
|
|
return header
|
|
|
|
}
|
2024-11-01 04:09:41 -05:00
|
|
|
|
|
|
|
func (d *Droplet) DumpDroplet(w http.ResponseWriter, r *http.Request) (string, error) {
|
|
|
|
if d == nil {
|
|
|
|
reason := "DumpDroplet() got d == nil"
|
|
|
|
log.Warn(reason)
|
|
|
|
fmt.Fprintln(w, reason)
|
|
|
|
return "", errors.New(reason)
|
|
|
|
}
|
|
|
|
t := d.FormatTEXT()
|
|
|
|
log.Info(t)
|
|
|
|
fmt.Fprintln(w, t)
|
|
|
|
return t, nil
|
|
|
|
}
|
|
|
|
|
2024-11-07 05:04:11 -06:00
|
|
|
func (c *Cluster) DumpDroplet(w http.ResponseWriter, r *http.Request) (string, error) {
|
2024-11-01 04:09:41 -05:00
|
|
|
hostname := r.URL.Query().Get("hostname")
|
|
|
|
d := c.FindDropletByName(hostname)
|
|
|
|
if d == nil {
|
|
|
|
result := "can not find droplet hostname=" + hostname
|
|
|
|
log.Info(result)
|
|
|
|
fmt.Fprintln(w, result)
|
|
|
|
return result, errors.New(result)
|
|
|
|
}
|
|
|
|
return d.DumpDroplet(w, r)
|
|
|
|
}
|