Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ceph_crush: add support check mode #7534

Merged
merged 2 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 66 additions & 17 deletions library/ceph_crush.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,62 @@ def sort_osd_crush_location(location, module):
fatal("{} is not a valid CRUSH bucket, valid bucket types are {}".format(error.args[0].split()[0], crush_bucket_types), module) # noqa: E501


def create_and_move_buckets_list(cluster, location, containerized=None):
def get_crush_tree(module, cluster, containerized=None):
'''
Get the CRUSH map
'''
cmd = [
'ceph',
'--cluster',
cluster,
'osd',
'crush',
'tree',
'--format',
'json',
]
if containerized:
cmd = containerized.split() + cmd

rc, out, err = module.run_command(cmd)
return rc, cmd, out, err


def create_and_move_buckets_list(cluster, location, crush_map, containerized=None): # noqa: E501
'''
Creates Ceph CRUSH buckets and arrange the hierarchy
'''
def bucket_exists(bucket_name, bucket_type):
for item in crush_map['nodes']:
if item['name'] == bucket_name and item['type'] == bucket_type:
return True
return False

def bucket_in_place(bucket_name, target_bucket_name, target_bucket_type): # noqa: E501
bucket_id = None
target_bucket = None
for item in crush_map['nodes']:
if item['name'] == bucket_name:
bucket_id = item['id']
if item['name'] == target_bucket_name and item['type'] == target_bucket_type: # noqa: E501
target_bucket = item

if not bucket_id or not target_bucket:
return False

return bucket_id in target_bucket['children']

previous_bucket = None
cmd_list = []
for item in location:
bucket_type, bucket_name = item
# ceph osd crush add-bucket maroot root
cmd_list.append(generate_cmd(cluster, "add-bucket", bucket_name, bucket_type, containerized)) # noqa: E501
if not bucket_exists(bucket_name, bucket_type):
cmd_list.append(generate_cmd(cluster, "add-bucket", bucket_name, bucket_type, containerized)) # noqa: E501
if previous_bucket:
# ceph osd crush move monrack root=maroot
cmd_list.append(generate_cmd(cluster, "move", previous_bucket, "%s=%s" % (bucket_type, bucket_name), containerized)) # noqa: E501
if not bucket_in_place(previous_bucket, bucket_name, bucket_type): # noqa: E501
cmd_list.append(generate_cmd(cluster, "move", previous_bucket, "%s=%s" % (bucket_type, bucket_name), containerized)) # noqa: E501
previous_bucket = item[1]
return cmd_list

Expand Down Expand Up @@ -154,23 +197,28 @@ def main():
location = sort_osd_crush_location(tuple(location_dict.items()), module)
containerized = module.params['containerized']

result = dict(
changed=False,
stdout='',
stderr='',
rc=0,
start='',
end='',
delta='',
)
diff = dict(before="", after="")
startd = datetime.datetime.now()

if module.check_mode:
module.exit_json(**result)
# get the CRUSH map
rc, cmd, out, err = get_crush_tree(module, cluster, containerized)
if rc != 0 and not module.check_mode:
module.fail_json(msg='non-zero return code', rc=rc, stdout=out, stderr=err) # noqa: E501

startd = datetime.datetime.now()
# parse the JSON output
if rc == 0:
crush_map = module.from_json(out)
else:
crush_map = {"nodes": []}

# run the Ceph command to add buckets
rc, cmd, out, err = exec_commands(module, create_and_move_buckets_list(cluster, location, containerized)) # noqa: E501
cmd_list = create_and_move_buckets_list(cluster, location, crush_map, containerized) # noqa: E501

changed = len(cmd_list) > 0
if changed:
diff['after'] = module.jsonify(cmd_list)
if not module.check_mode:
rc, cmd, out, err = exec_commands(module, cmd_list) # noqa: E501

endd = datetime.datetime.now()
delta = endd - startd
Expand All @@ -183,7 +231,8 @@ def main():
rc=rc,
stdout=out.rstrip("\r\n"),
stderr=err.rstrip("\r\n"),
changed=True,
changed=changed,
diff=diff
)

if rc != 0:
Expand Down
2 changes: 2 additions & 0 deletions library/ceph_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,11 +626,13 @@ def run_module():

elif action == 'list':
# List Ceph LVM Metadata on a device
changed = False
rc, cmd, out, err = exec_command(
module, list_osd(module, container_image))

elif action == 'inventory':
# List storage device inventory.
changed = False
rc, cmd, out, err = exec_command(
module, list_storage_inventory(module, container_image))

Expand Down
Loading