diff --git a/Makefile b/Makefile index 4879292..9ded075 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ BUILDTIME = $(shell date +%Y.%m.%d_%H%M) all: portmap.pb.go goimports vet build ./gus --version - ./gus + ./gus --gui gocui >/tmp/gocui.log 2>&1 build: goimports GO111MODULE=off go build -v -x \ diff --git a/argv.go b/argv.go index 5808239..a66764d 100644 --- a/argv.go +++ b/argv.go @@ -9,26 +9,22 @@ package main */ import ( - "go.wit.com/dev/alexflint/arg" "go.wit.com/log" ) var argv args type args struct { - Daemon bool `arg:"--daemon" default:"false" help:"run in daemon mode"` - Port int `arg:"--port" default:"2522" help:"port to run on"` - URL string `arg:"--url" help:"url to use"` + Verbose bool `arg:"--verbose" help:"talk more"` + Daemon bool `arg:"--daemon" default:"false" help:"run in daemon mode"` + Port int `arg:"--port" default:"2522" help:"port to run on"` + URL string `arg:"--url" help:"url to use"` } func (args) Version() string { return "gus " + VERSION + " Built on: " + BUILDTIME } -func init() { - arg.MustParse(&argv) -} - func (a args) Description() string { return ` this daemon talks to zookeeper diff --git a/debugger.go b/debugger.go new file mode 100644 index 0000000..f7a6aca --- /dev/null +++ b/debugger.go @@ -0,0 +1,20 @@ +package main + +/* + enables GUI options and the debugger in your application +*/ + +import ( + "go.wit.com/lib/debugger" + "go.wit.com/log" +) + +func init() { + if debugger.ArgDebug() { + log.Info("cmd line --debugger == true") + go func() { + log.Sleep(2) + debugger.DebugWindow() + }() + } +} diff --git a/doGui.go b/doGui.go new file mode 100644 index 0000000..94245a6 --- /dev/null +++ b/doGui.go @@ -0,0 +1,62 @@ +// 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 ( + "os" + "time" + + "go.wit.com/gui" + "go.wit.com/lib/gadgets" + "go.wit.com/log" +) + +// refresh the windows & tables the user has open +func refresh() { + time.Sleep(90 * time.Second) + if argv.Verbose { + log.Info("gus scan here") + } +} + +func doGui() { + me.myGui = gui.New() + me.myGui.InitEmbed(resources) + me.myGui.Default() + + win := gadgets.RawBasicWindow("gus: (squirl your way around networks)") + win.Make() + win.Show() + win.Custom = func() { + log.Warn("Main window close") + os.Exit(0) + } + + box := win.Box() + + vbox := box.NewVerticalBox("BOX2") + + group1 := vbox.NewGroup("gus Settings") + grid := group1.NewGrid("buildOptions", 0, 0) + + grid.NewButton("portwins", func() { + // if the window exists, just toggle it open or closed + if me.portwin != nil { + me.portwin.Toggle() + return + } + makePortmapWin() + }) + + grid.NewButton("Events", func() { + log.Info("todo: start a list here!") + }) + + // sit here forever refreshing the GUI + for { + refresh() + } +} diff --git a/main.go b/main.go index e5ea927..825301b 100644 --- a/main.go +++ b/main.go @@ -4,20 +4,26 @@ package main import ( + "embed" "io" "net" "os" "time" "go.wit.com/dev/alexflint/arg" + "go.wit.com/gui" "go.wit.com/log" ) var VERSION string var BUILDTIME string +//go:embed resources/* +var resources embed.FS + func main() { var pp *arg.Parser + gui.InitArg() pp = arg.MustParse(&argv) if pp == nil { @@ -25,8 +31,12 @@ func main() { os.Exit(0) } - me := new(gusconf) + me = new(gusconf) me.pollDelay = 10 * time.Second + me.portmaps = NewPortmaps() + p := new(Portmap) + p.Connect = "testing:323" + me.portmaps.Append(p) if argv.Daemon { // turn off timestamps for STDOUT (systemd adds them) @@ -39,7 +49,11 @@ func main() { go listen3000() - startHTTP() + go startHTTP() + if gui.NoGui() { + os.Exit(0) + } + doGui() } func listen3000() { diff --git a/portmap.proto b/portmap.proto index a1a6814..a3c3964 100644 --- a/portmap.proto +++ b/portmap.proto @@ -16,6 +16,7 @@ message Events { message Portmap { int64 listen = 1; string connect = 2; + bool enabled = 3; } message Portmaps { // `autogenpb:marshal` `autogenpb:gui` diff --git a/resources/gus.text b/resources/gus.text new file mode 100644 index 0000000..0f0f738 --- /dev/null +++ b/resources/gus.text @@ -0,0 +1,6 @@ +# this file is intended to be used to customize settings on what +# git repos you have write access to. That is, where you can run 'git push' + +Portmap: { + connect: "go.wit.com:80" +} diff --git a/structs.go b/structs.go index eab8923..1cf6370 100644 --- a/structs.go +++ b/structs.go @@ -4,13 +4,20 @@ package main import ( + sync "sync" "time" + + "go.wit.com/gui" + "go.wit.com/lib/gadgets" ) var me *gusconf // this app's variables type gusconf struct { + myGui *gui.Node // the base of the gui + portmaps *Portmaps // the portmap window + portwin *stdTableWin // the portwin window urlbase string // the dns name for the zookeeper hostname string // my hostname pollDelay time.Duration // how often to report our status @@ -18,3 +25,21 @@ type gusconf struct { failcount int // how many times we've failed to contact the zookeeper failcountmax int // after this, exit and let systemd restart the daemon } + +type stdTableWin struct { + sync.Mutex + win *gadgets.GenericWindow // the machines gui window + box *gui.Node // the machines gui parent box widget + TB *PortmapsTable // the gui table buffer + update bool // if the window should be updated +} + +func (w *stdTableWin) Toggle() { + if w == nil { + return + } + if w.win == nil { + return + } + w.win.Toggle() +} diff --git a/windowPortmap.go b/windowPortmap.go new file mode 100644 index 0000000..83ce7aa --- /dev/null +++ b/windowPortmap.go @@ -0,0 +1,115 @@ +// Copyright 2017-2025 WIT.COM Inc. All rights reserved. +// Use of this source code is governed by the GPL 3.0 + +package main + +import ( + "go.wit.com/gui" + "go.wit.com/lib/gadgets" + "go.wit.com/lib/protobuf/zoopb" + "go.wit.com/log" +) + +func makePortmapWin() { + me.portwin = new(stdTableWin) + me.portwin.win = gadgets.NewGenericWindow("zood daemon versions", "todo: add global controls here") + me.portwin.win.Custom = func() { + log.Info("test delete window here") + } + grid := me.portwin.win.Group.RawGrid() + grid.NewButton("save machines.pb", func() { + saveMachineState() + }) + grid.NewCheckbox("hide active") + grid.NewButton("update", func() { + doMachinesUpgradeTable() + }) + + // make a box at the bottom of the window for the protobuf table + me.portwin.box = me.portwin.win.Bottom.Box().SetProgName("TBOX") + doMachinesUpgradeTable() +} + +func doMachinesUpgradeTable() { + me.portwin.Lock() + defer me.portwin.Unlock() + if me.portwin.TB != nil { + me.portwin.TB.Delete() + me.portwin.TB = nil + } + + // display the protobuf + me.portwin.TB = AddMachinesPB(me.portwin.box, me.portmaps) + f := func(m *Portmap) { + log.Info("Triggering machine", m.Connect, "to upgrade portwin") + m.Enabled = true + } + me.portwin.TB.Custom(f) + log.Info("table has uuid", me.portwin.TB.GetUuid()) +} + +func AddMachinesPB(tbox *gui.Node, pb *Portmaps) *PortmapsTable { + t := pb.NewTable("PortmapsPB") + t.NewUuid() + t.SetParent(tbox) + + f := func(m *Portmap) string { + log.Info("machine =", m.Connect) + return "now" + } + t.AddButtonFunc("upgrade", f) + + t.AddConnect() + // t.AddMemory() + // t.AddCpus() + /* + t.AddStringFunc("sMB", func(m *oopb.Machine) string { + return fmt.Sprintf("%d mb", m.Memory/(1024*1024)) + }) + + t.AddStringFunc("portwin", func(m *zoopb.Machine) string { + return findVersion(m, "portwin") + }) + */ + + /* + // show if the machine needs to be upgraded + t.AddStringFunc("triggered?", func(m *zoopb.Machine) string { + if m.Upgrade { + return "yes" + } + return "" + }) + */ + + /* + t.AddTimeFunc("age", func(m *zoopb.Machine) time.Time { + return m.Laststamp.AsTime() + }) + */ + + t.ShowTable() + return t +} + +func findVersion(m *zoopb.Machine, pkgname string) string { + portwin := m.Packages.FindByName(pkgname) + if portwin == nil { + return "n/a" + } + return portwin.Version +} + +func saveMachineState() { + /* + cur := zoopb.NewMachines() + + all := me.machines.SortByHostname() + for all.Scan() { + m := all.Next() + log.Info("have machine:", m.Hostname) + cur.Append(m) + } + cur.ConfigSave() + */ +}