diff --git a/CHANGELOG.md b/CHANGELOG.md index bf11d2f3..ce5c6b7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Restore default idempotency of `PUT /api/nodes/{id}` +- `DELETE /api/overlays/{name}?force=true` can delete overlays that are in use ### Changed diff --git a/internal/pkg/warewulfd/api/overlay.go b/internal/pkg/warewulfd/api/overlay.go index a6152df6..d3c0b1d0 100644 --- a/internal/pkg/warewulfd/api/overlay.go +++ b/internal/pkg/warewulfd/api/overlay.go @@ -223,28 +223,32 @@ func deleteOverlay() usecase.Interactor { u := usecase.NewInteractor(func(ctx context.Context, input deleteOverlayInput, output *OverlayResponse) error { wwlog.Debug("api.deleteOverlay(Name:%v, Force:%v)", input.Name, input.Force) - if registry, err := node.New(); err != nil { - return err - } else { - nodesCount := len(registry.ListNodesUsingOverlay(input.Name)) - profilesCount := len(registry.ListProfilesUsingOverlay(input.Name)) - if nodesCount > 0 || profilesCount > 0 { - return status.Wrap(fmt.Errorf( - "overlay '%s' is in use by %v nodes and %v profiles", input.Name, nodesCount, profilesCount), - status.InvalidArgument) - } - } - *output = *NewOverlayResponse(input.Name) overlay_ := overlay.GetSiteOverlay(input.Name) if input.Force { if err := os.RemoveAll(overlay_.Path()); err != nil { return err } } else { - if err := os.Remove(overlay_.Path()); err != nil { + if registry, err := node.New(); err != nil { return err + } else { + nodesCount := len(registry.ListNodesUsingOverlay(input.Name)) + profilesCount := len(registry.ListProfilesUsingOverlay(input.Name)) + if nodesCount > 0 || profilesCount > 0 { + return status.Wrap(fmt.Errorf( + "overlay '%s' is in use by %v nodes and %v profiles", input.Name, nodesCount, profilesCount), + status.InvalidArgument) + } + } + if err := os.Remove(overlay_.Rootfs()); err != nil { + return status.Wrap(fmt.Errorf("failed to remove overlay rootfs: %v", err), status.Code(409)) + } else { + if err := os.Remove(overlay_.Path()); err != nil { + return status.Wrap(fmt.Errorf("failed to remove overlay: %v", err), status.Code(409)) + } } } + *output = *NewOverlayResponse(input.Name) return nil }) u.SetTitle("Delete an overlay") diff --git a/internal/pkg/warewulfd/api/overlay_test.go b/internal/pkg/warewulfd/api/overlay_test.go index d2e981f8..c9ab26ee 100644 --- a/internal/pkg/warewulfd/api/overlay_test.go +++ b/internal/pkg/warewulfd/api/overlay_test.go @@ -128,6 +128,6 @@ func TestOverlayAPI(t *testing.T) { assert.NoError(t, err) assert.NoError(t, resp.Body.Close()) - assert.JSONEq(t, `{"files":null, "site":true}`, string(body)) + assert.JSONEq(t, `{"files":[], "site":true}`, string(body)) }) }