262 lines
6.1 KiB
Go
262 lines
6.1 KiB
Go
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
|
// Use of this source code is governed by the GPL 3.0
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"go.wit.com/gui"
|
|
"go.wit.com/lib/gadgets"
|
|
"go.wit.com/lib/protobuf/virtpb"
|
|
"go.wit.com/log"
|
|
)
|
|
|
|
type stdDropletTableWin struct {
|
|
sync.Mutex
|
|
win *gadgets.GenericWindow // the machines gui window
|
|
box *gui.Node // the machines gui parent box widget
|
|
pb *virtpb.Droplets // the droplets protobuf
|
|
TB *virtpb.DropletsTable // the gui table buffer
|
|
update bool // if the window should be updated
|
|
Close func() // this function is called when the window is closed
|
|
}
|
|
|
|
func (w *stdDropletTableWin) Toggle() {
|
|
if w == nil {
|
|
return
|
|
}
|
|
if w.win == nil {
|
|
return
|
|
}
|
|
w.win.Toggle()
|
|
}
|
|
|
|
func newDropletsWindow() *stdDropletTableWin {
|
|
dwin := new(stdDropletTableWin)
|
|
dwin.win = gadgets.NewGenericWindow("virtigo current droplets", "Options")
|
|
dwin.win.Custom = func() {
|
|
log.Info("test delete window here")
|
|
}
|
|
grid := dwin.win.Group.RawGrid()
|
|
|
|
grid.NewButton("Active", func() {
|
|
var found *virtpb.Droplets
|
|
found = virtpb.NewDroplets()
|
|
all := me.admin.droplets.All()
|
|
for all.Scan() {
|
|
vm := all.Next()
|
|
if vm.Current.State != virtpb.DropletState_ON {
|
|
continue
|
|
}
|
|
found.Append(vm)
|
|
}
|
|
dwin.doActiveDroplets(found)
|
|
})
|
|
|
|
grid.NewButton("Inactive", func() {
|
|
var found *virtpb.Droplets
|
|
found = virtpb.NewDroplets()
|
|
all := me.admin.droplets.All()
|
|
for all.Scan() {
|
|
vm := all.Next()
|
|
if vm.Current.State == virtpb.DropletState_ON {
|
|
continue
|
|
}
|
|
found.Append(vm)
|
|
}
|
|
dwin.doInactiveDroplets(found)
|
|
})
|
|
|
|
// make a box at the bottom of the window for the protobuf table
|
|
dwin.box = dwin.win.Bottom.Box().SetProgName("TBOX")
|
|
return dwin
|
|
}
|
|
|
|
/*
|
|
func makeWindownDropletsPB(pb *virtpb.Droplets) *stdDropletTableWin {
|
|
dwin := new(stdDropletTableWin)
|
|
dwin.win = gadgets.NewGenericWindow("virtigo current droplets", "")
|
|
dwin.win.Custom = func() {
|
|
log.Info("test delete window here")
|
|
}
|
|
|
|
// make a box at the bottom of the window for the protobuf table
|
|
dwin.box = dwin.win.Bottom.Box().SetProgName("TBOX")
|
|
|
|
dwin.doDropletsTable(pb)
|
|
|
|
return dwin
|
|
}
|
|
*/
|
|
|
|
/*
|
|
func (dwin *stdDropletTableWin) doDropletsTable(currentDroplets *virtpb.Droplets) {
|
|
dwin.Lock()
|
|
defer dwin.Unlock()
|
|
if dwin.TB != nil {
|
|
dwin.TB.Delete()
|
|
dwin.TB = nil
|
|
}
|
|
|
|
// display the protobuf
|
|
dwin.TB = addDropletsPB(dwin.box, currentDroplets)
|
|
f := func(e *virtpb.Droplet) {
|
|
log.Info("Triggered. do something here", e.Hostname)
|
|
// m.Enabled = true
|
|
}
|
|
dwin.TB.Custom(f)
|
|
}
|
|
|
|
func addDropletsPB(tbox *gui.Node, pb *virtpb.Droplets) *virtpb.DropletsTable {
|
|
t := pb.NewTable("DropletsPB")
|
|
t.NewUuid()
|
|
t.SetParent(tbox)
|
|
|
|
vp := t.AddButtonFunc("start", func(p *virtpb.Droplet) string {
|
|
return "poweron"
|
|
})
|
|
vp.Custom = func(d *virtpb.Droplet) {
|
|
log.Info("power on the droplet here:", d.Hostname)
|
|
}
|
|
t.AddHostname()
|
|
t.AddMemory()
|
|
t.AddCpus()
|
|
t.ShowTable()
|
|
return t
|
|
}
|
|
*/
|
|
|
|
// default window for active running droplets
|
|
func (dw *stdDropletTableWin) doInactiveDroplets(pb *virtpb.Droplets) {
|
|
dw.Lock()
|
|
defer dw.Unlock()
|
|
|
|
// erase the old table
|
|
if dw.TB != nil {
|
|
dw.TB.Delete()
|
|
dw.TB = nil
|
|
}
|
|
|
|
// init the table
|
|
dw.pb = pb
|
|
t := dw.pb.NewTable("DropletsPB Off")
|
|
t.NewUuid()
|
|
t.SetParent(dw.box)
|
|
|
|
// pick the columns
|
|
// t.AddHostname()
|
|
dropon := t.AddButtonFunc("Start", func(d *virtpb.Droplet) string {
|
|
return "poweron"
|
|
})
|
|
dropon.Custom = func(d *virtpb.Droplet) {
|
|
log.Info("start droplet here", d.Hostname)
|
|
}
|
|
/*
|
|
t.AddHostname()
|
|
t.AddStringFunc("location", func(d *virtpb.Droplet) string {
|
|
return d.Current.Hypervisor
|
|
})
|
|
*/
|
|
vp := t.AddButtonFunc("Configure Hostname", func(p *virtpb.Droplet) string {
|
|
return p.Hostname
|
|
})
|
|
vp.Custom = func(d *virtpb.Droplet) {
|
|
log.Info("open config window", d.Hostname)
|
|
}
|
|
/*
|
|
t.AddHostname()
|
|
t.AddStringFunc("location", func(d *virtpb.Droplet) string {
|
|
return d.Current.Hypervisor
|
|
})
|
|
*/
|
|
t.AddMemory()
|
|
t.AddCpus()
|
|
|
|
// final setup and display the table
|
|
dw.TB = t
|
|
f := func(e *virtpb.Droplet) {
|
|
log.Info("Triggered. do something here", e.Hostname)
|
|
// m.Enabled = true
|
|
}
|
|
dw.TB.Custom(f)
|
|
dw.TB.ShowTable()
|
|
}
|
|
|
|
// default window for active running droplets
|
|
func (dw *stdDropletTableWin) doActiveDroplets(pb *virtpb.Droplets) {
|
|
dw.Lock()
|
|
defer dw.Unlock()
|
|
if dw.TB != nil {
|
|
dw.TB.Delete()
|
|
dw.TB = nil
|
|
}
|
|
|
|
dw.pb = pb
|
|
|
|
t := dw.pb.NewTable("DropletsPB On")
|
|
t.NewUuid()
|
|
|
|
t.SetParent(dw.box)
|
|
|
|
serial := t.AddButtonFunc("serial", func(p *virtpb.Droplet) string {
|
|
return "ttyS0"
|
|
})
|
|
serial.Custom = func(d *virtpb.Droplet) {
|
|
log.Printf("run %s: socat telnet somewhere %s:%d\n", d.Hostname, argv.Server, d.SpicePort)
|
|
log.Info("socat TCP-LISTEN:5000,reuseaddr,fork EXEC:\"virsh console myvm\"")
|
|
|
|
}
|
|
|
|
fb := t.AddButtonFunc("fb0 console", func(p *virtpb.Droplet) string {
|
|
return "remmina"
|
|
})
|
|
fb.Custom = func(d *virtpb.Droplet) {
|
|
log.Printf("connect to %s on %s: remmina spice://%s:%d\n", d.Hostname, d.Current.Hypervisor, argv.Server, 10000+d.SpicePort)
|
|
data, err := gusPost(fmt.Sprintf("%d", 10000+d.SpicePort), d.Current.Hypervisor)
|
|
log.Info("data", string(data), "err =", err)
|
|
}
|
|
|
|
t.AddHostname()
|
|
t.AddStringFunc("location", func(d *virtpb.Droplet) string {
|
|
return d.Current.Hypervisor
|
|
})
|
|
t.AddMemory()
|
|
t.AddCpus()
|
|
t.AddSpicePort()
|
|
t.AddTimeFunc("age", func(d *virtpb.Droplet) time.Time {
|
|
age := d.Current.OnSince.AsTime()
|
|
// log.Info("age", d.Hostname, virtpb.FormatDuration(time.Since(age)))
|
|
return age
|
|
})
|
|
t.AddStringFunc("State", func(d *virtpb.Droplet) string {
|
|
if d.Current.State == virtpb.DropletState_ON {
|
|
return "ON"
|
|
}
|
|
if d.Current.State == virtpb.DropletState_OFF {
|
|
return "OFF"
|
|
}
|
|
return "UNKNOWN"
|
|
})
|
|
t.AddStringFunc("mac addr", func(d *virtpb.Droplet) string {
|
|
var macs []string
|
|
for _, n := range d.Networks {
|
|
macs = append(macs, n.Mac)
|
|
}
|
|
tmp := strings.Join(macs, "\n")
|
|
return strings.TrimSpace(tmp)
|
|
})
|
|
t.ShowTable()
|
|
|
|
// display the protobuf
|
|
dw.TB = t
|
|
f := func(e *virtpb.Droplet) {
|
|
log.Info("Triggered. do something here", e.Hostname)
|
|
// m.Enabled = true
|
|
}
|
|
dw.TB.Custom(f)
|
|
}
|