Implement Ceph volume resize and rename in clients
[1/2] Implements #44
This commit is contained in:
		| @@ -803,6 +803,40 @@ def ceph_volume_add(pool, name, size): | ||||
|     } | ||||
|     return flask.jsonify(output), retcode | ||||
|  | ||||
| def ceph_volume_resize(pool, name, size): | ||||
|     """ | ||||
|     Resize an existing Ceph RBD volume in the PVC Ceph storage cluster. | ||||
|     """ | ||||
|     zk_conn = pvc_common.startZKConnection(config['coordinators']) | ||||
|     retflag, retdata = pvc_ceph.resize_volume(zk_conn, pool, name, size) | ||||
|     if retflag: | ||||
|         retcode = 200 | ||||
|     else: | ||||
|         retcode = 400 | ||||
|  | ||||
|     pvc_common.stopZKConnection(zk_conn) | ||||
|     output = { | ||||
|         'message': retdata.replace('\"', '\'') | ||||
|     } | ||||
|     return flask.jsonify(output), retcode | ||||
|  | ||||
| def ceph_volume_rename(pool, name, new_name): | ||||
|     """ | ||||
|     Rename a Ceph RBD volume in the PVC Ceph storage cluster. | ||||
|     """ | ||||
|     zk_conn = pvc_common.startZKConnection(config['coordinators']) | ||||
|     retflag, retdata = pvc_ceph.rename_volume(zk_conn, pool, name, new_name) | ||||
|     if retflag: | ||||
|         retcode = 200 | ||||
|     else: | ||||
|         retcode = 400 | ||||
|  | ||||
|     pvc_common.stopZKConnection(zk_conn) | ||||
|     output = { | ||||
|         'message': retdata.replace('\"', '\'') | ||||
|     } | ||||
|     return flask.jsonify(output), retcode | ||||
|  | ||||
| def ceph_volume_remove(pool, name): | ||||
|     """ | ||||
|     Remove a Ceph RBD volume to the PVC Ceph storage cluster. | ||||
|   | ||||
| @@ -799,8 +799,19 @@ def api_ceph_volume_element(pool, volume): | ||||
|         return pvcapi.ceph_volume_list(pool, volume) | ||||
|  | ||||
|     if flask.request.method == 'PUT': | ||||
|         # TODO: #44 | ||||
|         flask.abort(501) | ||||
|         if 'size' in flask.request.values: | ||||
|             size = flask.request.values['size'] | ||||
|  | ||||
|         if 'name' in flask.request.values: | ||||
|             name = flask.request.values['name'] | ||||
|  | ||||
|         if size and not name: | ||||
|             return pvcapi.ceph_volume_resize(pool, volume, size)  | ||||
|     | ||||
|         if name and not size: | ||||
|             return pvcapi.ceph_volume_rename(pool, volume, name) | ||||
|  | ||||
|         return flask.jsonify({"message":"ERROR: No name or size specified, or both specified; not changing anything."}), 400 | ||||
|  | ||||
|     if flask.request.method == 'DELETE': | ||||
|         return pvcapi.ceph_volume_remove(pool, volume) | ||||
|   | ||||
| @@ -1482,6 +1482,48 @@ def ceph_volume_remove(pool, name, yes): | ||||
|     retcode, retmsg = pvc_ceph.remove_volume(zk_conn, pool, name) | ||||
|     cleanup(retcode, retmsg, zk_conn) | ||||
|  | ||||
| ############################################################################### | ||||
| # pvc storage ceph volume resize | ||||
| ############################################################################### | ||||
| @click.command(name='resize', short_help='Resize RBD volume.') | ||||
| @click.argument( | ||||
|     'pool' | ||||
| ) | ||||
| @click.argument( | ||||
|     'name' | ||||
| ) | ||||
| @click.argument( | ||||
|     'size' | ||||
| ) | ||||
| def ceph_volume_resize(pool, name, size): | ||||
|     """ | ||||
|     Resize an existing Ceph RBD volume with name NAME in pool POOL to size SIZE [in human units, e.g. 1024M, 20G, etc.]. | ||||
|     """ | ||||
|     zk_conn = pvc_common.startZKConnection(zk_host) | ||||
|     retcode, retmsg = pvc_ceph.resize_volume(zk_conn, pool, name, size) | ||||
|     cleanup(retcode, retmsg, zk_conn) | ||||
|  | ||||
| ############################################################################### | ||||
| # pvc storage ceph volume rename | ||||
| ############################################################################### | ||||
| @click.command(name='rename', short_help'Rename RBD volume.') | ||||
| @click.argument( | ||||
|     'pool' | ||||
| ) | ||||
| @click.argument( | ||||
|     'name' | ||||
| ) | ||||
| @click.argument( | ||||
|     'new_name' | ||||
| ) | ||||
| def ceph_volume_rename(pool, name, new_name): | ||||
|     """ | ||||
|     Rename an existing Ceph RBD volume with name NAME in pool POOL to name NEW_NAME. | ||||
|     """ | ||||
|     zk_conn = pvc_common.startZKConnection(zk_host) | ||||
|     retcode, retmsg = pvc_ceph.rename_volume(zk_conn, pool, name, new_name) | ||||
|     cleanup(retcode, retmsg, zk_conn) | ||||
|  | ||||
| ############################################################################### | ||||
| # pvc storage ceph volume list | ||||
| ############################################################################### | ||||
| @@ -1753,6 +1795,8 @@ ceph_pool.add_command(ceph_pool_remove) | ||||
| ceph_pool.add_command(ceph_pool_list) | ||||
|  | ||||
| ceph_volume.add_command(ceph_volume_add) | ||||
| ceph_volume.add_command(ceph_volume_resize) | ||||
| ceph_volume.add_command(ceph_volume_rename) | ||||
| ceph_volume.add_command(ceph_volume_remove) | ||||
| ceph_volume.add_command(ceph_volume_list) | ||||
| ceph_volume.add_command(ceph_volume_snapshot) | ||||
|   | ||||
| @@ -966,6 +966,65 @@ def add_volume(zk_conn, pool, name, size): | ||||
|  | ||||
|     return success, message | ||||
|  | ||||
| def resize_volume(zk_conn, pool, name, size): | ||||
|     # Tell the cluster to resize the volume | ||||
|     databytes = format_bytes_fromhuman(size) | ||||
|     resize_volume_string = 'volume_resize {},{},{}'.format(pool, name, databytes) | ||||
|     zkhandler.writedata(zk_conn, {'/ceph/cmd': resize_volume_string}) | ||||
|     # Wait 1/2 second for the cluster to get the message and start working | ||||
|     time.sleep(0.5) | ||||
|     # Acquire a read lock, so we get the return exclusively | ||||
|     lock = zkhandler.readlock(zk_conn, '/ceph/cmd') | ||||
|     with lock: | ||||
|         try: | ||||
|             result = zkhandler.readdata(zk_conn, '/ceph/cmd').split()[0] | ||||
|             if result == 'success-volume_resize': | ||||
|                 message = 'Resized RBD volume "{}" to size "{}" on pool "{}".'.format(name, size, pool) | ||||
|                 success = True | ||||
|             else: | ||||
|                 message = 'ERROR: Failed to resize volume; check node logs for details.' | ||||
|                 success = False | ||||
|         except: | ||||
|             message = 'ERROR: Command ignored by node.' | ||||
|             success = False | ||||
|  | ||||
|     # Acquire a write lock to ensure things go smoothly | ||||
|     lock = zkhandler.writelock(zk_conn, '/ceph/cmd') | ||||
|     with lock: | ||||
|         time.sleep(1) | ||||
|         zkhandler.writedata(zk_conn, {'/ceph/cmd': ''}) | ||||
|  | ||||
|     return success, message | ||||
|  | ||||
| def rename_volume(zk_conn, pool, name, new_name): | ||||
|     # Tell the cluster to rename | ||||
|     rename_volume_string = 'volume_rename {},{},{}'.format(pool, name, new_name) | ||||
|     zkhandler.writedata(zk_conn, {'/ceph/cmd': rename_volume_string}) | ||||
|     # Wait 1/2 second for the cluster to get the message and start working | ||||
|     time.sleep(0.5) | ||||
|     # Acquire a read lock, so we get the return exclusively | ||||
|     lock = zkhandler.readlock(zk_conn, '/ceph/cmd') | ||||
|     with lock: | ||||
|         try: | ||||
|             result = zkhandler.readdata(zk_conn, '/ceph/cmd').split()[0] | ||||
|             if result == 'success-volume_add': | ||||
|                 message = 'Created new RBD volume "{}" of size "{}" on pool "{}".'.format(name, size, pool) | ||||
|                 success = True | ||||
|             else: | ||||
|                 message = 'ERROR: Failed to create new volume; check node logs for details.' | ||||
|                 success = False | ||||
|         except: | ||||
|             message = 'ERROR: Command ignored by node.' | ||||
|             success = False | ||||
|  | ||||
|     # Acquire a write lock to ensure things go smoothly | ||||
|     lock = zkhandler.writelock(zk_conn, '/ceph/cmd') | ||||
|     with lock: | ||||
|         time.sleep(1) | ||||
|         zkhandler.writedata(zk_conn, {'/ceph/cmd': ''}) | ||||
|  | ||||
|     return success, message | ||||
|  | ||||
| def remove_volume(zk_conn, pool, name): | ||||
|     if not verifyVolume(zk_conn, pool, name): | ||||
|         return False, 'ERROR: No volume with name "{}" is present in pool {}.'.format(name, pool) | ||||
|   | ||||
| @@ -524,6 +524,8 @@ Return a JSON document containing information about Ceph RBD volume `<volume>` i | ||||
|  | ||||
| Change the configuration of the volume `<volume>`. If `name` is specified, rename the volume to the specified name. If `size` is specified, resize the volume to the specified size (see `POST /api/v1/storage/ceph/volume` for restrictions). | ||||
|  | ||||
| **NOTE:** Only one change operation (either `name` or `size`) may be completed in one operation. | ||||
|  | ||||
| ###### `DELETE` | ||||
|  * Mandatory values: N/A | ||||
|  * Optional values: N/A | ||||
|   | ||||
		Reference in New Issue
	
	Block a user