detached 26223e3

fix: container name display and deployment retry after removal in survey prompt

commit
26223e38de9da57e75659422b58352d7362b7b9c
author
Brice · · 2024-11-05 14:09 UTC
parent
b5fdca8
signature
unsigned
refs
tag: v0.1.14
2 files · +25 -21
M internal/cli/cmd/deploy.go +13 -12
@@ -3,6 +3,7 @@
33 package cmd
44
55 import (
6+ "bytes"
67 "encoding/json"
78 "errors"
89 "fmt"
@@ -115,6 +116,12 @@ func exportDockerImage(imageName string) (io.ReadCloser, int64, error) {
115116 }
116117
117118 func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain string) error {
119+ // Convert reader to bytes for reuse
120+ imageData, err := io.ReadAll(reader)
121+ if err != nil {
122+ return fmt.Errorf("failed to read image data: %w", err)
123+ }
124+
118125 log.Info("Attempting to deploy...",
119126 "image", imageName,
120127 "port", port,
@@ -122,13 +129,14 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str
122129 )
123130
124131 for {
132+ // Create new reader from bytes for each attempt
125133 reqPayload := common.RequestPayload{
126134 Type: "deploy",
127135 Payload: common.DeployPayload{
128136 Port: port,
129137 TargetDomain: targetDomain,
130138 ImageName: imageName,
131- Data: io.NopCloser(reader),
139+ Data: io.NopCloser(bytes.NewReader(imageData)),
132140 },
133141 }
134142
@@ -138,28 +146,21 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str
138146 if errors.As(err, &deployErr) {
139147 var deployResponse common.DeployResponse
140148 if jsonErr := json.Unmarshal([]byte(deployErr.RawResponse), &deployResponse); jsonErr == nil {
141- // Handle existing container case
142149 if deployErr.StatusCode == http.StatusConflict && deployResponse.ContainerID != "" {
143150 if err := handler.HandleExistingContainer(a, &deployResponse); err != nil {
144151 if strings.Contains(err.Error(), "cancelled by user") {
145152 log.Warn("Deployment cancelled by user")
146- } else {
147- log.Error("Failed to handle existing container", "error", err)
153+ return nil
148154 }
149- return nil
155+ log.Error("Failed to handle existing container", "error", err)
156+ return err
150157 }
151158 log.Info("Retrying deployment...")
152159 continue // Retry deployment
153160 }
154-
155- log.Error("Deployment failed",
156- "error", deployErr.Message,
157- "status_code", deployErr.StatusCode,
158- "container_id", deployResponse.ContainerID,
159- )
160161 }
161162 }
162- return nil
163+ return err
163164 }
164165
165166 var deployResponse common.DeployResponse
@@ -3,6 +3,7 @@
3 package cmd3 package cmd
4 4
5 import (5 import (
6+ "bytes"
6 "encoding/json"7 "encoding/json"
7 "errors"8 "errors"
8 "fmt"9 "fmt"
@@ -115,6 +116,12 @@ func exportDockerImage(imageName string) (io.ReadCloser, int64, error) {
115 }116 }
116 117
117 func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain string) error {118 func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain string) error {
119+ // Convert reader to bytes for reuse
120+ imageData, err := io.ReadAll(reader)
121+ if err != nil {
122+ return fmt.Errorf("failed to read image data: %w", err)
123+ }
124+
118 log.Info("Attempting to deploy...",125 log.Info("Attempting to deploy...",
119 "image", imageName,126 "image", imageName,
120 "port", port,127 "port", port,
@@ -122,13 +129,14 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str
122 )129 )
123 130
124 for {131 for {
132+ // Create new reader from bytes for each attempt
125 reqPayload := common.RequestPayload{133 reqPayload := common.RequestPayload{
126 Type: "deploy",134 Type: "deploy",
127 Payload: common.DeployPayload{135 Payload: common.DeployPayload{
128 Port: port,136 Port: port,
129 TargetDomain: targetDomain,137 TargetDomain: targetDomain,
130 ImageName: imageName,138 ImageName: imageName,
131- Data: io.NopCloser(reader),139+ Data: io.NopCloser(bytes.NewReader(imageData)),
132 },140 },
133 }141 }
134 142
@@ -138,28 +146,21 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str
138 if errors.As(err, &deployErr) {146 if errors.As(err, &deployErr) {
139 var deployResponse common.DeployResponse147 var deployResponse common.DeployResponse
140 if jsonErr := json.Unmarshal([]byte(deployErr.RawResponse), &deployResponse); jsonErr == nil {148 if jsonErr := json.Unmarshal([]byte(deployErr.RawResponse), &deployResponse); jsonErr == nil {
141- // Handle existing container case
142 if deployErr.StatusCode == http.StatusConflict && deployResponse.ContainerID != "" {149 if deployErr.StatusCode == http.StatusConflict && deployResponse.ContainerID != "" {
143 if err := handler.HandleExistingContainer(a, &deployResponse); err != nil {150 if err := handler.HandleExistingContainer(a, &deployResponse); err != nil {
144 if strings.Contains(err.Error(), "cancelled by user") {151 if strings.Contains(err.Error(), "cancelled by user") {
145 log.Warn("Deployment cancelled by user")152 log.Warn("Deployment cancelled by user")
146- } else {153+ return nil
147- log.Error("Failed to handle existing container", "error", err)
148 }154 }
149- return nil155+ log.Error("Failed to handle existing container", "error", err)
156+ return err
150 }157 }
151 log.Info("Retrying deployment...")158 log.Info("Retrying deployment...")
152 continue // Retry deployment159 continue // Retry deployment
153 }160 }
154-
155- log.Error("Deployment failed",
156- "error", deployErr.Message,
157- "status_code", deployErr.StatusCode,
158- "container_id", deployResponse.ContainerID,
159- )
160 }161 }
161 }162 }
162- return nil163+ return err
163 }164 }
164 165
165 var deployResponse common.DeployResponse166 var deployResponse common.DeployResponse
M internal/httpserve/handlers/cli_endpoints.go +12 -9
@@ -264,21 +264,24 @@ func PostDeploy(c echo.Context, a *server.App) error {
264264 if err != nil {
265265 if strings.Contains(err.Error(), "is already in use") {
266266 log.Warn("Container already exists", "error", err)
267- extractedID := extractContainerID(err.Error())
268- log.Info("Extracted container ID", "containerID", extractedID)
267+ existingContainerID := extractContainerID(err.Error())
268+ existingContainerName, _ := docker.GetContainerName(existingContainerID)
269+ // Remove the / from the container name
270+ existingContainerName = strings.TrimLeft(existingContainerName, "/")
269271
270- if extractedID == "" {
271- log.Error("Failed to extract container ID from error message")
272+ if existingContainerID == "" || existingContainerName == "" {
273+ log.Error("Failed to extract container ID or Name from error message")
272274 return sendJSONResponse(c, http.StatusConflict, DeployResponse{
273275 Success: false,
274- Message: "A container with this name already exists, but we couldn't extract its ID.",
276+ Message: "A container for this deploy already exists but could not be identified.",
275277 })
276278 }
277279
278280 return sendJSONResponse(c, http.StatusConflict, DeployResponse{
279- Success: false,
280- Message: "A container for this deploy already exists.",
281- ContainerID: extractedID,
281+ Success: false,
282+ Message: "A container for this deploy already exists.",
283+ ContainerID: existingContainerID,
284+ ContainerName: existingContainerName,
282285 })
283286 }
284287 log.Error("Failed to create or start container", "error", err)
@@ -305,7 +308,7 @@ func PostDeploy(c echo.Context, a *server.App) error {
305308 return sendJSONResponse(c, http.StatusOK, response)
306309 }
307310
308-// is already in use by 08433f639cb1c01254d43f234360bfa793aa8c33b29e8de8ce42b0706c0090ba. example
311+// extractContainerID extracts the container ID from the error message
309312 func extractContainerID(errorMessage string) string {
310313 re := regexp.MustCompile(`by\s+([0-9a-f]+)\.`)
311314 match := re.FindStringSubmatch(errorMessage)
@@ -264,21 +264,24 @@ func PostDeploy(c echo.Context, a *server.App) error {
264 if err != nil {264 if err != nil {
265 if strings.Contains(err.Error(), "is already in use") {265 if strings.Contains(err.Error(), "is already in use") {
266 log.Warn("Container already exists", "error", err)266 log.Warn("Container already exists", "error", err)
267- extractedID := extractContainerID(err.Error())267+ existingContainerID := extractContainerID(err.Error())
268- log.Info("Extracted container ID", "containerID", extractedID)268+ existingContainerName, _ := docker.GetContainerName(existingContainerID)
269+ // Remove the / from the container name
270+ existingContainerName = strings.TrimLeft(existingContainerName, "/")
269 271
270- if extractedID == "" {272+ if existingContainerID == "" || existingContainerName == "" {
271- log.Error("Failed to extract container ID from error message")273+ log.Error("Failed to extract container ID or Name from error message")
272 return sendJSONResponse(c, http.StatusConflict, DeployResponse{274 return sendJSONResponse(c, http.StatusConflict, DeployResponse{
273 Success: false,275 Success: false,
274- Message: "A container with this name already exists, but we couldn't extract its ID.",276+ Message: "A container for this deploy already exists but could not be identified.",
275 })277 })
276 }278 }
277 279
278 return sendJSONResponse(c, http.StatusConflict, DeployResponse{280 return sendJSONResponse(c, http.StatusConflict, DeployResponse{
279- Success: false,281+ Success: false,
280- Message: "A container for this deploy already exists.",282+ Message: "A container for this deploy already exists.",
281- ContainerID: extractedID,283+ ContainerID: existingContainerID,
284+ ContainerName: existingContainerName,
282 })285 })
283 }286 }
284 log.Error("Failed to create or start container", "error", err)287 log.Error("Failed to create or start container", "error", err)
@@ -305,7 +308,7 @@ func PostDeploy(c echo.Context, a *server.App) error {
305 return sendJSONResponse(c, http.StatusOK, response)308 return sendJSONResponse(c, http.StatusOK, response)
306 }309 }
307 310
308-// is already in use by 08433f639cb1c01254d43f234360bfa793aa8c33b29e8de8ce42b0706c0090ba. example311+// extractContainerID extracts the container ID from the error message
309 func extractContainerID(errorMessage string) string {312 func extractContainerID(errorMessage string) string {
310 re := regexp.MustCompile(`by\s+([0-9a-f]+)\.`)313 re := regexp.MustCompile(`by\s+([0-9a-f]+)\.`)
311 match := re.FindStringSubmatch(errorMessage)314 match := re.FindStringSubmatch(errorMessage)

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