start making it work in the real world

This commit is contained in:
Jeff Carr 2025-03-10 03:12:09 -05:00
parent dfbb8090ac
commit fba2d24625
7 changed files with 91 additions and 64 deletions

View File

@ -3,12 +3,14 @@
VERSION = $(shell git describe --tags) VERSION = $(shell git describe --tags)
BUILDTIME = $(shell date +%Y.%m.%d_%H%M) BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
all: portmap.pb.go goimports vet build all: portmap.pb.go build
./gus --version ./gus --version
./gus --no-gui ./gus --no-gui --config /etc/gus/gus.text
# ./gus --gui gocui >/tmp/gocui.log 2>&1
build: goimports gocui: build
./gus --gui gocui --config /etc/gus/gus.text >/tmp/gocui.log 2>&1
build: goimports vet
GO111MODULE=off go build -v -x \ GO111MODULE=off go build -v -x \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
@ -36,3 +38,6 @@ clean:
portmap.pb.go: portmap.proto portmap.pb.go: portmap.proto
autogenpb --proto portmap.proto autogenpb --proto portmap.proto
list:
curl "http://localhost:2522/list"

View File

@ -1,11 +1,11 @@
all: all:
@echo "make log # watch the zoo daemon log" @echo "make log # watch the zoo daemon log"
@echo "make status # show the systemd status of zood" @echo "make status # show the systemd status of gus"
@echo "make restart # restart zood" @echo "make restart # restart gus"
@echo "make enable # enable zood on boot" @echo "make enable # enable gus on boot"
log: log:
journalctl -f -xeu zood.service journalctl -f -xeu gus.service
curl-toggle-PING-output: curl-toggle-PING-output:
curl "http://localhost:2521/flag?flag-PING" curl "http://localhost:2521/flag?flag-PING"
@ -14,16 +14,16 @@ curl-kill:
curl http://localhost:2521/kill curl http://localhost:2521/kill
status: status:
dpkg -s zood dpkg -s gus
systemctl status zood.service systemctl status gus.service
enable: enable:
systemctl enable zood.service systemctl enable gus.service
stop: stop:
systemctl stop zood.service systemctl stop gus.service
restart: restart:
systemctl stop zood.service systemctl stop gus.service
systemctl start zood.service systemctl start gus.service
make log make log

View File

