/event sends and gets an event PB

This commit is contained in:
Jeff Carr 2025-04-21 18:24:34 -05:00
parent 4121e66e01
commit a24448a9d4
8 changed files with 94 additions and 43 deletions

View File

@ -10,8 +10,8 @@ all: install
@echo build worked @echo build worked
virtigo list droplets virtigo list droplets
virtigo list droplets --on virtigo list droplets --on
virtigo droplet start --name coriolis
virtigo droplet show --name coriolis virtigo droplet show --name coriolis
virtigo droplet start --name coriolis
build: goimports vet build: goimports vet
GO111MODULE=off go build \ GO111MODULE=off go build \

View File

@ -109,7 +109,7 @@ func doLocalhostAdminGui() *adminT {
log.Info("droplets not initialized") log.Info("droplets not initialized")
return return
} }
admin.dwin = newDropletsWindow() admin.dwin = newDropletsWindow(admin)
admin.dwin.win.Custom = func() { admin.dwin.win.Custom = func() {
log.Info("hiding droplet table window") log.Info("hiding droplet table window")
} }
@ -225,7 +225,7 @@ func (admin *adminT) doAdminGui() {
log.Info("droplets not initialized") log.Info("droplets not initialized")
return return
} }
admin.dwin = newDropletsWindow() admin.dwin = newDropletsWindow(admin)
admin.dwin.win.Custom = func() { admin.dwin.win.Custom = func() {
log.Info("hiding droplet table window") log.Info("hiding droplet table window")
} }
@ -320,7 +320,7 @@ func (admin *adminT) makeClusterGroup(c *virtpb.Cluster) {
log.Info("droplets not initialized") log.Info("droplets not initialized")
return return
} }
admin.dwin = newDropletsWindow() admin.dwin = newDropletsWindow(admin)
admin.dwin.win.Custom = func() { admin.dwin.win.Custom = func() {
log.Info("hiding droplet table window") log.Info("hiding droplet table window")
} }
@ -382,3 +382,28 @@ func postData(url string, data []byte) ([]byte, error) {
return body, nil return body, nil
} }
func (admin *adminT) postEvent(e *virtpb.Event) error {
var result *virtpb.Event
result = new(virtpb.Event)
msg, err := e.Marshal()
if err != nil {
log.Info("postEvent() marshal() failed", err, e)
return err
}
// update the droplet list
if data, err := postData(admin.url.String()+"/event", msg); err != nil {
log.Info("postEvent() /event Error:", err)
return err
} else {
if err := result.Unmarshal(data); err != nil {
log.Println("postEvent() result marshal failed", err, "len(dat) =", len(data))
log.Println("postEvent() data =", string(data))
return err
}
}
log.Printf("Event type: %s\n", result.DropletUuid)
return nil
}

View File

@ -71,10 +71,25 @@ func doDroplet() (string, error) {
for all.Scan() { for all.Scan() {
vm := all.Next() vm := all.Next()
if argv.Droplet.Name == vm.Hostname { if argv.Droplet.Name == vm.Hostname {
log.Info(vm.SprintHeader()) if argv.Droplet.Show != nil {
txt := vm.FormatTEXT() log.Info(vm.SprintHeader())
log.Info(txt) txt := vm.FormatTEXT()
return "droplet found", nil log.Info(txt)
return "droplet status", nil
}
if argv.Droplet.Start != nil {
log.Info("should start droplet here")
log.Info(vm.SprintHeader())
e := new(virtpb.Event)
e.Etype = virtpb.EventType_POWERON
e.DropletUuid = vm.Uuid
if err := admin.postEvent(e); err != nil {
return "droplet start err", err
}
return "droplet start", nil
}
return "droplet found", fmt.Errorf("do what to the droplet?")
} }
found.Append(vm) found.Append(vm)
} }
@ -82,3 +97,16 @@ func doDroplet() (string, error) {
} }
return "", fmt.Errorf("droplet %s not found", argv.Droplet.Name) return "", fmt.Errorf("droplet %s not found", argv.Droplet.Name)
} }
func doEvent(e *virtpb.Event) *virtpb.Event {
result := new(virtpb.Event)
if e.Etype == virtpb.EventType_POWERON {
log.Println("power on droplet on local cluster here", e.DropletUuid)
result.State = virtpb.Event_DONE
rs, err := Start(e.DropletUuid)
log.Println("Start() returned", rs)
log.Println("Start() returned err", err)
}
return result
}

