Skip to content

fix(rm): support documented destructive removal flags#289

Merged
overtrue merged 1 commit into
mainfrom
overtrue/rc-5104-removal-flags
Jul 22, 2026
Merged

fix(rm): support documented destructive removal flags#289
overtrue merged 1 commit into
mainfrom
overtrue/rc-5104-removal-flags

Conversation

@overtrue

Copy link
Copy Markdown
Contributor

Related Issues

Refs rustfs/rustfs#5104.

Background

rc rm --versions, rc rm --bypass, and rc rb --force were shown in help but failed during execution. Versioned buckets could be left with non-current versions or delete markers that rc could not purge.

Changes

  • Make rm --versions use the existing RustFS force-delete path and list object versions for recursive deletes, so delete-marker-only keys are included.
  • Add the standard governance bypass delete header for rm --bypass.
  • Make rb --force purge bucket contents before deleting the bucket.
  • Hide still-unsupported --incomplete / --dangerous from help while keeping explicit runtime rejection if passed.

Validation

  • make pre-commit

Copilot AI review requested due to automatic review settings July 22, 2026 02:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@overtrue
overtrue merged commit 9080844 into main Jul 22, 2026
16 checks passed
@overtrue
overtrue deleted the overtrue/rc-5104-removal-flags branch July 22, 2026 04:55

@overtrue overtrue left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review note (needs a fix before merge)

The bypass-governance plumbing and the version-listing for delete-marker-only keys are good, with solid unit/header-level tests. But the headline rm --versions path, used recursively without --purge, does not actually purge — I verified this against the server as well.

Findings

[MAJOR] crates/cli/src/commands/rm.rs:285 (+ :315, :389) — rm <prefix>/ --recursive --versions (without --purge) does not purge versions; it silently creates delete markers and reports success

  • Why: --versions lists versions (:257) but, because args.purge is false, execution falls through to the batch delete_objects_with_options path (:315). On the server, x-rustfs-force-delete is honored only on the single-object DELETE path (rustfs/src/app/object_usecase.rs:6639 reads opts.delete_prefix); the multi-object handler builds ObjectOptions { versioned, version_suspended, object_lock_delete: Some(bypass_governance), ..Default::default() } at object_usecase.rs:6432 — it never sets delete_prefix and never reads the force-delete header — so the header is a no-op on the batch path. Version IDs are also dropped client-side (list_version_keys inserts only item.key; the batch call sends no VersionId). On a versioned bucket each key therefore just gets a new delete marker while all prior versions remain. Only --purge (per-key single DELETE, :285) actually purges; rb --force is safe because it sets purge: true. (Bypass-governance itself is plumbed correctly on both paths — that part works.)
  • Fix: Route force-delete through the per-key single-DELETE path, e.g. if args.purge || args.versions at rm.rs:285 (delete_request_options already sets force_delete for versions), and add an integration test for the recursive --versions path.

[MINOR] docs/reference/rc/rb.md — the documented --dangerous flag is now hidden and non-functional

  • Why: rb.md still lists --dangerous ("Remove the bucket even when incomplete multipart uploads exist"), but this PR hides it from help (rb.rs:25) and keeps rejecting it as unimplemented — a user following the docs hits UnsupportedFeature.
  • Fix: Update rb.md to drop/mark --dangerous as unsupported so the documented contract matches the CLI.

[MINOR] crates/cli/src/commands/rm.rs:389 — wiring --versions to force_delete extends prefix-delete over-reach to single objects

  • Why: rm bucket/key --versions (non-recursive) now sends force-delete, which the server treats as a recursive prefix delete of key/; a sibling object like key/child would also be destroyed. Previously this footgun existed only for --purge.
  • Fix: Document that --versions/--purge remove everything under the key path, or scope single-object force-delete to the exact object.

Test coverage

The --purge per-key path is well covered (rm_purge.rs), including an assertion that it avoids the batch path. Gaps: no integration test for the recursive --versions (non-purge) path (would have caught the MAJOR); --bypass and rb --force are only exercised at unit/header level, not end-to-end with exit codes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants