package deployer import ( "context" "fmt" "log" ) // rollback cleans up a failed deployment by removing the container, // deleting the NPM proxy host, and updating the instance status. // Errors during rollback are logged but do not prevent other cleanup steps. func (d *Deployer) rollback(ctx context.Context, deployID string, containerID string, npmProxyID int, instanceID string) { d.logDeploy(deployID, "Rolling back failed deployment", "warn") // Remove the container if it was created. if containerID != "" { if err := d.docker.RemoveContainer(ctx, containerID, true); err != nil { log.Printf("rollback: remove container %s: %v", containerID, err) d.logDeploy(deployID, fmt.Sprintf("Rollback: failed to remove container: %v", err), "error") } else { d.logDeploy(deployID, "Rollback: container removed", "info") } } // Delete the NPM proxy host if it was created. if npmProxyID > 0 { settings, err := d.store.GetSettings() if err != nil { log.Printf("rollback: get settings for npm auth: %v", err) d.logDeploy(deployID, fmt.Sprintf("Rollback: failed to get settings for proxy cleanup: %v", err), "error") } else if npmPassword, err := d.decryptNpmPassword(settings.NpmPassword); err != nil { log.Printf("rollback: decrypt npm password: %v", err) d.logDeploy(deployID, "Rollback: failed to decrypt NPM password for proxy cleanup", "error") } else if err := d.npm.Authenticate(ctx, settings.NpmEmail, npmPassword); err != nil { log.Printf("rollback: authenticate npm: %v", err) d.logDeploy(deployID, "Rollback: failed to authenticate NPM for proxy cleanup", "error") } else if err := d.npm.DeleteProxyHost(ctx, npmProxyID); err != nil { log.Printf("rollback: delete proxy host %d: %v", npmProxyID, err) d.logDeploy(deployID, fmt.Sprintf("Rollback: failed to delete proxy host: %v", err), "error") } else { d.logDeploy(deployID, "Rollback: proxy host deleted", "info") } } // Update instance status to failed if it was created. if instanceID != "" { if err := d.store.UpdateInstanceStatus(instanceID, "failed"); err != nil { log.Printf("rollback: update instance %s status: %v", instanceID, err) } } // Mark deploy as rolled back. if err := d.store.UpdateDeployStatus(deployID, "rolled_back", "deployment failed, rolled back"); err != nil { log.Printf("rollback: update deploy %s status: %v", deployID, err) } d.logDeploy(deployID, "Rollback complete", "info") }