From: Aashish Sharma Date: Mon, 5 Sep 2022 11:59:11 +0000 (+0530) Subject: mgr/dashboard: fix snapshot creation with duplicate name X-Git-Tag: v18.0.0~61^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=2ae1bca1d9c7a771be0fa9481bef2622ffd7cc45;p=ceph.git mgr/dashboard: fix snapshot creation with duplicate name Snapshot creation with same name on UI throwing 500 Internal Error, This PR intends to fix this issue. Fixes: https://tracker.ceph.com/issues/57456 Signed-off-by: Aashish Sharma --- diff --git a/src/pybind/mgr/dashboard/controllers/cephfs.py b/src/pybind/mgr/dashboard/controllers/cephfs.py index b6c8701320867..ed84c1b7d106e 100644 --- a/src/pybind/mgr/dashboard/controllers/cephfs.py +++ b/src/pybind/mgr/dashboard/controllers/cephfs.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import logging import os from collections import defaultdict @@ -19,6 +20,8 @@ GET_QUOTAS_SCHEMA = { 'max_files': (int, '') } +logger = logging.getLogger("controllers.rgw") + @APIRouter('/cephfs', Scope.CEPHFS) @APIDoc("Cephfs Management API", "Cephfs") @@ -470,6 +473,14 @@ class CephFS(RESTController): :rtype: str """ cfs = self._cephfs_instance(fs_id) + list_snaps = cfs.ls_snapshots(path) + for snap in list_snaps: + if name == snap['name']: + raise DashboardException(code='Snapshot name already in use', + msg='Snapshot name {} is already in use.' + 'Please use another name'.format(name), + component='cephfs') + return cfs.mk_snapshot(path, name) @RESTController.Resource('DELETE', path='/snapshot') diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts index c2528f7c4511e..4ae8a159a0559 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts @@ -1,5 +1,5 @@ import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { Validators } from '@angular/forms'; +import { AbstractControl, Validators } from '@angular/forms'; import { ITreeOptions, @@ -103,6 +103,7 @@ export class CephfsDirectoriesComponent implements OnInit, OnChanges { updateSelection: Function; }; nodes: any[]; + alreadyExists: boolean; constructor( private authStorageService: AuthStorageService, @@ -546,22 +547,34 @@ export class CephfsDirectoriesComponent implements OnInit, OnChanges { type: 'text', name: 'name', value: `${moment().toISOString(true)}`, - required: true + required: true, + validators: [this.validateValue.bind(this)] } ], submitButtonText: $localize`Create Snapshot`, onSubmit: (values: CephfsSnapshot) => { - this.cephfsService.mkSnapshot(this.id, path, values.name).subscribe((name) => { + if (!this.alreadyExists) { + this.cephfsService.mkSnapshot(this.id, path, values.name).subscribe((name) => { + this.notificationService.show( + NotificationType.success, + $localize`Created snapshot '${name}' for '${path}'` + ); + this.forceDirRefresh(); + }); + } else { this.notificationService.show( - NotificationType.success, - $localize`Created snapshot '${name}' for '${path}'` + NotificationType.error, + $localize`Snapshot name '${values.name}' is already in use. Please use another name.` ); - this.forceDirRefresh(); - }); + } } }); } + validateValue(control: AbstractControl) { + this.alreadyExists = this.selectedDir.snapshots.some((s) => s.name === control.value); + } + /** * Forces an update of the current selected directory *