mesh/merge-gate head 67d54d9d09b2 merged into trunk 13be75eb65c0 — pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus…
mesh/repo-check head 67d54d9d09b2 merged into trunk 13be75eb65c0 — pass: its merge-check.sh passed
mesh/delivery delivered
136 lines
4.1 KiB
Go
136 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
)
|
|
|
|
// machineLines is what a machine said it is made of (novox/hq issue 160), as `node` shows it: every fact in
|
|
// one block with its age, the architecture and kernel the profile always carried among them, and each fact
|
|
// the machine could not determine said as unknown with its why — never as a zero, and never left out.
|
|
func machineLines(a inventory.MachineAccount, had bool, now time.Time) []string {
|
|
if !had {
|
|
return []string{" what it is made of: never said — this machine has not reported a profile"}
|
|
}
|
|
m := a.Machine
|
|
if m == nil {
|
|
return []string{
|
|
" what it is made of: not said — its node-engine is older than the one that says it",
|
|
" " + factLine("architecture", orUnsaid(a.Architecture)),
|
|
" " + factLine("kernel", orUnsaid(a.Kernel)),
|
|
}
|
|
}
|
|
age := roughly(now.Sub(m.ObservedAt)) + " ago"
|
|
if m.ObservedAt.IsZero() {
|
|
// Said with no time: its age is not known, and is never read as two thousand years.
|
|
age = "at a time it did not say (age unknown)"
|
|
}
|
|
out := []string{fmt.Sprintf(" what it is made of, as it said %s:", age)}
|
|
add := func(name, value string) { out = append(out, " "+factLine(name, value)) }
|
|
unknown := map[string]string{}
|
|
for k, v := range m.Unknown {
|
|
unknown[k] = v
|
|
}
|
|
// said is the value, or the fact's own reason it is unknown; a fact neither said nor unknown is a
|
|
// node-engine that broke its own rule, and is said so rather than shown blank.
|
|
said := func(fact, value string) string {
|
|
if value != "" {
|
|
delete(unknown, fact)
|
|
return value
|
|
}
|
|
if why, ok := unknown[fact]; ok {
|
|
delete(unknown, fact)
|
|
return "unknown: " + why
|
|
}
|
|
return "unknown: the machine said neither it nor why"
|
|
}
|
|
|
|
add("architecture", orUnsaid(a.Architecture))
|
|
release := said("kernel release", m.KernelRelease)
|
|
if m.KernelRelease == "" {
|
|
release = "(release " + release + ")"
|
|
}
|
|
add("kernel", orUnsaid(a.Kernel)+" "+release)
|
|
dist := said("distribution", m.Distribution)
|
|
if m.Distribution != "" {
|
|
dist += " " + said("version", m.Version)
|
|
}
|
|
add("distribution", dist)
|
|
add("processor", said("processor", m.Processor))
|
|
add("cores", said("cores", countWords(m.Cores)))
|
|
add("threads", said("threads", countWords(m.Threads)))
|
|
add("memory", said("memory", bytesWords(m.MemoryBytes)))
|
|
add("virtual", said("virtual or physical", m.Virtual))
|
|
up := ""
|
|
if m.BootedAt != nil {
|
|
up = fmt.Sprintf("%s, since %s", roughly(now.Sub(*m.BootedAt)), m.BootedAt.Local().Format("2006-01-02 15:04"))
|
|
}
|
|
add("up", said("uptime", up))
|
|
add("timezone", said("timezone", m.Timezone))
|
|
if len(m.Filesystems) == 0 {
|
|
add("filesystems", said("filesystems", ""))
|
|
} else {
|
|
for i, f := range m.Filesystems {
|
|
name := ""
|
|
if i == 0 {
|
|
name = "filesystems"
|
|
}
|
|
add(name, fmt.Sprintf("%s %s, %s free (%s %s)", f.Mount, bytesWords(f.SizeBytes),
|
|
bytesWords(f.FreeBytes), f.Type, f.Device))
|
|
}
|
|
if why, ok := unknown["filesystems"]; ok {
|
|
add("", "and some unknown: "+why)
|
|
delete(unknown, "filesystems")
|
|
}
|
|
}
|
|
add("public address", said("public address", ""))
|
|
// Any other fact a newer node-engine named unknown, so nothing it said is dropped.
|
|
rest := make([]string, 0, len(unknown))
|
|
for k := range unknown {
|
|
rest = append(rest, k)
|
|
}
|
|
sort.Strings(rest)
|
|
for _, k := range rest {
|
|
add(k, "unknown: "+unknown[k])
|
|
}
|
|
return out
|
|
}
|
|
|
|
func factLine(name, value string) string { return fmt.Sprintf("%-15s %s", name, value) }
|
|
|
|
func orUnsaid(s string) string {
|
|
if strings.TrimSpace(s) == "" {
|
|
return "not said"
|
|
}
|
|
return s
|
|
}
|
|
|
|
// countWords is a number a machine said, or nothing when it said none (its unknown says why).
|
|
func countWords(n int) string {
|
|
if n <= 0 {
|
|
return ""
|
|
}
|
|
return fmt.Sprint(n)
|
|
}
|
|
|
|
// bytesWords is an amount of bytes a person reads, in binary units; nothing when none was said.
|
|
func bytesWords(n int64) string {
|
|
if n <= 0 {
|
|
return ""
|
|
}
|
|
units := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB"}
|
|
v, u := float64(n), 0
|
|
for v >= 1024 && u < len(units)-1 {
|
|
v /= 1024
|
|
u++
|
|
}
|
|
if u == 0 {
|
|
return fmt.Sprintf("%d B", n)
|
|
}
|
|
return fmt.Sprintf("%.1f %s", v, units[u])
|
|
}
|