@ -19,6 +19,7 @@ type args struct {
Daemon bool `arg:"--daemon" default:"false" help:"run in daemon mode"` Daemon bool `arg:"--daemon" default:"false" help:"run in daemon mode"`
Port int `arg:"--port" default:"2522" help:"port to run on"` Port int `arg:"--port" default:"2522" help:"port to run on"`
URL string `arg:"--url" help:"url to use"` URL string `arg:"--url" help:"url to use"`
Config string `arg:"--config" help:"config file (default is ~/.config/cloud/gus.text"`
} }
func (args) Version() string { func (args) Version() string {

View File

@ -10,7 +10,6 @@ import (
"path/filepath" "path/filepath"
"go.wit.com/log" "go.wit.com/log"
"google.golang.org/protobuf/proto"
) )
func (m *Portmaps) ConfigSave() error { func (m *Portmaps) ConfigSave() error {
@ -19,15 +18,25 @@ func (m *Portmaps) ConfigSave() error {
} }
s := m.FormatTEXT() s := m.FormatTEXT()
log.Info("proto.Marshal() worked len", len(s)) log.Info("proto.Marshal() worked len", len(s))
configWrite([]byte(s)) configWrite(argv.Config, []byte(s))
return nil return nil
} }
func ConfigLoad() *Portmaps { func ConfigLoad() *Portmaps {
if os.Getenv("CLOUD_HOME") == "" { var fullname string
if os.Getenv("CLOUD_HOME") != "" {
fullname = filepath.Join(os.Getenv("CLOUD_HOME"), "gus.text")
if argv.Config == "" {
argv.Config = fullname
}
}
if argv.Config != "" {
fullname = argv.Config
}
if fullname == "" {
homeDir, _ := os.UserHomeDir() homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/cloud") fullname = filepath.Join(homeDir, ".config/cloud", "gus.text")
os.Setenv("CLOUD_HOME", fullpath) argv.Config = fullname
} }
var data []byte var data []byte
@ -51,19 +60,30 @@ func ConfigLoad() *Portmaps {
return p return p
} }
/*
func (m *Portmaps) ConfigLoad() error { func (m *Portmaps) ConfigLoad() error {
var fullname string
if m == nil { if m == nil {
return errors.New("It's not safe to run ConfigLoad() on a nil ?") return errors.New("It's not safe to run ConfigLoad() on a nil ?")
} }
if os.Getenv("CLOUD_HOME") == "" { if os.Getenv("CLOUD_HOME") != "" {
fullname = filepath.Join(os.Getenv("CLOUD_HOME"), "gus.text")
if argv.Config == "" {
argv.Config = fullname
}
}
if argv.Config != "" {
fullname = argv.Config
}
if fullname == "" {
homeDir, _ := os.UserHomeDir() homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/cloud") fullname = filepath.Join(homeDir, ".config/cloud", "gus.text")
os.Setenv("CLOUD_HOME", fullpath) argv.Config = fullname
} }
var data []byte var data []byte
var err error var err error
if data, err = loadFile("gus.text"); err != nil { if data, err = loadFile(); err != nil {
// something went wrong loading the file // something went wrong loading the file
return err return err
} }
@ -79,11 +99,9 @@ func (m *Portmaps) ConfigLoad() error {
log.Log(INFO, "gus.ConfigLoad() has", m.Len(), "port mappings") log.Log(INFO, "gus.ConfigLoad() has", m.Len(), "port mappings")
return nil return nil
} }
*/
func loadFile(filename string) ([]byte, error) { func loadFile(fullname string) ([]byte, error) {
homeDir, err := os.UserHomeDir()
p := filepath.Join(homeDir, ".config/cloud")
fullname := filepath.Join(p, filename)
data, err := os.ReadFile(fullname) data, err := os.ReadFile(fullname)
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {
// if file does not exist, just return nil. this // if file does not exist, just return nil. this
@ -96,9 +114,7 @@ func loadFile(filename string) ([]byte, error) {
return data, nil return data, nil
} }
func (m *Portmaps) loadFile(fname string) ([]byte, error) { func (m *Portmaps) loadFile(fullname string) ([]byte, error) {
fullname := filepath.Join(os.Getenv("CLOUD_HOME"), fname)
data, err := os.ReadFile(fullname) data, err := os.ReadFile(fullname)
if err != nil { if err != nil {
// log.Info("open config file :", err) // log.Info("open config file :", err)
@ -107,23 +123,24 @@ func (m *Portmaps) loadFile(fname string) ([]byte, error) {
return data, nil return data, nil
} }
func configWrite(data []byte) error { func configWrite(fullname string, data []byte) error {
homeDir, err := os.UserHomeDir() if _, base := filepath.Split(fullname); base == "" {
p := filepath.Join(homeDir, ".config/cloud") return fmt.Errorf("--config option not set")
fname := filepath.Join(p, "gus.text") }
cfgfile, err := os.OpenFile(fname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
defer cfgfile.Close() defer cfgfile.Close()
if err != nil { if err != nil {
log.Warn("open config file :", err) log.Warn("open config file :", err)
return err return err
}
cfgfile.Write(data)
return nil
}
func (m *Portmaps) configWrite(fullname string, data []byte) error {
if _, base := filepath.Split(fullname); base == "" {
return fmt.Errorf("--config option not set")
} }
cfgfile.Write(data)
return nil
}
func (m *Portmaps) configWrite(fname string, data []byte) error {
fullname := filepath.Join(os.Getenv("CLOUD_HOME"), fname)
cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
defer cfgfile.Close() defer cfgfile.Close()
if err != nil { if err != nil {

25
http.go
View File

@ -23,7 +23,7 @@ func okHandler(w http.ResponseWriter, r *http.Request) {
log.Info("Got URL Path: ", r.URL.Path) log.Info("Got URL Path: ", r.URL.Path)
route := cleanURL(r.URL.Path) route := cleanURL(r.URL.Path)
domname := r.URL.Query().Get("domain") // domname := r.URL.Query().Get("domain")
flag := r.URL.Query().Get("flag") flag := r.URL.Query().Get("flag")
msg, err := ioutil.ReadAll(r.Body) // Read the body as []byte msg, err := ioutil.ReadAll(r.Body) // Read the body as []byte
@ -38,12 +38,7 @@ func okHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
// exit the virtigo daemon & have systemd restart it // exit gus
// this can happen & when it does, access to
// to libvirtd will hang (aka: virsh list will hang)
// One way to trigger this is to not properly close
// domain sockets opened from go-qemu/hypervisor
// it's a good idea in any case so leave it here
if route == "/kill" { if route == "/kill" {
log.Warn("KILLED") log.Warn("KILLED")
fmt.Fprintln(w, "KILLED") fmt.Fprintln(w, "KILLED")
@ -51,10 +46,18 @@ func okHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
// curl http://localhost:2520/import?domain=foo.bar.com if route == "/list" {
if route == "/import" { all := me.portmaps.All()
fmt.Fprint(w, "import domain:", domname) for all.Scan() {
pm := all.Next()
if !pm.Enabled {
continue
}
s := fmt.Sprintf("portmap enabled for port %d to %s", pm.Listen, pm.Connect)
log.Info(s)
fmt.Fprintln(w, s)
}
startHTTP()
return return
} }

14
main.go
View File

@ -50,9 +50,6 @@ func main() {
os.Exit(0) os.Exit(0)
} }
// go NewWatchdog()
go startHTTP()
if gui.NoGui() { if gui.NoGui() {
all := me.portmaps.All() all := me.portmaps.All()
for all.Scan() { for all.Scan() {
@ -61,10 +58,13 @@ func main() {
continue continue
} }
log.Info("portmap enabled for port", pm.Listen, "to", pm.Connect) log.Info("portmap enabled for port", pm.Listen, "to", pm.Connect)
gus3000(int(pm.Listen), pm.Connect) go gus3000(int(pm.Listen), pm.Connect)
} }
// startHTTP()
os.Exit(0) os.Exit(0)
} }
// go NewWatchdog()
go startHTTP()
doGui() doGui()
} }
@ -85,10 +85,10 @@ func gus3000(port int, connect string) {
log.Printf("Failed to accept client connection: %v", err) log.Printf("Failed to accept client connection: %v", err)
continue continue
} }
log.Printf("Client connected: %s", clientConn.RemoteAddr()) // log.Printf("Client connected: %s", clientConn.RemoteAddr())
// Handle the connection in a separate goroutine // Handle the connection in a separate goroutine
go handleConnection(clientConn, s) go handleConnection(clientConn, connect)
} }
} }
@ -103,7 +103,7 @@ func handleConnection(clientConn net.Conn, where string) {
return return
} }
defer targetConn.Close() defer targetConn.Close()
log.Printf("Connected to target server: %s", targetConn.RemoteAddr()) log.Printf("Connected to target server: %s where = %s\n", targetConn.RemoteAddr(), where)
// Bidirectional copy of data // Bidirectional copy of data
go io.Copy(targetConn, clientConn) // Client -> Target go io.Copy(targetConn, clientConn) // Client -> Target

View File

@ -17,6 +17,7 @@ message Portmap {
int64 listen = 1; // `autogenpb:unique` int64 listen = 1; // `autogenpb:unique`
string connect = 2; // `autogenpb:unique` string connect = 2; // `autogenpb:unique`
bool enabled = 3; bool enabled = 3;
string uuid = 4;
} }
message Portmaps { // `autogenpb:marshal` `autogenpb:gui` `autogenpb:nomutex` message Portmaps { // `autogenpb:marshal` `autogenpb:gui` `autogenpb:nomutex`