36
http.go
View File

@ -21,8 +21,8 @@ func cleanURL(url string) string {
func okHandler(w http.ResponseWriter, r *http.Request) { func okHandler(w http.ResponseWriter, r *http.Request) {
var route string var route string
route = cleanURL(r.URL.Path) route = cleanURL(r.URL.Path)
log.HttpMode(w) // log.HttpMode(w)
defer log.HttpMode(nil) // defer log.HttpMode(nil)
msg, err := ioutil.ReadAll(r.Body) // Read the body as []byte msg, err := ioutil.ReadAll(r.Body) // Read the body as []byte
if err != nil { if err != nil {
@ -70,26 +70,24 @@ func okHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
if route == "/start" { if route == "/event" {
hostname := r.URL.Query().Get("hostname") var e *virtpb.Event
if hostname == "" { e = new(virtpb.Event)
log.Warn("start failed. hostname is blank", cleanURL(r.URL.Path)) if err := e.Unmarshal(msg); err != nil {
log.Info("proto.Unmarshal() failed on wire message len", len(msg))
log.Info("error =", err)
return return
} }
log.Warn("hostname is", hostname) log.Info("/event proto.Unmarshal() worked on msg len", len(msg), "hostname =", e.DropletUuid)
result := doEvent(e)
// log.Warn("Handling URL:", tmp, "start droplet", start) data, err := result.Marshal()
result, err := Start(hostname) if err != nil {
if err == nil { log.Info("/event marshal failed", err, "len(data) =", len(data))
log.Info(result) fmt.Fprintln(w, "/event failed", err)
log.Info(hostname, "started output ok") return
log.Info(hostname, "need to parse the output here")
log.Info(hostname, "todo: switch to protobuf here")
} else {
log.Info(result)
log.Info(err)
log.Info(hostname, "start failed")
} }
w.Write(data)
// fmt.Fprintln("droplet marshal failed", err)
return return
} }

View File

@ -76,9 +76,9 @@ func main() {
if argv.Server != "" { if argv.Server != "" {
log.Info("start admin interface") log.Info("start admin interface")
me.admin = new(adminT) admin := new(adminT)
var err error var err error
me.admin.url, err = url.Parse(argv.Server) admin.url, err = url.Parse(argv.Server)
if err != nil { if err != nil {
badExit(err) badExit(err)
} }
@ -94,7 +94,7 @@ func main() {
badExit(err) badExit(err)
} }
me.admin.doAdminGui() admin.doAdminGui()
okExit("admin close") okExit("admin close")
} }

View File

@ -29,7 +29,7 @@ func isClusterStable() (string, error) {
// for now, because sometimes this should write to stdout and // for now, because sometimes this should write to stdout and
// sometimes to http socket, it returns a string // sometimes to http socket, it returns a string
func Start(name string) (string, error) { func Start(id string) (string, error) {
var result string var result string
if s, err := isClusterStable(); err != nil { if s, err := isClusterStable(); err != nil {
@ -38,9 +38,9 @@ func Start(name string) (string, error) {
} }
// lookup the droplet by name // lookup the droplet by name
d := me.cluster.FindDropletByName(name) d := me.cluster.FindDropletByName(id)
if d == nil { if d == nil {
result = "can't start unknown droplet: " + name result = "can't start unknown droplet: " + id
return result, errors.New(result) return result, errors.New(result)
} }
@ -66,12 +66,12 @@ func Start(name string) (string, error) {
if ok { if ok {
return result + b, nil return result + b, nil
} }
return result + b, errors.New("start " + name + " on hypervisor " + h.pb.Hostname) return result + b, errors.New("start " + d.Hostname + " on hypervisor " + h.pb.Hostname)
} }
// skip hypervisors marked inactive // skip hypervisors marked inactive
if h.pb.Active != true { if h.pb.Active != true {
result += fmt.Sprintln("hypervisor is inactive:", name, "for", h.pb.Hostname, h.pb.Active) result += fmt.Sprintln("hypervisor is inactive:", d.Hostname, "for", h.pb.Hostname, h.pb.Active)
continue continue
} }
@ -82,10 +82,10 @@ func Start(name string) (string, error) {
if ok { if ok {
return result + b, nil return result + b, nil
} }
return result + b, errors.New("start " + name + " on hypervisor " + h.pb.Hostname) return result + b, errors.New("start " + d.Hostname + " on hypervisor " + h.pb.Hostname)
} }
result += fmt.Sprintln("hypervisor ready:", name, "for", h.pb.Hostname, h.pb.Active) result += fmt.Sprintln("hypervisor ready:", d.Hostname, "for", h.pb.Hostname, h.pb.Active)
pool = append(pool, h) pool = append(pool, h)
} }
@ -106,5 +106,5 @@ func Start(name string) (string, error) {
if ok { if ok {
return result + output, nil return result + output, nil
} }
return result + output, errors.New("start " + name + " on hypervisor " + h.pb.Hostname) return result + output, errors.New("start " + d.Hostname + " on hypervisor " + h.pb.Hostname)
} }

View File

@ -25,7 +25,6 @@ func (b *virtigoT) Enable() {
// this app's variables // this app's variables
type virtigoT struct { type virtigoT struct {
pp *arg.Parser // go-arg parser pp *arg.Parser // go-arg parser
cluster *virtpb.OldCluster // basic cluster settings
myGui *gui.Node // the gui toolkit handle myGui *gui.Node // the gui toolkit handle
e *virtpb.Events // virt protobuf events e *virtpb.Events // virt protobuf events
hmap map[*virtpb.Hypervisor]*HyperT // map to the local struct hmap map[*virtpb.Hypervisor]*HyperT // map to the local struct
@ -40,10 +39,11 @@ type virtigoT struct {
missingDropletTimeout time.Duration // how long a droplet can be missing for missingDropletTimeout time.Duration // how long a droplet can be missing for
status *gui.Node // the cluster status status *gui.Node // the cluster status
lastuptime *gui.Node // the last time uptime was checked by Kuma lastuptime *gui.Node // the last time uptime was checked by Kuma
admin *adminT // the admin struct
clusters *virtpb.Clusters // clusters protobuf clusters *virtpb.Clusters // clusters protobuf
cmap map[*virtpb.Cluster]*adminT // map to local GUI objects and the protobuf cmap map[*virtpb.Cluster]*adminT // map to local GUI objects and the protobuf
gwin *gadgets.GenericWindow // main window gwin *gadgets.GenericWindow // main window
cluster *virtpb.OldCluster // basic cluster settings
// admin *adminT // the admin struct
} }
// cluster "admin" mode // cluster "admin" mode

View File

@ -35,7 +35,7 @@ func (w *stdDropletTableWin) Toggle() {
w.win.Toggle() w.win.Toggle()
} }
func newDropletsWindow() *stdDropletTableWin { func newDropletsWindow(admin *adminT) *stdDropletTableWin {
dwin := new(stdDropletTableWin) dwin := new(stdDropletTableWin)
dwin.win = gadgets.NewGenericWindow("virtigo current droplets", "Options") dwin.win = gadgets.NewGenericWindow("virtigo current droplets", "Options")
dwin.win.Custom = func() { dwin.win.Custom = func() {
@ -46,7 +46,7 @@ func newDropletsWindow() *stdDropletTableWin {
grid.NewButton("Active", func() { grid.NewButton("Active", func() {
var found *virtpb.Droplets var found *virtpb.Droplets
found = virtpb.NewDroplets() found = virtpb.NewDroplets()
all := me.admin.cluster.Droplets.All() all := admin.cluster.Droplets.All()
for all.Scan() { for all.Scan() {
vm := all.Next() vm := all.Next()
if vm.Current.State != virtpb.DropletState_ON { if vm.Current.State != virtpb.DropletState_ON {
@ -60,7 +60,7 @@ func newDropletsWindow() *stdDropletTableWin {
grid.NewButton("Inactive", func() { grid.NewButton("Inactive", func() {
var found *virtpb.Droplets var found *virtpb.Droplets
found = virtpb.NewDroplets() found = virtpb.NewDroplets()
all := me.admin.cluster.Droplets.All() all := admin.cluster.Droplets.All()
for all.Scan() { for all.Scan() {
vm := all.Next() vm := all.Next()
if vm.Current.State == virtpb.DropletState_ON { if vm.Current.State == virtpb.DropletState_ON {