diff --git a/Makefile b/Makefile index f01a705..72877e1 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,8 @@ all: install @echo build worked virtigo list droplets virtigo list droplets --on + virtigo droplet start --name coriolis + virtigo droplet show --name coriolis build: goimports vet GO111MODULE=off go build \ diff --git a/argv.go b/argv.go index 7ab034c..d032aea 100644 --- a/argv.go +++ b/argv.go @@ -11,15 +11,16 @@ import "go.wit.com/log" var argv args type args struct { - List *ListCmd `arg:"subcommand:list" help:"list things"` - Config string `arg:"env:VIRTIGO_HOME" help:"defaults to ~/.config/virtigo/"` - Server string `arg:"env:VIRTIGO_SERVER" help:"what virtigo cluster to connect to"` - Verbose bool `arg:"--verbose" help:"talk more"` - Port int `arg:"--port" default:"8080" help:"allow droplet events via http"` - Xml []string `arg:"--libvirt" help:"import qemu xml files: --libvirt /etc/libvirt/qemu/*.xml"` - Admin bool `arg:"--admin" help:"enter admin mode"` - Bash bool `arg:"--bash" help:"generate bash completion"` - BashAuto []string `arg:"--auto-complete" help:"todo: move this to go-arg"` + List *ListCmd `arg:"subcommand:list" help:"list things"` + Droplet *DropletCmd `arg:"subcommand:droplet" help:"send events to a droplet"` + Config string `arg:"env:VIRTIGO_HOME" help:"defaults to ~/.config/virtigo/"` + Server string `arg:"env:VIRTIGO_SERVER" help:"what virtigo cluster to connect to"` + Verbose bool `arg:"--verbose" help:"talk more"` + Port int `arg:"--port" default:"8080" help:"allow droplet events via http"` + Xml []string `arg:"--libvirt" help:"import qemu xml files: --libvirt /etc/libvirt/qemu/*.xml"` + Admin bool `arg:"--admin" help:"enter admin mode"` + Bash bool `arg:"--bash" help:"generate bash completion"` + BashAuto []string `arg:"--auto-complete" help:"todo: move this to go-arg"` } type EmptyCmd struct { @@ -33,6 +34,16 @@ type ListCmd struct { On bool `arg:"--on" help:"only show things that are on"` } +type DropletCmd struct { + Start *EmptyCmd `arg:"subcommand:start" help:"start droplet"` + Stop *EmptyCmd `arg:"subcommand:stop" help:"stop droplet"` + Show *EmptyCmd `arg:"subcommand:show" help:"show droplet"` + Console *EmptyCmd `arg:"subcommand:console" help:"open serial console"` + VNC *EmptyCmd `arg:"subcommand:vnc" help:"open VNC console"` + Spice *EmptyCmd `arg:"subcommand:spice" help:"open spiceconsole"` + Name string `arg:"--name" help:"what droplet to start"` +} + func (a args) Description() string { return ` virtigo: control your cluster diff --git a/argvAutoshell.go b/argvAutoshell.go index e3b9d94..5137946 100644 --- a/argvAutoshell.go +++ b/argvAutoshell.go @@ -25,6 +25,8 @@ func (args) doBashAuto() { switch argv.BashAuto[0] { case "list": fmt.Println("droplets hypervisors") + case "droplet": + fmt.Println("start stop") case "devel": fmt.Println("--force") case "master": @@ -34,7 +36,7 @@ func (args) doBashAuto() { default: if argv.BashAuto[0] == ARGNAME { // list the subcommands here - fmt.Println("--bash list") + fmt.Println("--bash list droplet") } } os.Exit(0) diff --git a/doDroplet.go b/doDroplet.go new file mode 100644 index 0000000..8a7cafc --- /dev/null +++ b/doDroplet.go @@ -0,0 +1,81 @@ +// Copyright 2017-2025 WIT.COM Inc. All rights reserved. +// Use of this source code is governed by the GPL 3.0 + +package main + +// An app to submit patches for the 30 GO GUI repos + +import ( + "fmt" + "net/http" + "net/url" + "time" + + "go.wit.com/lib/protobuf/virtpb" + "go.wit.com/log" +) + +func doDroplet() (string, error) { + err := me.clusters.ConfigLoad() + if err != nil { + return "", err + } + + msg := []byte(`{"message": "Hello"}`) + + // Initialize a persistent client with a custom Transport + client = &http.Client{ + Transport: &http.Transport{ + DisableKeepAlives: false, // Ensure Keep-Alive is enabled + }, + Timeout: 10 * time.Second, // Set a reasonable timeout + } + + me.cmap = make(map[*virtpb.Cluster]*adminT) + for c := range me.clusters.IterAll() { + var err error + admin := new(adminT) + me.cmap[c] = admin + log.Info("found in the config file", c.URL[0]) + // a.makeClusterGroup(c) + admin.url, err = url.Parse(c.URL[0]) + if err != nil { + return "", err + } + + // update the droplet list + if data, err := postData(admin.url.String()+"/DropletsPB", msg); err != nil { + log.Info("/DropletsPB Error:", err) + continue + } else { + admin.droplets = new(virtpb.Droplets) + if err := admin.droplets.Unmarshal(data); err != nil { + log.Printf("DropletsPB Response len:%d\n", len(data)) + log.Println("droplets marshal failed", err) + continue + } + } + log.Printf("Cluster Name: %s\n", c.Name) + log.Printf("Number of Droplets: %d\n", admin.droplets.Len()) + + if argv.Droplet.Name == "" { + return "", fmt.Errorf("--name droplet name was empty") + } + + var found *virtpb.Droplets + found = virtpb.NewDroplets() + all := admin.droplets.All() + for all.Scan() { + vm := all.Next() + if argv.Droplet.Name == vm.Hostname { + log.Info(vm.SprintHeader()) + txt := vm.FormatTEXT() + log.Info(txt) + return "droplet found", nil + } + found.Append(vm) + } + log.Println("On Droplet count=", found.Len()) + } + return "", fmt.Errorf("droplet %s not found", argv.Droplet.Name) +} diff --git a/exit.go b/exit.go index 4a39635..4043e5b 100644 --- a/exit.go +++ b/exit.go @@ -11,14 +11,26 @@ import ( func okExit(note string) { if note != "" { - log.Info("virtigo exit:", note, "ok") + log.Info(ARGNAME, "exit:", note, "ok") } me.myGui.Close() os.Exit(0) } func badExit(err error) { - log.Info("virtigo failed: ", err) + log.Info(ARGNAME, "failed: ", err) me.myGui.Close() os.Exit(-1) } + +func exit(note string, err error) { + if note != "" { + log.Info(ARGNAME, "exit:", note, "ok") + } + me.myGui.Close() + if err == nil { + os.Exit(0) + } + log.Info(ARGNAME, "failed: ", err) + os.Exit(-1) +} diff --git a/main.go b/main.go index ee3182e..0dc18f5 100644 --- a/main.go +++ b/main.go @@ -63,6 +63,10 @@ func main() { okExit("virtigo list") } + if argv.Droplet != nil { + exit(doDroplet()) + } + if argv.Admin { err := me.clusters.ConfigLoad() if err != nil {