]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: delete cephfs snapshot 55186/head
authorNizamudeen A <nia@redhat.com>
Wed, 10 Jan 2024 06:42:23 +0000 (12:12 +0530)
committerNizamudeen A <nia@redhat.com>
Tue, 16 Jan 2024 06:46:47 +0000 (12:16 +0530)
Fixes: https://tracker.ceph.com/issues/63990
Signed-off-by: Nizamudeen A <nia@redhat.com>
(cherry picked from commit c3d7f70b7a7d594050e3e231cd7d6544179fdfeb)

src/pybind/mgr/dashboard/controllers/cephfs.py
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-subvolume-snapshots-list/cephfs-subvolume-snapshots-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-subvolume-snapshots-list/cephfs-subvolume-snapshots-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs-subvolume.service.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts
src/pybind/mgr/dashboard/openapi.yaml

index 389d30ccbfe9a8c4b7df5b9f4b07d47189261060..cfa40b2dd7c0be3f2e0ac92119e51b17591e74e3 100644 (file)
@@ -837,3 +837,16 @@ class CephFSSubvolumeSnapshots(RESTController):
                 f'Failed to create subvolume snapshot {snap_name}: {err}'
             )
         return f'Subvolume snapshot {snap_name} created successfully'
+
+    def delete(self, vol_name: str, subvol_name: str, snap_name: str, group_name='', force=True):
+        params = {'vol_name': vol_name, 'sub_name': subvol_name, 'snap_name': snap_name}
+        if group_name:
+            params['group_name'] = group_name
+        params['force'] = str_to_bool(force)
+        error_code, _, err = mgr.remote('volumes', '_cmd_fs_subvolume_snapshot_rm', None,
+                                        params)
+        if error_code != 0:
+            raise DashboardException(
+                f'Failed to delete subvolume snapshot {snap_name}: {err}'
+            )
+        return f'Subvolume snapshot {snap_name} removed successfully'
index 1d03cf2a8bcaafd27e4fe0db2396343301dd1b08..c69f916c2c16aab10f0909b036b18080914cfbc8 100644 (file)
@@ -3,6 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { CephfsSubvolumeSnapshotsListComponent } from './cephfs-subvolume-snapshots-list.component';
 import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { SharedModule } from '~/app/shared/shared.module';
