]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
radosgw-admin: support 'account rm --purge-data'
authorCasey Bodley <cbodley@redhat.com>
Tue, 4 Feb 2025 16:09:12 +0000 (11:09 -0500)
committerCasey Bodley <cbodley@redhat.com>
Tue, 18 Mar 2025 17:57:47 +0000 (13:57 -0400)
analogous to 'user rm --purge-data'. instead of failing if the account
still owns buckets, remove the remaining buckets/objects

Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit 83bacbb47457dea380ac1958f73c82132a8f7fd4)

src/rgw/rgw_account.cc
src/rgw/rgw_account.h
src/rgw/rgw_admin.cc

index af61be8b500e09b24120fd535da06e18c86f4f39..fd9c479337ce0f5724ed7ff7e9f3fde8147f8375 100644 (file)
@@ -312,15 +312,36 @@ int remove(const DoutPrefixProvider* dpp,
 
   constexpr bool need_stats = false;
   rgw::sal::BucketList buckets;
-  ret = driver->list_buckets(dpp, info.id, info.tenant, marker, marker,
-                             max_items, need_stats, buckets, y);
-  if (ret < 0) {
-    return ret;
-  }
-  if (!buckets.buckets.empty()) {
-    err_msg = "The account cannot be deleted until all buckets are removed.";
-    return -ENOTEMPTY;
-  }
+  do {
+    ret = driver->list_buckets(dpp, info.id, info.tenant,
+                               buckets.next_marker, "",
+                               max_items, need_stats, buckets, y);
+    if (ret < 0) {
+      err_msg = "Unable to list account buckets";
+      return ret;
+    }
+
+    if (!buckets.buckets.empty() && !op_state.purge_data) {
+      err_msg = "The account cannot be deleted until all buckets are removed.";
+      return -EEXIST; // change to code that maps to 409: conflict
+    }
+
+    for (const auto& ent : buckets.buckets) {
+      std::unique_ptr<rgw::sal::Bucket> bucket;
+      ret = driver->load_bucket(dpp, ent.bucket, &bucket, y);
+      if (ret < 0) {
+        err_msg = fmt::format("unable to load bucket {}", ent.bucket.name);
+        return ret;
+      }
+
+      constexpr bool delete_objects = true;
+      ret = bucket->remove(dpp, delete_objects, y);
+      if (ret < 0) {
+        err_msg = fmt::format("unable to delete bucket {}", ent.bucket.name);
+        return ret;
+      }
+    }
+  } while (!buckets.next_marker.empty());
 
   rgw::sal::RoleList roles;
   ret = driver->list_account_roles(dpp, y, info.id, path_prefix,
index 2a6f3e2379751a54ec39aeee9621b20f5c3b3d24..d3c9055f101436a548bd9dfe579dba7240bc4e31 100644 (file)
@@ -53,6 +53,7 @@ struct AdminOpState {
   std::optional<int64_t> quota_max_size;
   std::optional<int64_t> quota_max_objects;
   std::optional<bool> quota_enabled;
+  bool purge_data = false;
 };
 
 /// create an account
index 7bdd0544899ac3ea6a8fc03ebc10ab40e3933727..f86a7c33907428caa2036a9b2072833a15ebcc11 100644 (file)
@@ -11523,6 +11523,7 @@ next:
       .max_groups = max_groups,
       .max_access_keys = max_access_keys,
       .max_buckets = max_buckets,
+      .purge_data = static_cast<bool>(purge_data),
     };
 
     std::string err_msg;