Backend: Improve deployment process and error handling
- Enhance error handling in deployImage function - Add container ID to deployment failure logs - Refactor waitForDeployment function to include container ID - Improve logging throughout the deployment process - Add function to extract container ID from error messages - Remove redundant debug logs and clean up code structure
- commit
- 1576ce623bb5e8552780f066fd410140cbef1c81
- author
- bamen · · 2024-09-26 17:06 UTC
- committer
- bamen · · 2024-09-26 20:02 UTC
- parent
- 28124a3
- signature
- unsigned
4 files · +77 -42
M internal/cli/cmd/deploy.go +34 -25
| @@ -4,6 +4,7 @@ package cmd | |||
| 4 | 4 | ||
| 5 | 5 | import ( | |
| 6 | 6 | "encoding/json" | |
| 7 | + | "errors" | |
| 7 | 8 | "fmt" | |
| 8 | 9 | "io" | |
| 9 | 10 | "net/http" | |
| @@ -59,18 +60,8 @@ func NewDeployCommand(a *cli.App) *cobra.Command { | |||
| 59 | 60 | log.Info("Image exported successfully", "image", imageName, "size", fmt.Sprintf("%.2fMB", sizeInMB)) | |
| 60 | 61 | ||
| 61 | 62 | if err := deployImage(a, reader, imageName, port, targetDomain); err != nil { | |
| 62 | - | if deployErr, ok := err.(*common.DeploymentError); ok { | |
| 63 | - | log.Error("Deployment failed", | |
| 64 | - | "status_code", deployErr.StatusCode, | |
| 65 | - | "message", deployErr.Message, | |
| 66 | - | ) | |
| 67 | - | } else { | |
| 68 | - | log.Error("Deployment failed", "error", err) | |
| 69 | - | } | |
| 70 | - | return | |
| 63 | + | os.Exit(1) | |
| 71 | 64 | } | |
| 72 | - | ||
| 73 | - | log.Info("Deployment successful!") | |
| 74 | 65 | }, | |
| 75 | 66 | } | |
| 76 | 67 | ||
| @@ -124,6 +115,9 @@ func exportDockerImage(imageName string) (io.ReadCloser, int64, error) { | |||
| 124 | 115 | } | |
| 125 | 116 | ||
| 126 | 117 | func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain string) error { | |
| 118 | + | ||
| 119 | + | log.Info("Attempting to deploy...", "image", imageName, "port", port, "target_domain", targetDomain) | |
| 120 | + | ||
| 127 | 121 | reqPayload := common.RequestPayload{ | |
| 128 | 122 | Type: "deploy", | |
| 129 | 123 | Payload: common.DeployPayload{ | |
| @@ -136,33 +130,45 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str | |||
| 136 | 130 | ||
| 137 | 131 | resp, err := handler.SendHTTPRequest(a, &reqPayload, "POST", "/deploy") | |
| 138 | 132 | if err != nil { | |
| 139 | - | if deployErr, ok := err.(*common.DeploymentError); ok { | |
| 140 | - | log.Error("Deployment failed", | |
| 141 | - | "status_code", deployErr.StatusCode, | |
| 142 | - | "message", deployErr.Message, | |
| 143 | - | ) | |
| 144 | - | } else { | |
| 145 | - | log.Error("Error sending HTTP request", "error", err) | |
| 133 | + | var deployErr *common.DeploymentError | |
| 134 | + | if errors.As(err, &deployErr) { | |
| 135 | + | // Try to parse the raw response to get the container ID | |
| 136 | + | var deployResponse common.DeployResponse | |
| 137 | + | if jsonErr := json.Unmarshal([]byte(deployErr.RawResponse), &deployResponse); jsonErr == nil { | |
| 138 | + | log.Error("Deployment failed", | |
| 139 | + | "error", deployErr.Message, | |
| 140 | + | "status_code", deployErr.StatusCode, | |
| 141 | + | "container_id", deployResponse.ContainerID, | |
| 142 | + | ) | |
| 143 | + | } else { | |
| 144 | + | // If parsing fails, just log the error without the container ID | |
| 145 | + | log.Error("Deployment failed", "error", deployErr.Message, "status_code", deployErr.StatusCode) | |
| 146 | + | } | |
| 147 | + | // Return nil to prevent further error logging | |
| 148 | + | return nil | |
| 146 | 149 | } | |
| 147 | - | return nil // Return nil to prevent double-logging | |
| 150 | + | log.Error("Error sending HTTP request", "error", err) | |
| 151 | + | return nil | |
| 148 | 152 | } | |
| 149 | 153 | ||
| 150 | 154 | var deployResponse common.DeployResponse | |
| 151 | 155 | if err := json.Unmarshal(resp.Body, &deployResponse); err != nil { | |
| 152 | - | log.Error("Error parsing response", "error", err) | |
| 156 | + | log.Error("Error parsing response", "error", err, "response", string(resp.Body)) | |
| 153 | 157 | return nil | |
| 154 | 158 | } | |
| 155 | 159 | ||
| 156 | 160 | if !deployResponse.Success { | |
| 157 | - | log.Error("Deployment failed", "message", deployResponse.Message) | |
| 161 | + | log.Error("Deployment failed", | |
| 162 | + | "message", deployResponse.Message, | |
| 163 | + | "container_id", deployResponse.ContainerID, | |
| 164 | + | ) | |
| 158 | 165 | return nil | |
| 159 | 166 | } | |
| 160 | 167 | ||
| 161 | - | log.Info("Application deployed", "domain", deployResponse.Domain) | |
| 162 | - | return waitForDeployment(deployResponse.Domain) | |
| 168 | + | return waitForDeployment(deployResponse.Domain, deployResponse.ContainerID) | |
| 163 | 169 | } | |
| 164 | 170 | ||
| 165 | - | func waitForDeployment(domain string) error { | |
| 171 | + | func waitForDeployment(domain string, containerID string) error { | |
| 166 | 172 | client := &http.Client{Timeout: 10 * time.Second} | |
| 167 | 173 | maxRetries := 20 | |
| 168 | 174 | retryInterval := time.Second | |
| @@ -173,6 +179,9 @@ func waitForDeployment(domain string) error { | |||
| 173 | 179 | if err == nil { | |
| 174 | 180 | defer resp.Body.Close() | |
| 175 | 181 | if resp.StatusCode == http.StatusOK { | |
| 182 | + | log.Info("Deployment successful", | |
| 183 | + | "domain", domain, | |
| 184 | + | "container_id", containerID) | |
| 176 | 185 | return nil | |
| 177 | 186 | } | |
| 178 | 187 | // Check for error messages in the response body | |
| @@ -181,7 +190,7 @@ func waitForDeployment(domain string) error { | |||
| 181 | 190 | return fmt.Errorf("deployment failed: %s", string(body)) | |
| 182 | 191 | } | |
| 183 | 192 | } | |
| 184 | - | log.Warn("Deployment not ready yet, retrying", "attempt", fmt.Sprintf("%d/20", i+1)) | |
| 193 | + | log.Warn("Deployment not ready yet, retrying", "attempt", fmt.Sprintf("%d/%d", i+1, maxRetries)) | |
| 185 | 194 | time.Sleep(retryInterval) | |
| 186 | 195 | } | |
| 187 | 196 | ||
| @@ -4,6 +4,7 @@ package cmd | |||||
| 4 | 4 | ||||
| 5 | import ( | 5 | import ( | ||
| 6 | "encoding/json" | 6 | "encoding/json" | ||
| 7 | + | "errors" | |||
| 7 | "fmt" | 8 | "fmt" | ||
| 8 | "io" | 9 | "io" | ||
| 9 | "net/http" | 10 | "net/http" | ||
| @@ -59,18 +60,8 @@ func NewDeployCommand(a *cli.App) *cobra.Command { | |||||
| 59 | log.Info("Image exported successfully", "image", imageName, "size", fmt.Sprintf("%.2fMB", sizeInMB)) | 60 | log.Info("Image exported successfully", "image", imageName, "size", fmt.Sprintf("%.2fMB", sizeInMB)) | ||
| 60 | 61 | ||||
| 61 | if err := deployImage(a, reader, imageName, port, targetDomain); err != nil { | 62 | if err := deployImage(a, reader, imageName, port, targetDomain); err != nil { | ||
| 62 | - | if deployErr, ok := err.(*common.DeploymentError); ok { | 63 | + | os.Exit(1) |
| 63 | - | log.Error("Deployment failed", | |||
| 64 | - | "status_code", deployErr.StatusCode, | |||
| 65 | - | "message", deployErr.Message, | |||
| 66 | - | ) | |||
| 67 | - | } else { | |||
| 68 | - | log.Error("Deployment failed", "error", err) | |||
| 69 | - | } | |||
| 70 | - | return | |||
| 71 | } | 64 | } | ||
| 72 | - | ||||
| 73 | - | log.Info("Deployment successful!") | |||
| 74 | }, | 65 | }, | ||
| 75 | } | 66 | } | ||
| 76 | 67 | ||||
| @@ -124,6 +115,9 @@ func exportDockerImage(imageName string) (io.ReadCloser, int64, error) { | |||||
| 124 | } | 115 | } | ||
| 125 | 116 | ||||
| 126 | 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 | + | ||||
| 119 | + | log.Info("Attempting to deploy...", "image", imageName, "port", port, "target_domain", targetDomain) | |||
| 120 | + | ||||
| 127 | reqPayload := common.RequestPayload{ | 121 | reqPayload := common.RequestPayload{ | ||
| 128 | Type: "deploy", | 122 | Type: "deploy", | ||
| 129 | Payload: common.DeployPayload{ | 123 | Payload: common.DeployPayload{ | ||
| @@ -136,33 +130,45 @@ func deployImage(a *cli.App, reader io.Reader, imageName, port, targetDomain str | |||||
| 136 | 130 | ||||
| 137 | resp, err := handler.SendHTTPRequest(a, &reqPayload, "POST", "/deploy") | 131 | resp, err := handler.SendHTTPRequest(a, &reqPayload, "POST", "/deploy") | ||
| 138 | if err != nil { | 132 | if err != nil { | ||
| 139 | - | if deployErr, ok := err.(*common.DeploymentError); ok { | 133 | + | var deployErr *common.DeploymentError |
| 140 | - | log.Error("Deployment failed", | 134 | + | if errors.As(err, &deployErr) { |
| 141 | - | "status_code", deployErr.StatusCode, | 135 | + | // Try to parse the raw response to get the container ID |
| 142 | - | "message", deployErr.Message, | 136 | + | var deployResponse common.DeployResponse |
| 143 | - | ) | 137 | + | if jsonErr := json.Unmarshal([]byte(deployErr.RawResponse), &deployResponse); jsonErr == nil { |
| 144 | - | } else { | 138 | + | log.Error("Deployment failed", |
| 145 | - | log.Error("Error sending HTTP request", "error", err) | 139 | + | "error", deployErr.Message, |
| 140 | + | "status_code", deployErr.StatusCode, | |||
| 141 | + | "container_id", deployResponse.ContainerID, | |||
| 142 | + | ) | |||
| 143 | + | } else { | |||
| 144 | + | // If parsing fails, just log the error without the container ID | |||
| 145 | + | log.Error("Deployment failed", "error", deployErr.Message, "status_code", deployErr.StatusCode) | |||
| 146 | + | } | |||
| 147 | + | // Return nil to prevent further error logging | |||
| 148 | + | return nil | |||
| 146 | } | 149 | } | ||
| 147 | - | return nil // Return nil to prevent double-logging | 150 | + | log.Error("Error sending HTTP request", "error", err) |
| 151 | + | return nil | |||
| 148 | } | 152 | } | ||
| 149 | 153 | ||||
| 150 | var deployResponse common.DeployResponse | 154 | var deployResponse common.DeployResponse | ||
| 151 | if err := json.Unmarshal(resp.Body, &deployResponse); err != nil { | 155 | if err := json.Unmarshal(resp.Body, &deployResponse); err != nil { | ||
| 152 | - | log.Error("Error parsing response", "error", err) | 156 | + | log.Error("Error parsing response", "error", err, "response", string(resp.Body)) |
| 153 | return nil | 157 | return nil | ||
| 154 | } | 158 | } | ||
| 155 | 159 | ||||
| 156 | if !deployResponse.Success { | 160 | if !deployResponse.Success { | ||
| 157 | - | log.Error("Deployment failed", "message", deployResponse.Message) | 161 | + | log.Error("Deployment failed", |
| 162 | + | "message", deployResponse.Message, | |||
| 163 | + | "container_id", deployResponse.ContainerID, | |||
| 164 | + | ) | |||
| 158 | return nil | 165 | return nil | ||
| 159 | } | 166 | } | ||
| 160 | 167 | ||||
| 161 | - | log.Info("Application deployed", "domain", deployResponse.Domain) | 168 | + | return waitForDeployment(deployResponse.Domain, deployResponse.ContainerID) |
| 162 | - | return waitForDeployment(deployResponse.Domain) | |||
| 163 | } | 169 | } | ||
| 164 | 170 | ||||
| 165 | - | func waitForDeployment(domain string) error { | 171 | + | func waitForDeployment(domain string, containerID string) error { |
| 166 | client := &http.Client{Timeout: 10 * time.Second} | 172 | client := &http.Client{Timeout: 10 * time.Second} | ||
| 167 | maxRetries := 20 | 173 | maxRetries := 20 | ||
| 168 | retryInterval := time.Second | 174 | retryInterval := time.Second | ||
| @@ -173,6 +179,9 @@ func waitForDeployment(domain string) error { | |||||
| 173 | if err == nil { | 179 | if err == nil { | ||
| 174 | defer resp.Body.Close() | 180 | defer resp.Body.Close() | ||
| 175 | if resp.StatusCode == http.StatusOK { | 181 | if resp.StatusCode == http.StatusOK { | ||
| 182 | + | log.Info("Deployment successful", | |||
| 183 | + | "domain", domain, | |||
| 184 | + | "container_id", containerID) | |||
| 176 | return nil | 185 | return nil | ||
| 177 | } | 186 | } | ||
| 178 | // Check for error messages in the response body | 187 | // Check for error messages in the response body | ||
| @@ -181,7 +190,7 @@ func waitForDeployment(domain string) error { | |||||
| 181 | return fmt.Errorf("deployment failed: %s", string(body)) | 190 | return fmt.Errorf("deployment failed: %s", string(body)) | ||
| 182 | } | 191 | } | ||
| 183 | } | 192 | } | ||
| 184 | - | log.Warn("Deployment not ready yet, retrying", "attempt", fmt.Sprintf("%d/20", i+1)) | 193 | + | log.Warn("Deployment not ready yet, retrying", "attempt", fmt.Sprintf("%d/%d", i+1, maxRetries)) |
| 185 | time.Sleep(retryInterval) | 194 | time.Sleep(retryInterval) | ||
| 186 | } | 195 | } | ||
| 187 | 196 | ||||
M internal/httpserve/handler/cli-endpoints.go +31 -15
| @@ -170,9 +170,6 @@ func generateCreateContainerURL(a *server.App, shortID string) string { | |||
| 170 | 170 | ||
| 171 | 171 | // PostDeploy handles the container deployment request | |
| 172 | 172 | func PostDeploy(c echo.Context, a *server.App) error { | |
| 173 | - | // Debug | |
| 174 | - | log.Info("Starting deployment process", "handler", "PostDeploy", "requestID", c.Response().Header().Get(echo.HeaderXRequestID)) | |
| 175 | - | ||
| 176 | 173 | payload, err := validateAndPrepareDeployPayload(c) | |
| 177 | 174 | if err != nil { | |
| 178 | 175 | // Debug | |
| @@ -182,10 +179,8 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||
| 182 | 179 | Message: fmt.Sprintf("Invalid payload: %v", err), | |
| 183 | 180 | }) | |
| 184 | 181 | } | |
| 185 | - | // Debug | |
| 186 | - | log.Info("Payload validated and prepared", "payload", payload) | |
| 187 | 182 | ||
| 188 | - | imagePath, err := saveAndImportDeployImage(c, a, payload) | |
| 183 | + | _, err = saveAndImportDeployImage(c, a, payload) | |
| 189 | 184 | if err != nil { | |
| 190 | 185 | // Debug | |
| 191 | 186 | log.Error("Failed to save and import image", "error", err) | |
| @@ -194,16 +189,26 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||
| 194 | 189 | Message: fmt.Sprintf("Failed to save or import image: %v", err), | |
| 195 | 190 | }) | |
| 196 | 191 | } | |
| 197 | - | // Debug | |
| 198 | - | log.Info("Image saved and imported successfully", "imagePath", imagePath) | |
| 199 | 192 | ||
| 200 | 193 | containerID, err := createAndStartContainer(a, payload) | |
| 201 | 194 | if err != nil { | |
| 202 | 195 | if strings.Contains(err.Error(), "is already in use") { | |
| 203 | 196 | log.Warn("Container already exists", "error", err) | |
| 197 | + | extractedID := extractContainerID(err.Error()) | |
| 198 | + | log.Info("Extracted container ID", "containerID", extractedID) | |
| 199 | + | ||
| 200 | + | if extractedID == "" { | |
| 201 | + | log.Error("Failed to extract container ID from error message") | |
| 202 | + | return sendJSONResponse(c, http.StatusConflict, DeployResponse{ | |
| 203 | + | Success: false, | |
| 204 | + | Message: "A container with this name already exists, but we couldn't extract its ID.", | |
| 205 | + | }) | |
| 206 | + | } | |
| 207 | + | ||
| 204 | 208 | return sendJSONResponse(c, http.StatusConflict, DeployResponse{ | |
| 205 | - | Success: false, | |
| 206 | - | Message: fmt.Sprintf("Container with name '%s' already exists. Please remove it first or use a different name.", payload.ImageName), | |
| 209 | + | Success: false, | |
| 210 | + | Message: fmt.Sprintf("A container for this deploy already exists."), | |
| 211 | + | ContainerID: extractedID, | |
| 207 | 212 | }) | |
| 208 | 213 | } | |
| 209 | 214 | log.Error("Failed to create or start container", "error", err) | |
| @@ -212,9 +217,6 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||
| 212 | 217 | Message: fmt.Sprintf("Failed to create or start container: %v", err), | |
| 213 | 218 | }) | |
| 214 | 219 | } | |
| 215 | - | // Debug | |
| 216 | - | log.Info("Container created and started successfully", "containerID", containerID) | |
| 217 | - | ||
| 218 | 220 | response := DeployResponse{ | |
| 219 | 221 | Success: true, | |
| 220 | 222 | Message: "Deployment successful", | |
| @@ -222,12 +224,26 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||
| 222 | 224 | ContainerID: containerID, | |
| 223 | 225 | } | |
| 224 | 226 | ||
| 225 | - | // Debug | |
| 226 | - | log.Info("Deployment completed successfully", "response", response) | |
| 227 | + | // Debug: Verify containerID in response | |
| 228 | + | if response.ContainerID != containerID { | |
| 229 | + | log.Error("Container ID mismatch", "responseID", response.ContainerID, "actualID", containerID) | |
| 230 | + | } else { | |
| 231 | + | log.Info("Container ID successfully stored in response", "containerID", containerID) | |
| 232 | + | } | |
| 227 | 233 | ||
| 228 | 234 | return sendJSONResponse(c, http.StatusOK, response) | |
| 229 | 235 | } | |
| 230 | 236 | ||
| 237 | + | // is already in use by 08433f639cb1c01254d43f234360bfa793aa8c33b29e8de8ce42b0706c0090ba. example | |
| 238 | + | func extractContainerID(errorMessage string) string { | |
| 239 | + | re := regexp.MustCompile(`by\s+([0-9a-f]+)\.`) | |
| 240 | + | match := re.FindStringSubmatch(errorMessage) | |
| 241 | + | if len(match) > 1 { | |
| 242 | + | return match[1] | |
| 243 | + | } | |
| 244 | + | return "" | |
| 245 | + | } | |
| 246 | + | ||
| 231 | 247 | // validateAndPrepareDeployPayload prepares the deployment payload | |
| 232 | 248 | func validateAndPrepareDeployPayload(c echo.Context) (*common.DeployPayload, error) { | |
| 233 | 249 | payload := &common.DeployPayload{ | |
| @@ -170,9 +170,6 @@ func generateCreateContainerURL(a *server.App, shortID string) string { | |||||
| 170 | 170 | ||||
| 171 | // PostDeploy handles the container deployment request | 171 | // PostDeploy handles the container deployment request | ||
| 172 | func PostDeploy(c echo.Context, a *server.App) error { | 172 | func PostDeploy(c echo.Context, a *server.App) error { | ||
| 173 | - | // Debug | |||
| 174 | - | log.Info("Starting deployment process", "handler", "PostDeploy", "requestID", c.Response().Header().Get(echo.HeaderXRequestID)) | |||
| 175 | - | ||||
| 176 | payload, err := validateAndPrepareDeployPayload(c) | 173 | payload, err := validateAndPrepareDeployPayload(c) | ||
| 177 | if err != nil { | 174 | if err != nil { | ||
| 178 | // Debug | 175 | // Debug | ||
| @@ -182,10 +179,8 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||||
| 182 | Message: fmt.Sprintf("Invalid payload: %v", err), | 179 | Message: fmt.Sprintf("Invalid payload: %v", err), | ||
| 183 | }) | 180 | }) | ||
| 184 | } | 181 | } | ||
| 185 | - | // Debug | |||
| 186 | - | log.Info("Payload validated and prepared", "payload", payload) | |||
| 187 | 182 | ||||
| 188 | - | imagePath, err := saveAndImportDeployImage(c, a, payload) | 183 | + | _, err = saveAndImportDeployImage(c, a, payload) |
| 189 | if err != nil { | 184 | if err != nil { | ||
| 190 | // Debug | 185 | // Debug | ||
| 191 | log.Error("Failed to save and import image", "error", err) | 186 | log.Error("Failed to save and import image", "error", err) | ||
| @@ -194,16 +189,26 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||||
| 194 | Message: fmt.Sprintf("Failed to save or import image: %v", err), | 189 | Message: fmt.Sprintf("Failed to save or import image: %v", err), | ||
| 195 | }) | 190 | }) | ||
| 196 | } | 191 | } | ||
| 197 | - | // Debug | |||
| 198 | - | log.Info("Image saved and imported successfully", "imagePath", imagePath) | |||
| 199 | 192 | ||||
| 200 | containerID, err := createAndStartContainer(a, payload) | 193 | containerID, err := createAndStartContainer(a, payload) | ||
| 201 | if err != nil { | 194 | if err != nil { | ||
| 202 | if strings.Contains(err.Error(), "is already in use") { | 195 | if strings.Contains(err.Error(), "is already in use") { | ||
| 203 | log.Warn("Container already exists", "error", err) | 196 | log.Warn("Container already exists", "error", err) | ||
| 197 | + | extractedID := extractContainerID(err.Error()) | |||
| 198 | + | log.Info("Extracted container ID", "containerID", extractedID) | |||
| 199 | + | ||||
| 200 | + | if extractedID == "" { | |||
| 201 | + | log.Error("Failed to extract container ID from error message") | |||
| 202 | + | return sendJSONResponse(c, http.StatusConflict, DeployResponse{ | |||
| 203 | + | Success: false, | |||
| 204 | + | Message: "A container with this name already exists, but we couldn't extract its ID.", | |||
| 205 | + | }) | |||
| 206 | + | } | |||
| 207 | + | ||||
| 204 | return sendJSONResponse(c, http.StatusConflict, DeployResponse{ | 208 | return sendJSONResponse(c, http.StatusConflict, DeployResponse{ | ||
| 205 | - | Success: false, | 209 | + | Success: false, |
| 206 | - | Message: fmt.Sprintf("Container with name '%s' already exists. Please remove it first or use a different name.", payload.ImageName), | 210 | + | Message: fmt.Sprintf("A container for this deploy already exists."), |
| 211 | + | ContainerID: extractedID, | |||
| 207 | }) | 212 | }) | ||
| 208 | } | 213 | } | ||
| 209 | log.Error("Failed to create or start container", "error", err) | 214 | log.Error("Failed to create or start container", "error", err) | ||
| @@ -212,9 +217,6 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||||
| 212 | Message: fmt.Sprintf("Failed to create or start container: %v", err), | 217 | Message: fmt.Sprintf("Failed to create or start container: %v", err), | ||
| 213 | }) | 218 | }) | ||
| 214 | } | 219 | } | ||
| 215 | - | // Debug | |||
| 216 | - | log.Info("Container created and started successfully", "containerID", containerID) | |||
| 217 | - | ||||
| 218 | response := DeployResponse{ | 220 | response := DeployResponse{ | ||
| 219 | Success: true, | 221 | Success: true, | ||
| 220 | Message: "Deployment successful", | 222 | Message: "Deployment successful", | ||
| @@ -222,12 +224,26 @@ func PostDeploy(c echo.Context, a *server.App) error { | |||||
| 222 | ContainerID: containerID, | 224 | ContainerID: containerID, | ||
| 223 | } | 225 | } | ||
| 224 | 226 | ||||
| 225 | - | // Debug | 227 | + | // Debug: Verify containerID in response |
| 226 | - | log.Info("Deployment completed successfully", "response", response) | 228 | + | if response.ContainerID != containerID { |
| 229 | + | log.Error("Container ID mismatch", "responseID", response.ContainerID, "actualID", containerID) | |||
| 230 | + | } else { | |||
| 231 | + | log.Info("Container ID successfully stored in response", "containerID", containerID) | |||
| 232 | + | } | |||
| 227 | 233 | ||||
| 228 | return sendJSONResponse(c, http.StatusOK, response) | 234 | return sendJSONResponse(c, http.StatusOK, response) | ||
| 229 | } | 235 | } | ||
| 230 | 236 | ||||
| 237 | + | // is already in use by 08433f639cb1c01254d43f234360bfa793aa8c33b29e8de8ce42b0706c0090ba. example | |||
| 238 | + | func extractContainerID(errorMessage string) string { | |||
| 239 | + | re := regexp.MustCompile(`by\s+([0-9a-f]+)\.`) | |||
| 240 | + | match := re.FindStringSubmatch(errorMessage) | |||
| 241 | + | if len(match) > 1 { | |||
| 242 | + | return match[1] | |||
| 243 | + | } | |||
| 244 | + | return "" | |||
| 245 | + | } | |||
| 246 | + | ||||
| 231 | // validateAndPrepareDeployPayload prepares the deployment payload | 247 | // validateAndPrepareDeployPayload prepares the deployment payload | ||
| 232 | func validateAndPrepareDeployPayload(c echo.Context) (*common.DeployPayload, error) { | 248 | func validateAndPrepareDeployPayload(c echo.Context) (*common.DeployPayload, error) { | ||
| 233 | payload := &common.DeployPayload{ | 249 | payload := &common.DeployPayload{ | ||
M internal/httpserve/handler/containers.go +0 -2
| @@ -2,7 +2,6 @@ package handler | |||
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "fmt" | |
| 5 | - | "log" | |
| 6 | 5 | "net/http" | |
| 7 | 6 | "strings" | |
| 8 | 7 | "sync" | |
| @@ -41,7 +40,6 @@ func safelyInteractWithIDMap(op MapOperation, key string, value ...string) (stri | |||
| 41 | 40 | case Update: | |
| 42 | 41 | if len(value) > 0 { | |
| 43 | 42 | idMap[key] = value[0] | |
| 44 | - | log.Printf("Updated mapping: %s -> %s", key, value[0]) | |
| 45 | 43 | } | |
| 46 | 44 | return "", true | |
| 47 | 45 | case Delete: | |
| @@ -2,7 +2,6 @@ package handler | |||||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | "fmt" | 4 | "fmt" | ||
| 5 | - | "log" | |||
| 6 | "net/http" | 5 | "net/http" | ||
| 7 | "strings" | 6 | "strings" | ||
| 8 | "sync" | 7 | "sync" | ||
| @@ -41,7 +40,6 @@ func safelyInteractWithIDMap(op MapOperation, key string, value ...string) (stri | |||||
| 41 | case Update: | 40 | case Update: | ||
| 42 | if len(value) > 0 { | 41 | if len(value) > 0 { | ||
| 43 | idMap[key] = value[0] | 42 | idMap[key] = value[0] | ||
| 44 | - | log.Printf("Updated mapping: %s -> %s", key, value[0]) | |||
| 45 | } | 43 | } | ||
| 46 | return "", true | 44 | return "", true | ||
| 47 | case Delete: | 45 | case Delete: | ||
M pkg/docker/containers.go +12 -0
| @@ -316,6 +316,18 @@ func GetContainerInfo(containerID string) (types.ContainerJSON, error) { | |||
| 316 | 316 | return containerInfo, nil | |
| 317 | 317 | } | |
| 318 | 318 | ||
| 319 | + | // GetContainerName returns the name of a container | |
| 320 | + | func GetContainerName(containerID string) (string, error) { | |
| 321 | + | containerInfo, err := GetContainerInfo(containerID) | |
| 322 | + | if err != nil { | |
| 323 | + | return "", err | |
| 324 | + | } | |
| 325 | + | ||
| 326 | + | // Debug | |
| 327 | + | fmt.Printf("Container name: %s\n", containerInfo.Name) | |
| 328 | + | return containerInfo.Name, nil | |
| 329 | + | } | |
| 330 | + | ||
| 319 | 331 | // UpdateContainerConfig updates the configuration of an existing container. | |
| 320 | 332 | func UpdateContainerConfig(containerID string, newConfig *container.Config, newHostConfig *container.HostConfig, newNetworkingConfig *network.NetworkingConfig) error { | |
| 321 | 333 | ctx := context.Background() | |
| @@ -316,6 +316,18 @@ func GetContainerInfo(containerID string) (types.ContainerJSON, error) { | |||||
| 316 | return containerInfo, nil | 316 | return containerInfo, nil | ||
| 317 | } | 317 | } | ||
| 318 | 318 | ||||
| 319 | + | // GetContainerName returns the name of a container | |||
| 320 | + | func GetContainerName(containerID string) (string, error) { | |||
| 321 | + | containerInfo, err := GetContainerInfo(containerID) | |||
| 322 | + | if err != nil { | |||
| 323 | + | return "", err | |||
| 324 | + | } | |||
| 325 | + | ||||
| 326 | + | // Debug | |||
| 327 | + | fmt.Printf("Container name: %s\n", containerInfo.Name) | |||
| 328 | + | return containerInfo.Name, nil | |||
| 329 | + | } | |||
| 330 | + | ||||
| 319 | // UpdateContainerConfig updates the configuration of an existing container. | 331 | // UpdateContainerConfig updates the configuration of an existing container. | ||
| 320 | func UpdateContainerConfig(containerID string, newConfig *container.Config, newHostConfig *container.HostConfig, newNetworkingConfig *network.NetworkingConfig) error { | 332 | func UpdateContainerConfig(containerID string, newConfig *container.Config, newHostConfig *container.HostConfig, newNetworkingConfig *network.NetworkingConfig) error { | ||
| 321 | ctx := context.Background() | 333 | ctx := context.Background() | ||