Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(server): Optional graceful shutdown before deleting servers #755

Merged
merged 9 commits into from
Sep 20, 2023
48 changes: 47 additions & 1 deletion internal/server/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ func Resource() *schema.Resource {
Optional: true,
Default: false,
},
"shutdown_before_deletion": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
}
}
Expand Down Expand Up @@ -849,6 +854,47 @@ func resourceServerDelete(ctx context.Context, d *schema.ResourceData, m interfa
d.SetId("")
return nil
}

var warnings diag.Diagnostics

if d.Get("shutdown_before_deletion").(bool) {
// Try shutting down the server
shutdownResult, _, err := client.Server.Shutdown(ctx, &hcloud.Server{ID: serverID})
if err != nil {
return hcclient.ErrorToDiag(err)
}

if err = hcclient.WaitForAction(ctx, &client.Action, shutdownResult); err != nil {
return hcclient.ErrorToDiag(err)
}

// Give the server some time to shut down
err = control.Retry(control.DefaultRetries, func() error {
server, _, err := client.Server.GetByID(ctx, serverID)

// If it is not possible to get the server status, it is probably futile to retry
if err != nil {
return control.AbortRetry(err)
}

if server.Status != hcloud.ServerStatusOff {
return fmt.Errorf("Server has not shut down yet")
}

// Server has shut down successfully
return nil
})
if err != nil {
// If shutting down does not work, add a warning and move on with deletion
warnings = append(warnings, diag.Diagnostic{
Severity: diag.Warning,
Summary: fmt.Sprintf("Server id %d took longer than 30s to shut down gracefully, deleting it anyways.", serverID),
})
LionC marked this conversation as resolved.
Show resolved Hide resolved

err = nil
}
}

result, _, err := client.Server.DeleteWithResult(ctx, &hcloud.Server{ID: serverID})
if err != nil {
return hcclient.ErrorToDiag(err)
Expand All @@ -859,7 +905,7 @@ func resourceServerDelete(ctx context.Context, d *schema.ResourceData, m interfa
return hcclient.ErrorToDiag(err)
}

return nil
return warnings
}

func resourceServerIsNotFound(err error, d *schema.ResourceData) bool {
Expand Down
1 change: 1 addition & 0 deletions website/docs/d/server.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ data "hcloud_server" "s_3" {
- `placement_group_id` - (Optional, string) Placement Group ID the server is assigned to.
- `delete_protection` - (bool) Whether delete protection is enabled.
- `rebuild_protection` - (bool) Whether rebuild protection is enabled.
- `shutdown_before_deletion` - (bool) Whether to try shutting the server down gracefully before deleting it.
LionC marked this conversation as resolved.
Show resolved Hide resolved