detached 2966ef2

Refine CLI and server interactions, improve error handling

- Update launch configuration to use main.go
- Adjust VHS demo settings for better visibility
- Enhance logging and error messages in CLI commands
- Improve response handling in push and deploy operations
- Refactor HTTP handlers for better error reporting
- Standardize error message formatting
- Minor UI improvements in log output
commit
2966ef22b58616251f81cd814f14cfbf085f5967
author
bamen · · 2024-10-16 08:56 UTC
parent
f6c0a0b
signature
unsigned
8 files · +34 -24
M .vscode/launch.json +1 -1
@@ -9,7 +9,7 @@
99 "type": "go",
1010 "request": "launch",
1111 "mode": "debug",
12- "program": "./cmd/cli/main.go",
12+ "program": "./main.go",
1313 }
1414
1515
@@ -9,7 +9,7 @@
9 "type": "go",9 "type": "go",
10 "request": "launch",10 "request": "launch",
11 "mode": "debug",11 "mode": "debug",
12- "program": "./cmd/cli/main.go",12+ "program": "./main.go",
13 }13 }
14 14
15 15
M Makefile +1 -0
@@ -1,3 +1,4 @@
1+# This Makefile is used for dev purposes
12 # Variables
23 REPO := ghcr.io/bnema/gordon
34 TAG := dev
@@ -1,3 +1,4 @@
1+# This Makefile is used for dev purposes
1 # Variables2 # Variables
2 REPO := ghcr.io/bnema/gordon3 REPO := ghcr.io/bnema/gordon
3 TAG := dev4 TAG := dev
M assets/vhs/demo_deploy.gif +0 -0 binary file: no text diff

binary file: no text diff

M assets/vhs/demo_deploy.tape +2 -2
@@ -60,10 +60,10 @@ Require curl
6060
6161 Set TypingSpeed 75ms
6262 Set Shell "bash"
63-Set FontSize 17
63+Set FontSize 16
6464 Set FontFamily "FiraCode Nerd Font"
6565 Set Width 1200
66-Set Height 300
66+Set Height 350
6767
6868 Type "gordon"
6969 Sleep 1
@@ -60,10 +60,10 @@ Require curl
60 60
61 Set TypingSpeed 75ms61 Set TypingSpeed 75ms
62 Set Shell "bash"62 Set Shell "bash"
63-Set FontSize 1763+Set FontSize 16
64 Set FontFamily "FiraCode Nerd Font"64 Set FontFamily "FiraCode Nerd Font"
65 Set Width 120065 Set Width 1200
66-Set Height 30066+Set Height 350
67 67
68 Type "gordon"68 Type "gordon"
69 Sleep 169 Sleep 1
M assets/vhs/demo_push.gif +0 -0 binary file: no text diff

binary file: no text diff

