summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--argv.go27
-rw-r--r--argvAutoshell.go91
-rw-r--r--doList.go102
-rw-r--r--main.go32
-rw-r--r--structs.go4
6 files changed, 247 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index df73d11..56e04b3 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@ REDOMOD = $(shell if [ -e go.sum ]; then echo go.sum exists; else GO111MODULE=
all: install
@echo build worked
+ virtigo list droplets
build: goimports vet
GO111MODULE=off go build \
@@ -113,3 +114,6 @@ http-dumplibvirtxml:
protogen:
go-clone google.golang.org/protobuf
cd ~/go/src/google.golang.org/protobuf/cmd/protoc-gen-go && go install
+
+gocui: install
+ virtigo --gui gocui --gui-verbose --gui-file ../../toolkits/gocui/gocui.so >/tmp/forge.log 2>&1
diff --git a/argv.go b/argv.go
index b3cab5c..a1d2862 100644
--- a/argv.go
+++ b/argv.go
@@ -11,12 +11,25 @@ import "go.wit.com/log"
var argv args
type args struct {
- Verbose bool `arg:"--verbose" help:"talk more"`
- Config string `arg:"env:VIRTIGO_HOME" help:"defaults to ~/.config/virtigo/"`
- Port int `arg:"--port" default:"8080" help:"allow droplet events via http"`
- Server string `arg:"env:VIRTIGO_SERVER" help:"what virtigo cluster to connect to"`
- Xml []string `arg:"--libvirt" help:"import qemu xml files: --libvirt /etc/libvirt/qemu/*.xml"`
- Admin bool `arg:"--admin" help:"enter admin mode"`
+ 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"`
+}
+
+type EmptyCmd struct {
+}
+
+type testCmd string
+
+type ListCmd struct {
+ Droplets *EmptyCmd `arg:"subcommand:droplets" help:"list droplets"`
+ Hypervisors *EmptyCmd `arg:"subcommand:hypervisors" help:"list hypervisors"`
}
func (a args) Description() string {
@@ -30,7 +43,7 @@ This app talks to your hypervisors via the virtigod daemon.
}
func (args) Version() string {
- return "virtigo " + Version
+ return ARGNAME + " " + VERSION + " Built on " + BUILDTIME
}
var INFO *log.LogFlag
diff --git a/argvAutoshell.go b/argvAutoshell.go
new file mode 100644
index 0000000..e3b9d94
--- /dev/null
+++ b/argvAutoshell.go
@@ -0,0 +1,91 @@
+// 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"
+ "os"
+)
+
+/*
+ handles shell autocomplete
+*/
+
+// used for shell auto completion
+// var ARGNAME string = "forge" // todo: get this from $0 ?
+
+func deleteMatch() {
+ // f := forgedb.InitSimple()
+ fmt.Println("go.wit.com/lib/gui/repostatus todo: need to do this")
+}
+
+func (args) doBashAuto() {
+ argv.doBashHelp()
+ switch argv.BashAuto[0] {
+ case "list":
+ fmt.Println("droplets hypervisors")
+ case "devel":
+ fmt.Println("--force")
+ case "master":
+ fmt.Println("")
+ case "verify":
+ fmt.Println("user devel master")
+ default:
+ if argv.BashAuto[0] == ARGNAME {
+ // list the subcommands here
+ fmt.Println("--bash list")
+ }
+ }
+ os.Exit(0)
+}
+
+// prints help to STDERR // TODO: move everything below this to go-args
+func (args) doBashHelp() {
+ if argv.BashAuto[1] != "''" {
+ // if this is not blank, then the user has typed something
+ return
+ }
+ if argv.BashAuto[0] != ARGNAME {
+ // if this is not the name of the command, the user already started doing something
+ return
+ }
+ if argv.BashAuto[0] == ARGNAME {
+ me.pp.WriteHelp(os.Stderr)
+ return
+ }
+ fmt.Fprintln(os.Stderr, "")
+ fmt.Fprintln(os.Stderr, "hello world")
+ fmt.Fprintln(os.Stderr, "")
+}
+
+// complete -F forge --bash forge
+func (args) doBash() {
+ fmt.Println("# add this in your bashrc:")
+ fmt.Println("")
+ fmt.Println("# todo: add this to go-arg as a 'hidden' go-arg option --bash")
+ fmt.Println("#")
+ fmt.Println("# todo: can this output work/parse with:")
+ fmt.Println("# complete -C `" + ARGNAME + " --bash` " + ARGNAME)
+ fmt.Println("")
+ fmt.Println("_" + ARGNAME + "_complete()")
+ fmt.Println("{")
+ fmt.Println(" # sets local to this func vars")
+ fmt.Println(" local cur prev all")
+ fmt.Println(" cur=${COMP_WORDS[COMP_CWORD]}")
+ fmt.Println(" prev=${COMP_WORDS[COMP_CWORD-1]}")
+ fmt.Println(" all=${COMP_WORDS[@]}")
+ fmt.Println("")
+ fmt.Println(" # this is where we generate the go-arg output")
+ fmt.Println(" GOARGS=$(" + ARGNAME + " --auto-complete $prev \\'$cur\\' $all)")
+ fmt.Println("")
+ fmt.Println(" # this compares the command line input from the user")
+ fmt.Println(" # to whatever strings we output")
+ fmt.Println(" COMPREPLY=( $(compgen -W \"$GOARGS\" -- $cur) ) # THIS WORKS")
+ fmt.Println(" return 0")
+ fmt.Println("}")
+ fmt.Println("complete -F _" + ARGNAME + "_complete " + ARGNAME)
+ fmt.Println("")
+ fmt.Println("# copy and paste the above into your bash shell should work")
+ os.Exit(0)
+}
diff --git a/doList.go b/doList.go
new file mode 100644
index 0000000..ee2eeea
--- /dev/null
+++ b/doList.go
@@ -0,0 +1,102 @@
+// 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"
+)
+
+// refresh the windows & tables the user has open
+func doListDroplets() {
+ /*
+ // update the droplet list
+ if data, err := postData(admin.url.String()+"/DropletsPB", msg); err != nil {
+ log.Info("/DropletsPB Error:", err)
+ } else {
+ fmt.Println("DropletsPB Response len:", len(data))
+ admin.droplets = new(virtpb.Droplets)
+ if err := admin.droplets.Unmarshal(data); err != nil {
+ fmt.Println("droplets marshal failed", err)
+ return
+ }
+ fmt.Println("Droplet len=", admin.droplets.Len())
+ }
+
+ // update the hypervisor list
+ if data, err := postData(admin.url.String()+"/HypervisorsPB", msg); err != nil {
+ log.Info("Error:", err)
+ } else {
+ fmt.Println("HypervisorsPB Response len:", len(data))
+ admin.hypervisors = new(virtpb.Hypervisors)
+ if err := admin.hypervisors.Unmarshal(data); err != nil {
+ fmt.Println("hypervisors marshal failed", err)
+ return
+ }
+ fmt.Println("Hypervisors len=", admin.hypervisors.Len())
+ }
+
+ // update the events list
+ if data, err := postData(admin.url.String()+"/EventsPB", msg); err != nil {
+ log.Info("Error:", err)
+ } else {
+ fmt.Println("EventsPB Response len:", len(data))
+ admin.events = new(virtpb.Events)
+ if err := admin.events.Unmarshal(data); err != nil {
+ fmt.Println("events marshal failed", err)
+ return
+ }
+ fmt.Println("Events len=", admin.events.Len())
+ }
+ */
+}
+
+// var client *http.Client
+
+func doList() {
+ 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)
+ // a.makeClusterGroup(c)
+ admin.url, err = url.Parse(c.URL)
+ if err != nil {
+ badExit(err)
+ }
+ // update the droplet list
+ if data, err := postData(admin.url.String()+"/DropletsPB", msg); err != nil {
+ log.Info("/DropletsPB Error:", err)
+ } else {
+ fmt.Println("DropletsPB Response len:", len(data))
+ admin.droplets = new(virtpb.Droplets)
+ if err := admin.droplets.Unmarshal(data); err != nil {
+ fmt.Println("droplets marshal failed", err)
+ return
+ }
+ fmt.Println("Droplet len=", admin.droplets.Len())
+ }
+
+ }
+
+ // sit here forever refreshing the GUI
+}
diff --git a/main.go b/main.go
index b6403fc..1ca73f1 100644
--- a/main.go
+++ b/main.go
@@ -18,18 +18,31 @@ import (
"go.wit.com/log"
)
-var Version string
+// sent via -ldflags
+var VERSION string
+var BUILDTIME string
+
+var ARGNAME string = "virtigo"
//go:embed resources/*
var resources embed.FS
func main() {
- var pp *arg.Parser
+ me = new(virtigoT)
gui.InitArg()
- pp = arg.MustParse(&argv)
+ me.pp = arg.MustParse(&argv)
+
+ if argv.Bash {
+ argv.doBash()
+ os.Exit(0)
+ }
+ if len(argv.BashAuto) != 0 {
+ argv.doBashAuto()
+ os.Exit(0)
+ }
- if pp == nil {
- pp.WriteHelp(os.Stdout)
+ if me.pp == nil {
+ me.pp.WriteHelp(os.Stdout)
os.Exit(0)
}
@@ -41,6 +54,15 @@ func main() {
me.clusters = virtpb.NewClusters()
+ if argv.List != nil {
+ err := me.clusters.ConfigLoad()
+ if err != nil {
+ badExit(err)
+ }
+ doList()
+ okExit("virtigo list")
+ }
+
if argv.Admin {
err := me.clusters.ConfigLoad()
if err != nil {
diff --git a/structs.go b/structs.go
index c7010f9..84349b4 100644
--- a/structs.go
+++ b/structs.go
@@ -4,12 +4,13 @@ import (
"net/url"
"time"
+ "go.wit.com/dev/alexflint/arg"
"go.wit.com/gui"
"go.wit.com/lib/gadgets"
"go.wit.com/lib/protobuf/virtpb"
)
-var me virtigoT
+var me *virtigoT
// disable the GUI
func (b *virtigoT) Disable() {
@@ -23,6 +24,7 @@ func (b *virtigoT) Enable() {
// this app's variables
type virtigoT struct {
+ pp *arg.Parser // go-arg parser
cluster *virtpb.OldCluster // basic cluster settings
myGui *gui.Node // the gui toolkit handle
e *virtpb.Events // virt protobuf events