+import { ToastrModule } from 'ngx-toastr';
 
 describe('CephfsSubvolumeSnapshotsListComponent', () => {
   let component: CephfsSubvolumeSnapshotsListComponent;
@@ -11,7 +12,7 @@ describe('CephfsSubvolumeSnapshotsListComponent', () => {
   beforeEach(async () => {
     await TestBed.configureTestingModule({
       declarations: [CephfsSubvolumeSnapshotsListComponent],
-      imports: [HttpClientTestingModule, SharedModule]
+      imports: [HttpClientTestingModule, SharedModule, ToastrModule.forRoot()]
     }).compileComponents();
 
     fixture = TestBed.createComponent(CephfsSubvolumeSnapshotsListComponent);
index 9970d598887986bd89a65d6463e8d988f2ee02d7..798307a0cf9f44502b142323e4fd48d3fa191b14 100644 (file)
@@ -16,6 +16,10 @@ import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
 import { Permissions } from '~/app/shared/models/permissions';
 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
 import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
 
 @Component({
   selector: 'cd-cephfs-subvolume-snapshots-list',
@@ -30,6 +34,7 @@ export class CephfsSubvolumeSnapshotsListComponent implements OnInit, OnChanges
   tableActions: CdTableAction[];
   selection = new CdTableSelection();
   permissions: Permissions;
+  modalRef: NgbModalRef;
 
   subVolumes$: Observable<CephfsSubvolume[]>;
   snapshots$: Observable<any[]>;
@@ -53,7 +58,8 @@ export class CephfsSubvolumeSnapshotsListComponent implements OnInit, OnChanges
     private actionLabels: ActionLabelsI18n,
     private modalService: ModalService,
     private authStorageService: AuthStorageService,
-    private cdDatePipe: CdDatePipe
+    private cdDatePipe: CdDatePipe,
+    private taskWrapper: TaskWrapperService
   ) {
     this.permissions = this.authStorageService.getPermissions();
   }
@@ -91,6 +97,12 @@ export class CephfsSubvolumeSnapshotsListComponent implements OnInit, OnChanges
         permission: 'create',
         icon: Icons.add,
         click: () => this.openModal()
+      },
+      {
+        name: this.actionLabels.REMOVE,
+        permission: 'delete',
+        icon: Icons.destroy,
+        click: () => this.deleteSnapshot()
       }
     ];
 
@@ -190,4 +202,36 @@ export class CephfsSubvolumeSnapshotsListComponent implements OnInit, OnChanges
   updateSelection(selection: CdTableSelection) {
     this.selection = selection;
   }
+
+  deleteSnapshot() {
+    const snapshotName = this.selection.first().name;
+    const subVolumeName = this.activeSubVolumeName;
+    const subVolumeGroupName = this.activeGroupName;
+    const fsName = this.fsName;
+    this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
+      actionDescription: 'Remove',
+      itemNames: [snapshotName],
+      itemDescription: 'Snapshot',
+      submitAction: () =>
+        this.taskWrapper
+          .wrapTaskAroundCall({
+            task: new FinishedTask('cephfs/subvolume/snapshot/delete', {
+              fsName: fsName,
+              subVolumeName: subVolumeName,
+              subVolumeGroupName: subVolumeGroupName,
+              snapshotName: snapshotName
+            }),
+            call: this.cephfsSubvolumeService.deleteSnapshot(
+              fsName,
+              subVolumeName,
+              snapshotName,
+              subVolumeGroupName
+            )
+          })
+          .subscribe({
+            complete: () => this.modalRef.close(),
+            error: () => this.modalRef.componentInstance.stopLoadingSpinner()
+          })
+    });
+  }
 }
index 1995fd293bae0c0341f3e29a55a40c5df31787e7..ad0ce248064db29faab549d3d29c1da3afd8115c 100644 (file)
@@ -161,4 +161,14 @@ export class CephfsSubvolumeService {
       { observe: 'response' }
     );
   }
+
+  deleteSnapshot(fsName: string, subVolumeName: string, snapshotName: string, groupName = '') {
+    return this.http.delete(`${this.baseURL}/snapshot/${fsName}/${subVolumeName}`, {
+      params: {
+        snap_name: snapshotName,
+        group_name: groupName
+      },
+      observe: 'response'
+    });
+  }
 }
index c1165d318a364312552448f7d835d8e0c87ddd98..dba742fbf7831be105feeb8eb5ead7729fd18304 100644 (file)
@@ -383,6 +383,10 @@ export class TaskMessageService {
     'cephfs/subvolume/snapshot/create': this.newTaskMessage(
       this.commonOperations.create,
       (metadata) => this.snapshot(metadata)
+    ),
+    'cephfs/subvolume/snapshot/delete': this.newTaskMessage(
+      this.commonOperations.delete,
+      (metadata) => this.snapshot(metadata)
     )
   };
 
index 2be67eb877c0eeb27664e68b334580e9d30d713c..45af71681ef46fc7256bb858062b1cf0ea783125 100644 (file)
@@ -2006,6 +2006,57 @@ paths:
       tags:
       - CephfsSubvolumeSnapshot
   /api/cephfs/subvolume/snapshot/{vol_name}/{subvol_name}:
+    delete:
+      parameters:
+      - in: path
+        name: vol_name
+        required: true
+        schema:
+          type: string
+      - in: path
+        name: subvol_name
+        required: true
+        schema:
+          type: string
+      - in: query
+        name: snap_name
+        required: true
+        schema:
+          type: string
+      - default: ''
+        in: query
+        name: group_name
+        schema:
+          type: string
+      - default: true
+        in: query
+        name: force
+        schema:
+          type: boolean
+      responses:
+        '202':
+          content:
+            application/vnd.ceph.api.v1.0+json:
+              type: object
+          description: Operation is still executing. Please check the task queue.
+        '204':
+          content:
+            application/vnd.ceph.api.v1.0+json:
+              type: object
+          description: Resource deleted.
+        '400':
+          description: Operation exception. Please check the response body for details.
+        '401':
+          description: Unauthenticated access. Please login first.
+        '403':
+          description: Unauthorized access. Please check your permissions.
+        '500':
+          description: Unexpected error. Please check the response body for the stack
+            trace.
+      security:
+      - jwt: []
+      tags:
+      - CephfsSubvolumeSnapshot
     get:
       parameters:
       - in: path