]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: RGW - Reatin Head Object Fix 62761/head
authorDnyaneshwari <dnyaneshwari@li-9c9fbecc-2d5c-11b2-a85c-e2a7cc8a424f.ibm.com>
Thu, 10 Apr 2025 08:22:47 +0000 (13:52 +0530)
committerDnyaneshwari <dnyaneshwari@li-9c9fbecc-2d5c-11b2-a85c-e2a7cc8a424f.ibm.com>
Fri, 11 Apr 2025 09:20:40 +0000 (14:50 +0530)
Fixes: https://tracker.ceph.com/issues/70871
Signed-off-by: Dnyaneshwari Talwekar <dtalwekar@redhat.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-storage-class.model.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-details/rgw-storage-class-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-details/rgw-storage-class-details.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-details/rgw-storage-class-details.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-form/rgw-storage-class-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/utils/rgw-bucket-tiering.ts
src/pybind/mgr/dashboard/services/rgw_client.py

index 85b0bf75d0afa5edd126e26aa075357b96e6cce3..6e7b1d745d119fbafeb88994811d0758645c3cce 100644 (file)
@@ -19,6 +19,7 @@ export interface StorageClassDetails {
   multipart_min_part_size: number;
   multipart_sync_threshold: number;
   host_style: string;
+  retain_head_object: boolean;
 }
 
 export interface S3Details {
@@ -38,6 +39,7 @@ export interface TierTarget {
   val: {
     storage_class: string;
     tier_type: string;
+    retain_head_object: boolean;
     s3: S3Details;
   };
 }
@@ -55,6 +57,7 @@ export interface StorageClassDetails {
   multipart_sync_threshold: number;
   host_style: string;
 }
+
 export interface ZoneGroup {
   name: string;
   id: string;
@@ -74,7 +77,6 @@ export interface S3Details {
   host_style: boolean;
   retain_head_object?: boolean;
 }
-
 export interface RequestModel {
   zone_group: string;
   placement_targets: PlacementTarget[];
index 1f724fc7a2d1bf112a00fae9269140bfd11f368d..378c0b6372a8b93de524ce5bdbd2764015c0453c 100644 (file)
             </td>
             <td>{{ selection?.multipart_sync_threshold }}</td>
           </tr>
+          <tr>
+            <td
+                class="bold">
+              Retain Head Object
+              <cd-helper class="text-pre-wrap">
+                <span i18n>
+                  Retain object metadata after transition to the cloud (default: false).
+                </span>
+              </cd-helper>
+            </td>
+            <td>{{ selection?.retain_head_object }}</td>
+          </tr>
         </tbody>
       </table>
     </cds-tab>
index 90541d45855c9194e64f846cc8466f8f313d5ae5..ca7e9fcaac79636bbce2eea2fe3774d5e9bed8a5 100644 (file)
@@ -38,7 +38,8 @@ describe('RgwStorageClassDetailsComponent', () => {
       target_path: '/test/path',
       multipart_min_part_size: 100,
       multipart_sync_threshold: 200,
-      host_style: 'path'
+      host_style: 'path',
+      retain_head_object: true
     };
     component.selection = mockSelection;
     component.ngOnChanges();
index 7494e6deac2c83361ad0d56498d6a4a058b87924..aeb72b0bdc213ea5848073f3d02c546f291709d0 100644 (file)
@@ -21,7 +21,8 @@ export class RgwStorageClassDetailsComponent implements OnChanges {
         target_path: this.selection.target_path,
         multipart_min_part_size: this.selection.multipart_min_part_size,
         multipart_sync_threshold: this.selection.multipart_sync_threshold,
-        host_style: this.selection.host_style
+        host_style: this.selection.host_style,
+        retain_head_object: this.selection.retain_head_object
       };
     }
   }
index c6582e46af2c867f11b8448a3ed1e96ea2ae1d8d..80f5fcf7a108d7ba2d86f5f35cefb5e328b4e50b 100644 (file)
@@ -71,6 +71,7 @@ describe('RgwStorageClassFormComponent', () => {
                   val: {
                     storage_class: 'CLOUDIBM',
                     tier_type: 'cloud-s3',
+                    retain_head_object: true,
                     s3: {
                       endpoint: 'https://s3.amazonaws.com',
                       access_key: 'ACCESSKEY',
@@ -94,6 +95,7 @@ describe('RgwStorageClassFormComponent', () => {
                   val: {
                     storage_class: 'CloudIBM',
                     tier_type: 'cloud-s3',
+                    retain_head_object: true,
                     s3: {
                       endpoint: 'https://s3.amazonaws.com',
                       access_key: 'ACCESSKEY',
index d380f08bcc0f65191c6681fba1604d28546acb0b..47669107d2174619fb4c13f2ff51f1e96ab096e9 100644 (file)
@@ -80,7 +80,7 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
     this.targetSecretKeyText =
       "To view or copy your secret key, go to your cloud service's user management or credentials section, find your user profile, and locate the access key. You can view and copy the key by following the instructions provided.";
     this.retainHeadObjectText =
-      'Retain object metadata after transition to the cloud (default: deleted).';
+      'Retain object metadata after transition to the cloud (default: false).';
     this.createForm();
     this.loadingReady();
     this.loadZoneGroup();
@@ -111,7 +111,7 @@ export class RgwStorageClassFormComponent extends CdForm implements OnInit {
           this.storageClassForm.get('target_path').setValue(response.target_path);
           this.storageClassForm
             .get('retain_head_object')
-            .setValue(response.retain_head_object || false);
+            .setValue(this.tierTargetInfo?.val?.retain_head_object || false);
           this.storageClassForm
             .get('multipart_sync_threshold')
             .setValue(response.multipart_sync_threshold || '');
index 7c33d89f236da2e16c6e7b5de5cdfc5ba766e3e0..33cd412c3666cd6f6c47d5a4038cd36a20cc7e12 100644 (file)
@@ -27,6 +27,7 @@ export class BucketTieringUtils {
       zonegroup_name: zoneGroup,
       placement_target: targetName,
       storage_class: tierTarget.val.storage_class,
+      retain_head_object: tierTarget.val.retain_head_object,
       ...tierTarget.val.s3
     };
   }
index fb633726805f7ea3d413b36ee9cd82c7cccc1a29..13c03ec9c95a21ab4eba242b48d6670ba9d7c102 100755 (executable)
@@ -1864,6 +1864,14 @@ class RgwMultisite:
         else:
             self.update_period()
 
+    def modify_retain_head(self, tier_config: dict) -> List[str]:
+        tier_config_items = []
+        for key, value in tier_config.items():
+            if isinstance(value, bool):
+                value = str(value).lower()
+            tier_config_items.append(f'{key}={value}')
+        return tier_config_items
+
     def add_placement_targets(self, zonegroup_name: str, placement_targets: List[Dict]):
         rgw_add_placement_cmd = ['zonegroup', 'placement', 'add']
         STANDARD_STORAGE_CLASS = "STANDARD"
@@ -1882,9 +1890,7 @@ class RgwMultisite:
             ):
                 tier_config = placement_target.get('tier_config', {})
                 if tier_config:
-                    tier_config_items = (
-                        f'{key}={value}' for key, value in tier_config.items()
-                    )
+                    tier_config_items = self.modify_retain_head(tier_config)
                     tier_config_str = ','.join(tier_config_items)
                     cmd_add_placement_options += [
                         '--tier-type', 'cloud-s3', '--tier-config', tier_config_str
@@ -1957,9 +1963,7 @@ class RgwMultisite:
             ):
                 tier_config = placement_target.get('tier_config', {})
                 if tier_config:
-                    tier_config_items = (
-                        f'{key}={value}' for key, value in tier_config.items()
-                    )
+                    tier_config_items = self.modify_retain_head(tier_config)
                     tier_config_str = ','.join(tier_config_items)
                     cmd_add_placement_options += [
                         '--tier-type', 'cloud-s3', '--tier-config', tier_config_str