Add dedicated volume scan endpoint
Allows an imported volume to be scanned for stats independently. Designed to be used as part of a snapshot import via API, to allow the "create" to happen before the real import (to check for available space, etc.) and then run this import after when the RBD volume actually exists.
This commit is contained in:
parent
8cb44c0c5d
commit
7543eb839d
|
@ -6461,6 +6461,41 @@ api.add_resource(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# /storage/ceph/volume/<pool>/<volume>/scan
|
||||||
|
class API_Storage_Ceph_Volume_Element_Scan(Resource):
|
||||||
|
@Authenticator
|
||||||
|
def post(self, pool, volume):
|
||||||
|
"""
|
||||||
|
Scan a Ceph volume {volume} in pool {pool} for stats (after import)
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- storage / ceph
|
||||||
|
parameters:
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
id: Message
|
||||||
|
404:
|
||||||
|
description: Not found
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
id: Message
|
||||||
|
400:
|
||||||
|
description: Bad request
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
id: Message
|
||||||
|
"""
|
||||||
|
return api_helper.ceph_volume_scan(pool, volume)
|
||||||
|
|
||||||
|
|
||||||
|
api.add_resource(
|
||||||
|
API_Storage_Ceph_Volume_Element_Scan, "/storage/ceph/volume/<pool>/<volume>/scan"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# /storage/ceph/volume/<pool>/<volume>/clone
|
# /storage/ceph/volume/<pool>/<volume>/clone
|
||||||
class API_Storage_Ceph_Volume_Element_Clone(Resource):
|
class API_Storage_Ceph_Volume_Element_Clone(Resource):
|
||||||
@RequestParser(
|
@RequestParser(
|
||||||
|
|
|
@ -1996,6 +1996,22 @@ def ceph_volume_list(zkhandler, pool=None, limit=None, is_fuzzy=True):
|
||||||
return retdata, retcode
|
return retdata, retcode
|
||||||
|
|
||||||
|
|
||||||
|
@ZKConnection(config)
|
||||||
|
def ceph_volume_scan(zkhandler, pool, name):
|
||||||
|
"""
|
||||||
|
(Re)scan a Ceph RBD volume for stats in the PVC Ceph storage cluster.
|
||||||
|
"""
|
||||||
|
retflag, retdata = pvc_ceph.scan_volume(zkhandler, pool, name)
|
||||||
|
|
||||||
|
if retflag:
|
||||||
|
retcode = 200
|
||||||
|
else:
|
||||||
|
retcode = 400
|
||||||
|
|
||||||
|
output = {"message": retdata.replace('"', "'")}
|
||||||
|
return output, retcode
|
||||||
|
|
||||||
|
|
||||||
@ZKConnection(config)
|
@ZKConnection(config)
|
||||||
def ceph_volume_add(zkhandler, pool, name, size, force_flag=False):
|
def ceph_volume_add(zkhandler, pool, name, size, force_flag=False):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -560,7 +560,21 @@ def getVolumeInformation(zkhandler, pool, volume):
|
||||||
return volume_information
|
return volume_information
|
||||||
|
|
||||||
|
|
||||||
def add_volume(zkhandler, pool, name, size, force_flag=False):
|
def scan_volume(zkhandler, pool, name):
|
||||||
|
retcode, stdout, stderr = common.run_os_command(
|
||||||
|
"rbd info --format json {}/{}".format(pool, name)
|
||||||
|
)
|
||||||
|
volstats = stdout
|
||||||
|
|
||||||
|
# 3. Add the new volume to Zookeeper
|
||||||
|
zkhandler.write(
|
||||||
|
[
|
||||||
|
(("volume.stats", f"{pool}/{name}"), volstats),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def add_volume(zkhandler, pool, name, size, force_flag=False, zk_only=False):
|
||||||
# 1. Verify the size of the volume
|
# 1. Verify the size of the volume
|
||||||
pool_information = getPoolInformation(zkhandler, pool)
|
pool_information = getPoolInformation(zkhandler, pool)
|
||||||
size_bytes = format_bytes_fromhuman(size)
|
size_bytes = format_bytes_fromhuman(size)
|
||||||
|
@ -592,27 +606,28 @@ def add_volume(zkhandler, pool, name, size, force_flag=False):
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2. Create the volume
|
# 2. Create the volume
|
||||||
retcode, stdout, stderr = common.run_os_command(
|
# zk_only flag skips actually creating the volume - this would be done by some other mechanism
|
||||||
"rbd create --size {}B {}/{}".format(size_bytes, pool, name)
|
if not zk_only:
|
||||||
)
|
retcode, stdout, stderr = common.run_os_command(
|
||||||
if retcode:
|
"rbd create --size {}B {}/{}".format(size_bytes, pool, name)
|
||||||
return False, 'ERROR: Failed to create RBD volume "{}": {}'.format(name, stderr)
|
)
|
||||||
|
if retcode:
|
||||||
# 2. Get volume stats
|
return False, 'ERROR: Failed to create RBD volume "{}": {}'.format(
|
||||||
retcode, stdout, stderr = common.run_os_command(
|
name, stderr
|
||||||
"rbd info --format json {}/{}".format(pool, name)
|
)
|
||||||
)
|
|
||||||
volstats = stdout
|
|
||||||
|
|
||||||
# 3. Add the new volume to Zookeeper
|
# 3. Add the new volume to Zookeeper
|
||||||
zkhandler.write(
|
zkhandler.write(
|
||||||
[
|
[
|
||||||
(("volume", f"{pool}/{name}"), ""),
|
(("volume", f"{pool}/{name}"), ""),
|
||||||
(("volume.stats", f"{pool}/{name}"), volstats),
|
(("volume.stats", f"{pool}/{name}"), ""),
|
||||||
(("snapshot", f"{pool}/{name}"), ""),
|
(("snapshot", f"{pool}/{name}"), ""),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 4. Scan the volume stats
|
||||||
|
scan_volume(zkhandler, pool, name)
|
||||||
|
|
||||||
return True, 'Created RBD volume "{}" of size "{}" in pool "{}".'.format(
|
return True, 'Created RBD volume "{}" of size "{}" in pool "{}".'.format(
|
||||||
name, format_bytes_tohuman(size_bytes), pool
|
name, format_bytes_tohuman(size_bytes), pool
|
||||||
)
|
)
|
||||||
|
@ -662,21 +677,18 @@ def clone_volume(zkhandler, pool, name_src, name_new, force_flag=False):
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# 3. Get volume stats
|
# 3. Add the new volume to Zookeeper
|
||||||
retcode, stdout, stderr = common.run_os_command(
|
|
||||||
"rbd info --format json {}/{}".format(pool, name_new)
|
|
||||||
)
|
|
||||||
volstats = stdout
|
|
||||||
|
|
||||||
# 4. Add the new volume to Zookeeper
|
|
||||||
zkhandler.write(
|
zkhandler.write(
|
||||||
[
|
[
|
||||||
(("volume", f"{pool}/{name_new}"), ""),
|
(("volume", f"{pool}/{name_new}"), ""),
|
||||||
(("volume.stats", f"{pool}/{name_new}"), volstats),
|
(("volume.stats", f"{pool}/{name_new}"), ""),
|
||||||
(("snapshot", f"{pool}/{name_new}"), ""),
|
(("snapshot", f"{pool}/{name_new}"), ""),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 4. Scan the volume stats
|
||||||
|
scan_volume(zkhandler, pool, name_new)
|
||||||
|
|
||||||
return True, 'Cloned RBD volume "{}" to "{}" in pool "{}"'.format(
|
return True, 'Cloned RBD volume "{}" to "{}" in pool "{}"'.format(
|
||||||
name_src, name_new, pool
|
name_src, name_new, pool
|
||||||
)
|
)
|
||||||
|
@ -761,20 +773,8 @@ def resize_volume(zkhandler, pool, name, size, force_flag=False):
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# 4. Get volume stats
|
# 4. Scan the volume stats
|
||||||
retcode, stdout, stderr = common.run_os_command(
|
scan_volume(zkhandler, pool, name)
|
||||||
"rbd info --format json {}/{}".format(pool, name)
|
|
||||||
)
|
|
||||||
volstats = stdout
|
|
||||||
|
|
||||||
# 5. Update the volume in Zookeeper
|
|
||||||
zkhandler.write(
|
|
||||||
[
|
|
||||||
(("volume", f"{pool}/{name}"), ""),
|
|
||||||
(("volume.stats", f"{pool}/{name}"), volstats),
|
|
||||||
(("snapshot", f"{pool}/{name}"), ""),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
return True, 'Resized RBD volume "{}" to size "{}" in pool "{}".'.format(
|
return True, 'Resized RBD volume "{}" to size "{}" in pool "{}".'.format(
|
||||||
name, format_bytes_tohuman(size_bytes), pool
|
name, format_bytes_tohuman(size_bytes), pool
|
||||||
|
@ -807,18 +807,8 @@ def rename_volume(zkhandler, pool, name, new_name):
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
# 3. Get volume stats
|
# 3. Scan the volume stats
|
||||||
retcode, stdout, stderr = common.run_os_command(
|
scan_volume(zkhandler, pool, new_name)
|
||||||
"rbd info --format json {}/{}".format(pool, new_name)
|
|
||||||
)
|
|
||||||
volstats = stdout
|
|
||||||
|
|
||||||
# 4. Update the volume stats in Zookeeper
|
|
||||||
zkhandler.write(
|
|
||||||
[
|
|
||||||
(("volume.stats", f"{pool}/{new_name}"), volstats),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
return True, 'Renamed RBD volume "{}" to "{}" in pool "{}".'.format(
|
return True, 'Renamed RBD volume "{}" to "{}" in pool "{}".'.format(
|
||||||
name, new_name, pool
|
name, new_name, pool
|
||||||
|
|
Loading…
Reference in New Issue