]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Allow renaming an existing Pool 25107/head
authorguodan1 <guodan1@lenovo.com>
Wed, 14 Nov 2018 12:34:03 +0000 (20:34 +0800)
committerguodan1 <guodan1@lenovo.com>
Tue, 27 Nov 2018 08:19:19 +0000 (16:19 +0800)
fixes: http://tracker.ceph.com/issues/36560
Signed-off-by: guodan1 <guodan1@lenovo.com>
src/pybind/mgr/dashboard/controllers/pool.py
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.ts

index 1964204d88ef96c34779a9b4ef7b4a602695929e..cdd9a7110d45d1684feb76d544fa4f35c032caf4 100644 (file)
@@ -91,6 +91,7 @@ class Pool(RESTController):
         self._set_pool_values(pool, application_metadata, flags, False, kwargs)
 
     def _set_pool_values(self, pool, application_metadata, flags, update_existing, kwargs):
+        update_name = False
         if update_existing:
             current_pool = self._get(pool)
             self._handle_update_compression_args(current_pool.get('options'), kwargs)
@@ -116,9 +117,15 @@ class Pool(RESTController):
             CephService.send_command('mon', 'osd pool set', pool=pool, var=key, val=str(value))
 
         for key, value in kwargs.items():
-            set_key(key, value)
-            if key == 'pg_num':
-                set_key('pgp_num', value)
+            if key == 'pool':
+                update_name = True
+                destpool = value
+            else:
+                set_key(key, value)
+                if key == 'pg_num':
+                    set_key('pgp_num', value)
+        if update_name:
+            CephService.send_command('mon', 'osd pool rename', srcpool=pool, destpool=destpool)
 
     def _handle_update_compression_args(self, options, kwargs):
         if kwargs.get('compression_mode') == 'unset' and options is not None:
index 133578afec4e4e3996c55dadc0d354cdd72eb867..9507b5fb84ad0cf0897b9197a9bd177b0cd099a7 100644 (file)
@@ -221,6 +221,7 @@ describe('PoolFormComponent', () => {
     });
 
     it('validates name', () => {
+      expect(component.editing).toBeFalsy();
       formHelper.expectError('name', 'required');
       formHelper.expectValidChange('name', 'some-name');
       component.info.pool_names.push('someExistingPoolName');
@@ -990,18 +991,19 @@ describe('PoolFormComponent', () => {
       });
 
       it('disabled inputs', () => {
-        const disabled = [
-          'name',
-          'poolType',
-          'crushRule',
-          'size',
-          'erasureProfile',
-          'ecOverwrites'
-        ];
+        const disabled = ['poolType', 'crushRule', 'size', 'erasureProfile', 'ecOverwrites'];
         disabled.forEach((controlName) => {
           return expect(form.get(controlName).disabled).toBeTruthy();
         });
-        const enabled = ['pgNum', 'mode', 'algorithm', 'minBlobSize', 'maxBlobSize', 'ratio'];
+        const enabled = [
+          'name',
+          'pgNum',
+          'mode',
+          'algorithm',
+          'minBlobSize',
+          'maxBlobSize',
+          'ratio'
+        ];
         enabled.forEach((controlName) => {
           return expect(form.get(controlName).enabled).toBeTruthy();
         });
index 7931368babd2a86e122ee40834bfa08a95224287..a17802a574cae42174fcc8de5e779b1105ef6135 100644 (file)
@@ -100,14 +100,7 @@ export class PoolFormComponent implements OnInit {
     this.form = new CdFormGroup(
       {
         name: new FormControl('', {
-          validators: [
-            Validators.pattern('[A-Za-z0-9_-]+'),
-            Validators.required,
-            CdValidators.custom(
-              'uniqueName',
-              (value) => this.info && this.info.pool_names.indexOf(value) !== -1
-            )
-          ]
+          validators: [Validators.pattern('[A-Za-z0-9_-]+'), Validators.required]
         }),
         poolType: new FormControl('', {
           validators: [Validators.required]
@@ -178,8 +171,8 @@ export class PoolFormComponent implements OnInit {
   }
 
   private disableForEdit() {
-    ['name', 'poolType', 'crushRule', 'size', 'erasureProfile', 'ecOverwrites'].forEach(
-      (controlName) => this.form.get(controlName).disable()
+    ['poolType', 'crushRule', 'size', 'erasureProfile', 'ecOverwrites'].forEach((controlName) =>
+      this.form.get(controlName).disable()
     );
   }
 
@@ -380,6 +373,20 @@ export class PoolFormComponent implements OnInit {
         .setValidators(
           CdValidators.custom('noDecrease', (pgs) => this.data.pool && pgs < this.data.pool.pg_num)
         );
+      this.form
+        .get('name')
+        .setValidators([
+          this.form.get('name').validator,
+          CdValidators.custom(
+            'uniqueName',
+            (name) =>
+              this.data.pool &&
+              this.info &&
+              this.info.pool_names.indexOf(name) !== -1 &&
+              this.info.pool_names.indexOf(name) !==
+                this.info.pool_names.indexOf(this.data.pool.pool_name)
+          )
+        ]);
     } else {
       CdValidators.validateIf(
         this.form.get('size'),
@@ -395,6 +402,15 @@ export class PoolFormComponent implements OnInit {
           )
         ]
       );
+      this.form
+        .get('name')
+        .setValidators([
+          this.form.get('name').validator,
+          CdValidators.custom(
+            'uniqueName',
+            (name) => this.info && this.info.pool_names.indexOf(name) !== -1
+          )
+        ]);
     }
     this.setCompressionValidators();
   }
@@ -543,6 +559,12 @@ export class PoolFormComponent implements OnInit {
             formControlName: 'mode',
             editable: true,
             replaceFn: () => 'unset'
+          },
+          {
+            externalFieldName: 'srcpool',
+            formControlName: 'name',
+            editable: true,
+            replaceFn: () => this.data.pool.pool_name
           }
         ]);
       }
@@ -598,7 +620,7 @@ export class PoolFormComponent implements OnInit {
     this.taskWrapper
       .wrapTaskAroundCall({
         task: new FinishedTask('pool/' + (this.editing ? 'edit' : 'create'), {
-          pool_name: pool.pool
+          pool_name: pool.hasOwnProperty('srcpool') ? pool.srcpool : pool.pool
         }),
         call: this.poolService[this.editing ? 'update' : 'create'](pool)
       })
index 59f4eec686769f14dc61a4d8b2f660881bce3561..30a5c6ecaaadf62041e6f690a6d8774978ff23af 100644 (file)
@@ -21,8 +21,14 @@ export class PoolService {
   }
 
   update(pool) {
-    const name = pool.pool;
-    delete pool.pool;
+    let name: string;
+    if (pool.hasOwnProperty('srcpool')) {
+      name = pool.srcpool;
+      delete pool.srcpool;
+    } else {
+      name = pool.pool;
+      delete pool.pool;
+    }
     return this.http.put(`${this.apiPath}/${name}`, pool, { observe: 'response' });
   }