Add support for replacing/refreshing OSDs

Adds commands to both replace an OSD disk, and refresh (reimport) an
existing OSD disk on a new node. This handles the cases where an OSD
disk should be replaced (either due to upgrades or failures) or where a
node is rebuilt in-place and an existing OSD must be re-imported to it.

This should avoid the need to do a full remove/add sequence for either
case.

Also cleans up some aspects of OSD removal that are identical between
methods (e.g. using safe-to-destroy and sleeping after stopping) and
fixes a bug if an OSD does not truly exist when the daemon starts up.
This commit is contained in:
2022-05-06 15:31:58 -04:00
parent 8027a6efdc
commit 7a40c7a55b
7 changed files with 853 additions and 37 deletions

View File

@ -4097,6 +4097,102 @@ class API_Storage_Ceph_OSD_Element(Resource):
"""
return api_helper.ceph_osd_list(osdid)
@RequestParser(
[
{
"name": "device",
"required": True,
"helptext": "A valid device or detect string must be specified.",
},
{
"name": "weight",
"required": True,
"helptext": "An OSD weight must be specified.",
},
{
"name": "yes-i-really-mean-it",
"required": True,
"helptext": "Please confirm that 'yes-i-really-mean-it'.",
},
]
)
@Authenticator
def post(self, osdid, reqargs):
"""
Replace a Ceph OSD in the cluster
Note: This task may take up to 30s to complete and return
---
tags:
- storage / ceph
parameters:
- in: query
name: device
type: string
required: true
description: The block device (e.g. "/dev/sdb", "/dev/disk/by-path/...", etc.) or detect string ("detect:NAME:SIZE:ID") to replace the OSD onto
- in: query
name: weight
type: number
required: true
description: The Ceph CRUSH weight for the replaced OSD
responses:
200:
description: OK
schema:
type: object
id: Message
400:
description: Bad request
schema:
type: object
id: Message
"""
return api_helper.ceph_osd_replace(
osdid,
reqargs.get("device", None),
reqargs.get("weight", None),
)
@RequestParser(
[
{
"name": "device",
"required": True,
"helptext": "A valid device or detect string must be specified.",
},
]
)
@Authenticator
def put(self, osdid, reqargs):
"""
Refresh (reimport) a Ceph OSD in the cluster
Note: This task may take up to 30s to complete and return
---
tags:
- storage / ceph
parameters:
- in: query
name: device
type: string
required: true
description: The block device (e.g. "/dev/sdb", "/dev/disk/by-path/...", etc.) or detect string ("detect:NAME:SIZE:ID") that the OSD should be using
responses:
200:
description: OK
schema:
type: object
id: Message
400:
description: Bad request
schema:
type: object
id: Message
"""
return api_helper.ceph_osd_refresh(
osdid,
reqargs.get("device", None),
)
@RequestParser(
[
{

View File

@ -1301,6 +1301,38 @@ def ceph_osd_add(zkhandler, node, device, weight, ext_db_flag=False, ext_db_rati
return output, retcode
@ZKConnection(config)
def ceph_osd_replace(zkhandler, osd_id, device, weight):
"""
Replace a Ceph OSD in the PVC Ceph storage cluster.
"""
retflag, retdata = pvc_ceph.replace_osd(zkhandler, osd_id, device, weight)
if retflag:
retcode = 200
else:
retcode = 400
output = {"message": retdata.replace('"', "'")}
return output, retcode
@ZKConnection(config)
def ceph_osd_refresh(zkhandler, osd_id, device):
"""
Refresh (reimport) a Ceph OSD in the PVC Ceph storage cluster.
"""
retflag, retdata = pvc_ceph.refresh_osd(zkhandler, osd_id, device)
if retflag:
retcode = 200
else:
retcode = 400
output = {"message": retdata.replace('"', "'")}
return output, retcode
@ZKConnection(config)
def ceph_osd_remove(zkhandler, osd_id, force_flag):
"""