diff --git a/Makefile b/Makefile index 9a687c0..df73d11 100644 --- a/Makefile +++ b/Makefile @@ -13,11 +13,11 @@ build: goimports vet GO111MODULE=off go build \ -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" -verbose: +verbose: goimports vet GO111MODULE=off go build -v -x \ -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" -install: +install: goimports vet GO111MODULE=off go install -v -x \ -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" diff --git a/doAdminGui.go b/doAdminGui.go index 20d6351..423a840 100644 --- a/doAdminGui.go +++ b/doAdminGui.go @@ -6,11 +6,17 @@ package main // An app to submit patches for the 30 GO GUI repos import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" "os" + "os/user" "time" "go.wit.com/gui" "go.wit.com/lib/gadgets" + "go.wit.com/lib/protobuf/virtpb" "go.wit.com/log" ) @@ -22,11 +28,21 @@ func refresh() { } } +var client *http.Client + func doAdminGui() { me.myGui = gui.New() me.myGui.InitEmbed(resources) me.myGui.Default() + // 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 + } + win := gadgets.NewGenericWindow("Virtigo: (run your cluster)", "virtigo stuff") win.Custom = func() { log.Warn("Main window close") @@ -35,10 +51,53 @@ func doAdminGui() { grid := win.Group.RawGrid() - grid.NewButton("show hyperbisors", func() { + // url := "http://example.com/endpoint" + url := argv.Server + data := []byte(`{"message": "Hello"}`) + + grid.NewButton("show hypervisors", func() { + response, err := postData(url, data) + if err != nil { + fmt.Println("Error:", err) + } else { + fmt.Println("Response:", string(response)) + } }) grid.NewButton("show droplets", func() { + durl := url + "/dumpdroplets" + response, err := postData(durl, data) + if err != nil { + fmt.Println("Error:", err) + } else { + fmt.Println("Response:", string(response)) + } + }) + + grid.NewButton("uptime", func() { + durl := url + "/uptime" + response, err := postData(durl, data) + if err != nil { + fmt.Println("Error:", err) + } else { + fmt.Println("Response:", string(response)) + } + }) + + grid.NewButton("get DropletsPB", func() { + durl := url + "/DropletsPB" + data, err := postData(durl, data) + if err != nil { + fmt.Println("Error:", err) + return + } + fmt.Println("Response len:", len(data)) + me.droplets = new(virtpb.Droplets) + if err := me.droplets.Unmarshal(data); err != nil { + fmt.Println("marshal failed", err) + return + } + fmt.Println("Droplet len=", me.droplets.Len()) }) grid.NewButton("clean exit", func() { @@ -50,3 +109,46 @@ func doAdminGui() { refresh() } } + +func postData(url string, data []byte) ([]byte, error) { + req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("failed to create request: %w", err) + } + + usr, _ := user.Current() + req.Header.Set("author", usr.Username) + req.Header.Set("Connection", "keep-alive") // Ensure keep-alive is used + + resp, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("request failed: %w", err) + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response: %w", err) + } + + return body, nil +} + +/* +func main() { + url := "http://example.com/endpoint" + data := []byte(`{"message": "Hello"}`) + + ticker := time.NewTicker(1 * time.Minute) + defer ticker.Stop() + + for range ticker.C { + response, err := postData(url, data) + if err != nil { + fmt.Println("Error:", err) + } else { + fmt.Println("Response:", string(response)) + } + } +} +*/ diff --git a/me.go b/me.go new file mode 100644 index 0000000..bc723ca --- /dev/null +++ b/me.go @@ -0,0 +1,84 @@ +package main + +// RFC implementation + +import ( + "bytes" + "context" + "fmt" + "io/ioutil" + "net" + "net/http" + "os/user" + "time" +) + +// Function to create a persistent TCP connection +func createPersistentConnection(host string) (net.Conn, error) { + dialer := &net.Dialer{ + Timeout: 10 * time.Second, + KeepAlive: 30 * time.Second, + } + conn, err := dialer.Dial("tcp", host) + if err != nil { + return nil, fmt.Errorf("failed to establish connection: %w", err) + } + return conn, nil +} + +func mesocket() { + host := "example.com:80" + + // Establish a persistent TCP connection + conn, err := createPersistentConnection(host) + if err != nil { + fmt.Println("Error creating connection:", err) + return + } + defer conn.Close() + + // Custom transport that forces HTTP requests to use our existing connection + transport := &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + fmt.Println("Reusing existing TCP connection") + return conn, nil + }, + DisableKeepAlives: false, // Ensure Keep-Alive is enabled + } + + client := &http.Client{ + Transport: transport, + Timeout: 10 * time.Second, + } + + url := "http://example.com/endpoint" + data := []byte(`{"message": "Hello"}`) + + // Create an HTTP request + req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data)) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + usr, _ := user.Current() + req.Header.Set("author", usr.Username) + req.Header.Set("Connection", "keep-alive") // Keep connection alive + + // Perform the HTTP request + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error performing request:", err) + return + } + defer resp.Body.Close() + + // Read and print the response + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Println("Error reading response:", err) + return + } + + fmt.Println("Response:", string(body)) +} diff --git a/structs.go b/structs.go index ac6cc01..4075227 100644 --- a/structs.go +++ b/structs.go @@ -36,6 +36,11 @@ type virtigoT struct { missingDropletTimeout time.Duration // how long a droplet can be missing for status *gui.Node // the cluster status lastuptime *gui.Node // the last time uptime was checked by Kuma + + // admin mode + droplets *virtpb.Droplets // your droplets + hypervisors *virtpb.Hypervisors // yep + events *virtpb.Events // yep } // the stuff that is needed for a hypervisor