M internal/cli/cmd/deploy.go +4 -2
@@ -116,7 +116,7 @@ func exportDockerImage(imageName string) (io.ReadCloser, int64, error) {
116116
117117 func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain string) error {
118118
119- log.Info("Attempting to deploy...", "image", imageName, "port", port, "target_domain", targetDomain)
119+ log.Info("Attempting to deploy...", "image", imageName, "port", port, "target", targetDomain)
120120
121121 reqPayload := common.RequestPayload{
122122 Type: "deploy",
@@ -172,6 +172,8 @@ func waitForDeployment(domain string, containerID string) error {
172172 client := &http.Client{Timeout: 10 * time.Second}
173173 maxRetries := 20
174174 retryInterval := time.Second
175+ // shorten the container id to 12 characters
176+ shortContainerID := containerID[:12]
175177
176178 log.Info("Waiting for deployment to be reachable")
177179 for i := 0; i < maxRetries; i++ {
@@ -181,7 +183,7 @@ func waitForDeployment(domain string, containerID string) error {
181183 if resp.StatusCode == http.StatusOK {
182184 log.Info("Deployment successful",
183185 "domain", domain,
184- "container_id", containerID)
186+ "container_id", shortContainerID)
185187 return nil
186188 }
187189 // Check for error messages in the response body
@@ -116,7 +116,7 @@ func exportDockerImage(imageName string) (io.ReadCloser, int64, error) {
116 116
117 func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain string) error {117 func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain string) error {
118 118
119- log.Info("Attempting to deploy...", "image", imageName, "port", port, "target_domain", targetDomain)119+ log.Info("Attempting to deploy...", "image", imageName, "port", port, "target", targetDomain)
120 120
121 reqPayload := common.RequestPayload{121 reqPayload := common.RequestPayload{
122 Type: "deploy",122 Type: "deploy",
@@ -172,6 +172,8 @@ func waitForDeployment(domain string, containerID string) error {
172 client := &http.Client{Timeout: 10 * time.Second}172 client := &http.Client{Timeout: 10 * time.Second}
173 maxRetries := 20173 maxRetries := 20
174 retryInterval := time.Second174 retryInterval := time.Second
175+ // shorten the container id to 12 characters
176+ shortContainerID := containerID[:12]
175 177
176 log.Info("Waiting for deployment to be reachable")178 log.Info("Waiting for deployment to be reachable")
177 for i := 0; i < maxRetries; i++ {179 for i := 0; i < maxRetries; i++ {
@@ -181,7 +183,7 @@ func waitForDeployment(domain string, containerID string) error {
181 if resp.StatusCode == http.StatusOK {183 if resp.StatusCode == http.StatusOK {
182 log.Info("Deployment successful",184 log.Info("Deployment successful",
183 "domain", domain,185 "domain", domain,
184- "container_id", containerID)186+ "container_id", shortContainerID)
185 return nil187 return nil
186 }188 }
187 // Check for error messages in the response body189 // Check for error messages in the response body
M internal/cli/cmd/push.go +12 -5
@@ -4,6 +4,7 @@ import (
44 "encoding/json"
55 "fmt"
66 "os"
7+ "strings"
78
89 "github.com/bnema/gordon/internal/cli"
910 "github.com/bnema/gordon/internal/cli/handler"
@@ -73,22 +74,28 @@ func pushImage(a *cli.App, imageName string) error {
7374
7475 resp, err := handler.SendHTTPRequest(a, &reqPayload, "POST", "/push")
7576 if err != nil {
76- return fmt.Errorf("error sending HTTP request: %w", err)
77+ log.Error("Error sending HTTP request", "error", err)
78+ return err
7779 }
7880
7981 var pushResponse common.PushResponse
8082 if err := json.Unmarshal(resp.Body, &pushResponse); err != nil {
81- return fmt.Errorf("error parsing response: %w", err)
83+ log.Error("Error parsing response", "error", err)
84+ return err
8285 }
8386
8487 if !pushResponse.Success {
85- return fmt.Errorf("push failed: %s", pushResponse.Message)
88+ log.Error("Push failed", "resp", pushResponse.Message)
89+ return fmt.Errorf(pushResponse.Message)
8690 }
8791
88- log.Info("Image pushed successfully", "image", imageName)
92+ //Remove the double quotes from the message
93+ message := strings.Trim(pushResponse.Message, "\"")
94+
95+ log.Info(message)
8996
9097 if pushResponse.CreateContainerURL != "" {
91- log.Info("Container creation URL:", "url", pushResponse.CreateContainerURL)
98+ log.Info("Container creation available", "url", pushResponse.CreateContainerURL)
9299 }
93100
94101 return nil
@@ -4,6 +4,7 @@ import (
4 "encoding/json"4 "encoding/json"
5 "fmt"5 "fmt"
6 "os"6 "os"
7+ "strings"
7 8
8 "github.com/bnema/gordon/internal/cli"9 "github.com/bnema/gordon/internal/cli"
9 "github.com/bnema/gordon/internal/cli/handler"10 "github.com/bnema/gordon/internal/cli/handler"
@@ -73,22 +74,28 @@ func pushImage(a *cli.App, imageName string) error {
73 74
74 resp, err := handler.SendHTTPRequest(a, &reqPayload, "POST", "/push")75 resp, err := handler.SendHTTPRequest(a, &reqPayload, "POST", "/push")
75 if err != nil {76 if err != nil {
76- return fmt.Errorf("error sending HTTP request: %w", err)77+ log.Error("Error sending HTTP request", "error", err)
78+ return err
77 }79 }
78 80
79 var pushResponse common.PushResponse81 var pushResponse common.PushResponse
80 if err := json.Unmarshal(resp.Body, &pushResponse); err != nil {82 if err := json.Unmarshal(resp.Body, &pushResponse); err != nil {
81- return fmt.Errorf("error parsing response: %w", err)83+ log.Error("Error parsing response", "error", err)
84+ return err
82 }85 }
83 86
84 if !pushResponse.Success {87 if !pushResponse.Success {
85- return fmt.Errorf("push failed: %s", pushResponse.Message)88+ log.Error("Push failed", "resp", pushResponse.Message)
89+ return fmt.Errorf(pushResponse.Message)
86 }90 }
87 91
88- log.Info("Image pushed successfully", "image", imageName)92+ //Remove the double quotes from the message
93+ message := strings.Trim(pushResponse.Message, "\"")
94+
95+ log.Info(message)
89 96
90 if pushResponse.CreateContainerURL != "" {97 if pushResponse.CreateContainerURL != "" {
91- log.Info("Container creation URL:", "url", pushResponse.CreateContainerURL)98+ log.Info("Container creation available", "url", pushResponse.CreateContainerURL)
92 }99 }
93 100
94 return nil101 return nil
M internal/httpserve/handlers/cli_endpoints.go +14 -14
@@ -89,7 +89,7 @@ func PostPush(c echo.Context, a *server.App) error {
8989
9090 return sendJSONResponse(c, http.StatusOK, common.PushResponse{
9191 Success: true,
92- Message: "Image pushed successfully",
92+ Message: "Image pushed and imported successfully",
9393 CreateContainerURL: createContainerURL,
9494 })
9595 }
@@ -101,7 +101,7 @@ func validateAndPreparePayload(c echo.Context) (*common.PushPayload, error) {
101101 }
102102
103103 if payload.ImageName == "" {
104- return nil, errors.New("Invalid image name")
104+ return nil, errors.New("invalid image name")
105105 }
106106
107107 return payload, nil
@@ -116,22 +116,22 @@ func saveAndImportImage(c echo.Context, a *server.App, payload *common.PushPaylo
116116
117117 imagePath, err := store.SaveImageToStorage(&a.Config, imageFileName, imageReader)
118118 if err != nil {
119- return "", fmt.Errorf("Failed to save image: %v", err)
119+ return "", fmt.Errorf("failed to save image: %v", err)
120120 }
121121
122122 imageID, err := docker.ImportImageToEngine(imagePath)
123123 if err != nil {
124124 store.RemoveFromStorage(imagePath)
125- return "", fmt.Errorf("Failed to import image: %v", err)
125+ return "", fmt.Errorf("failed to import image: %v", err)
126126 }
127127
128128 if imageID == "" {
129- return "", errors.New("Imported image ID is empty")
129+ return "", errors.New("imported image ID is empty")
130130 }
131131
132132 err = store.RemoveFromStorage(imagePath)
133133 if err != nil {
134- return "", fmt.Errorf("Failed to remove temporary image file: %v", err)
134+ return "", fmt.Errorf("failed to remove temporary image file: %v", err)
135135 }
136136
137137 payload.ImageID = imageID
@@ -253,7 +253,7 @@ func validateAndPrepareDeployPayload(c echo.Context) (*common.DeployPayload, err
253253 }
254254
255255 if payload.ImageName == "" {
256- return nil, errors.New("Invalid image name")
256+ return nil, errors.New("invalid image name")
257257 }
258258
259259 payload.Port = normalizePort(payload.Port)
@@ -287,22 +287,22 @@ func saveAndImportDeployImage(c echo.Context, a *server.App, payload *common.Dep
287287
288288 imagePath, err := store.SaveImageToStorage(&a.Config, imageFileName, imageReader)
289289 if err != nil {
290- return "", fmt.Errorf("Failed to save image: %v", err)
290+ return "", fmt.Errorf("failed to save image: %v", err)
291291 }
292292
293293 imageID, err := docker.ImportImageToEngine(imagePath)
294294 if err != nil {
295295 store.RemoveFromStorage(imagePath)
296- return "", fmt.Errorf("Failed to import image: %v", err)
296+ return "", fmt.Errorf("failed to import image: %v", err)
297297 }
298298
299299 if imageID == "" {
300- return "", errors.New("Imported image ID is empty")
300+ return "", errors.New("imported image ID is empty")
301301 }
302302
303303 err = store.RemoveFromStorage(imagePath)
304304 if err != nil {
305- return "", fmt.Errorf("Failed to remove temporary image file: %v", err)
305+ return "", fmt.Errorf("failed to remove temporary image file: %v", err)
306306 }
307307
308308 payload.ImageID = imageID
@@ -313,18 +313,18 @@ func saveAndImportDeployImage(c echo.Context, a *server.App, payload *common.Dep
313313 func createAndStartContainer(a *server.App, payload *common.DeployPayload) (string, error) {
314314 params, err := cmdparams.FromPayloadStructToCmdParams(payload, a, payload.ImageID)
315315 if err != nil {
316- return "", fmt.Errorf("Failed to create command parameters: %v", err)
316+ return "", fmt.Errorf("failed to create command parameters: %v", err)
317317 }
318318
319319 containerID, err := docker.CreateContainer(params)
320320 if err != nil {
321- return "", fmt.Errorf("Failed to create container: %v", err)
321+ return "", fmt.Errorf("failed to create container: %v", err)
322322 }
323323
324324 err = docker.StartContainer(containerID)
325325 if err != nil {
326326 docker.RemoveContainer(containerID)
327- return "", fmt.Errorf("Failed to start container: %v", err)
327+ return "", fmt.Errorf("failed to start container: %v", err)
328328 }
329329
330330 return containerID, nil
@@ -89,7 +89,7 @@ func PostPush(c echo.Context, a *server.App) error {
89 89
90 return sendJSONResponse(c, http.StatusOK, common.PushResponse{90 return sendJSONResponse(c, http.StatusOK, common.PushResponse{
91 Success: true,91 Success: true,
92- Message: "Image pushed successfully",92+ Message: "Image pushed and imported successfully",
93 CreateContainerURL: createContainerURL,93 CreateContainerURL: createContainerURL,
94 })94 })
95 }95 }
@@ -101,7 +101,7 @@ func validateAndPreparePayload(c echo.Context) (*common.PushPayload, error) {
101 }101 }
102 102
103 if payload.ImageName == "" {103 if payload.ImageName == "" {
104- return nil, errors.New("Invalid image name")104+ return nil, errors.New("invalid image name")
105 }105 }
106 106
107 return payload, nil107 return payload, nil
@@ -116,22 +116,22 @@ func saveAndImportImage(c echo.Context, a *server.App, payload *common.PushPaylo
116 116
117 imagePath, err := store.SaveImageToStorage(&a.Config, imageFileName, imageReader)117 imagePath, err := store.SaveImageToStorage(&a.Config, imageFileName, imageReader)
118 if err != nil {118 if err != nil {
119- return "", fmt.Errorf("Failed to save image: %v", err)119+ return "", fmt.Errorf("failed to save image: %v", err)
120 }120 }
121 121
122 imageID, err := docker.ImportImageToEngine(imagePath)122 imageID, err := docker.ImportImageToEngine(imagePath)
123 if err != nil {123 if err != nil {
124 store.RemoveFromStorage(imagePath)124 store.RemoveFromStorage(imagePath)
125- return "", fmt.Errorf("Failed to import image: %v", err)125+ return "", fmt.Errorf("failed to import image: %v", err)
126 }126 }
127 127
128 if imageID == "" {128 if imageID == "" {
129- return "", errors.New("Imported image ID is empty")129+ return "", errors.New("imported image ID is empty")
130 }130 }
131 131
132 err = store.RemoveFromStorage(imagePath)132 err = store.RemoveFromStorage(imagePath)
133 if err != nil {133 if err != nil {
134- return "", fmt.Errorf("Failed to remove temporary image file: %v", err)134+ return "", fmt.Errorf("failed to remove temporary image file: %v", err)
135 }135 }
136 136
137 payload.ImageID = imageID137 payload.ImageID = imageID
@@ -253,7 +253,7 @@ func validateAndPrepareDeployPayload(c echo.Context) (*common.DeployPayload, err
253 }253 }
254 254
255 if payload.ImageName == "" {255 if payload.ImageName == "" {
256- return nil, errors.New("Invalid image name")256+ return nil, errors.New("invalid image name")
257 }257 }
258 258
259 payload.Port = normalizePort(payload.Port)259 payload.Port = normalizePort(payload.Port)
@@ -287,22 +287,22 @@ func saveAndImportDeployImage(c echo.Context, a *server.App, payload *common.Dep
287 287
288 imagePath, err := store.SaveImageToStorage(&a.Config, imageFileName, imageReader)288 imagePath, err := store.SaveImageToStorage(&a.Config, imageFileName, imageReader)
289 if err != nil {289 if err != nil {
290- return "", fmt.Errorf("Failed to save image: %v", err)290+ return "", fmt.Errorf("failed to save image: %v", err)
291 }291 }
292 292
293 imageID, err := docker.ImportImageToEngine(imagePath)293 imageID, err := docker.ImportImageToEngine(imagePath)
294 if err != nil {294 if err != nil {
295 store.RemoveFromStorage(imagePath)295 store.RemoveFromStorage(imagePath)
296- return "", fmt.Errorf("Failed to import image: %v", err)296+ return "", fmt.Errorf("failed to import image: %v", err)
297 }297 }
298 298
299 if imageID == "" {299 if imageID == "" {
300- return "", errors.New("Imported image ID is empty")300+ return "", errors.New("imported image ID is empty")
301 }301 }
302 302
303 err = store.RemoveFromStorage(imagePath)303 err = store.RemoveFromStorage(imagePath)
304 if err != nil {304 if err != nil {
305- return "", fmt.Errorf("Failed to remove temporary image file: %v", err)305+ return "", fmt.Errorf("failed to remove temporary image file: %v", err)
306 }306 }
307 307
308 payload.ImageID = imageID308 payload.ImageID = imageID
@@ -313,18 +313,18 @@ func saveAndImportDeployImage(c echo.Context, a *server.App, payload *common.Dep
313 func createAndStartContainer(a *server.App, payload *common.DeployPayload) (string, error) {313 func createAndStartContainer(a *server.App, payload *common.DeployPayload) (string, error) {
314 params, err := cmdparams.FromPayloadStructToCmdParams(payload, a, payload.ImageID)314 params, err := cmdparams.FromPayloadStructToCmdParams(payload, a, payload.ImageID)
315 if err != nil {315 if err != nil {
316- return "", fmt.Errorf("Failed to create command parameters: %v", err)316+ return "", fmt.Errorf("failed to create command parameters: %v", err)
317 }317 }
318 318
319 containerID, err := docker.CreateContainer(params)319 containerID, err := docker.CreateContainer(params)
320 if err != nil {320 if err != nil {
321- return "", fmt.Errorf("Failed to create container: %v", err)321+ return "", fmt.Errorf("failed to create container: %v", err)
322 }322 }
323 323
324 err = docker.StartContainer(containerID)324 err = docker.StartContainer(containerID)
325 if err != nil {325 if err != nil {
326 docker.RemoveContainer(containerID)326 docker.RemoveContainer(containerID)
327- return "", fmt.Errorf("Failed to start container: %v", err)327+ return "", fmt.Errorf("failed to start container: %v", err)
328 }328 }
329 329
330 return containerID, nil330 return containerID, nil

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close