]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
improve error handling and add --resume flag to 'ceph rgw realm bootstrap' for partia... 63391/head
authorKushal Deb <Kushal.Deb@ibm.com>
Wed, 21 May 2025 10:01:06 +0000 (15:31 +0530)
committerKushal Deb <Kushal.Deb@ibm.com>
Thu, 17 Jul 2025 12:18:12 +0000 (17:48 +0530)
This patch enhances the `ceph rgw realm bootstrap` command by improving error
messaging and introducing a `--resume` flag to support recovery from partial
bootstrap failures.

Signed-off-by: Kushal Deb <Kushal.Deb@ibm.com>
src/pybind/mgr/rgw/module.py
src/python-common/ceph/rgw/rgwam_core.py

index 82560a567a8264b34d1d5f45dab72df864000282..284d88ef175194ceb536b85312bb970d98f5b25e 100644 (file)
@@ -184,6 +184,7 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
                                  placement: Optional[str] = None,
                                  zone_endpoints: Optional[str] = None,
                                  start_radosgw: Optional[bool] = True,
+                                 skip_realm_components: Optional[bool] = False,
                                  inbuf: Optional[str] = None) -> HandleCommandResult:
         """Bootstrap new rgw realm, zonegroup, and zone"""
 
@@ -207,7 +208,8 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
         try:
             for spec in rgw_specs:
                 self.create_pools(spec)
-                RGWAM(self.env).realm_bootstrap(spec, start_radosgw)
+                RGWAM(self.env).realm_bootstrap(spec, start_radosgw, skip_realm_components)
+
         except RGWAMException as e:
             self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message))
             # The RGWAM code isn't always consistent about what goes into stdout
@@ -237,6 +239,11 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
             elif e.stdout:
                 msg = e.stdout
             return HandleCommandResult(retval=e.retcode, stdout=msg, stderr=e.stderr)
+            e.stderr = (e.stderr or '') + (
+                "\nNote: Partial bootstrap detected - The following entries were already created during a previous bootstrap attempt. \n"
+                "To resume, run:\n ceph rgw realm bootstrap with --skip-realm-components\n"
+            )
+            return HandleCommandResult(retval=e.retcode, stdout=e.stdout, stderr=e.stderr)
         except PoolCreationError as e:
             self.log.error(f'Pool creation failure: {str(e)}')
             return HandleCommandResult(retval=-errno.EINVAL, stderr=str(e))
index bbfb85af27a70c929fb7b643c1e25f1266b9a265..9b19865bfc5012aff74b59605be5641df1bc9373 100644 (file)
@@ -555,19 +555,28 @@ class RGWAM:
         except RGWAMCmdRunException as e:
             raise RGWAMException('failed to update period', e)
 
-    def realm_bootstrap(self, rgw_spec, start_radosgw=True):
+    def realm_bootstrap(self, rgw_spec, start_radosgw=True, skip_realm_components=False):
 
         realm_name = rgw_spec.rgw_realm
         zonegroup_name = rgw_spec.rgw_zonegroup
         zone_name = rgw_spec.rgw_zone
 
         # Some sanity checks
-        if realm_name in self.realm_op().list():
-            raise RGWAMException(f'Realm {realm_name} already exists')
-        if zonegroup_name in self.zonegroup_op().list():
-            raise RGWAMException(f'Zonegroup {zonegroup_name} already exists')
-        if zone_name in self.zone_op().list():
-            raise RGWAMException(f'Zone {zone_name} already exists')
+        if not skip_realm_components:
+            existing = []
+            if realm_name in self.realm_op().list():
+                existing.append(f"realm: {realm_name}")
+                # raise RGWAMException(f'Realm {realm_name} already exists')
+            if zonegroup_name in self.zonegroup_op().list():
+                existing.append(f"zonegroup: {zonegroup_name}")
+                # raise RGWAMException(f'Zonegroup {zonegroup_name} already exists')
+            if zone_name in self.zone_op().list():
+                existing.append(f"zone: {zone_name}")
+                # raise RGWAMException(f'Zone {zone_name} already exists')
+            if existing:
+                raise RGWAMException(
+                    f"The following components already exist: {', '.join(existing)}"
+                )
 
         # Create RGW entities and update the period
         realm = self.create_realm(realm_name)