Skip to content

Commit

Permalink
Use data of ceph report for analysis instead of multiple sources
Browse files Browse the repository at this point in the history
Signed-off-by: Tobias Wolf <[email protected]>
  • Loading branch information
NotTheEvilOne authored Oct 21, 2024
1 parent b745bcd commit 7d464bc
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 45 deletions.
63 changes: 36 additions & 27 deletions src/rookify/modules/analyze_ceph/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,45 @@


class AnalyzeCephHandler(ModuleHandler):
def _process_command(
def _process_command_result(
self, state_data: Any, command: str, value: Optional[Any] = None
) -> bool:
"""Helper method to process commands by either setting or checking state data."""
parts = command.split(" ")
current_level = state_data # the root of the data structure
"""
Helper method to process commands by either setting or checking state data.
"""

command_parts = command.split(" ")
state_structure_data = state_data # the root of the data structure

# Traverse the dictionary structure based on command parts
for idx, part in enumerate(parts):
if len(parts) == idx + 1: # Last part of the command
if value is not None:
current_level[part] = value
else:
return part in current_level
for idx, key in enumerate(command_parts):
# Last part of the command
if len(command_parts) == idx + 1:
if value is None:
return key in state_structure_data

state_structure_data[key] = value
else:
if part not in current_level:
current_level[part] = {}
current_level = current_level[part]
if key not in state_structure_data:
state_structure_data[key] = {}

state_structure_data = state_structure_data[key]

return True

def preflight(self) -> Any:
commands = ["mon dump", "osd dump", "device ls", "fs ls", "node ls"]
state = self.machine.get_preflight_state("AnalyzeCephHandler")

if getattr(state, "data", None) is not None:
return

commands = ["fs ls", "node ls", "report"]
state.data = {}

# Execute each command and store the result
for command in commands:
result = self.ceph.mon_command(command)
self._process_command(state.data, command, result)
self._process_command_result(state.data, command, result)

self.logger.info("AnalyzeCephHandler ran successfully.")

Expand All @@ -45,25 +54,25 @@ def get_readable_key_value_state(self) -> Dict[str, str]:

kv_state_data = OrderedDict()

if "mon" not in state.data or "dump" not in state.data["mon"]:
kv_state_data["ceph mon dump"] = "Not analyzed yet"
if "report" not in state.data:
kv_state_data["Ceph report"] = "Not analyzed yet"
else:
kv_state_data["ceph mon dump"] = self._get_readable_json_dump(
state.data["mon"]["dump"]
kv_state_data["Ceph report"] = self._get_readable_json_dump(
state.data["report"]
)

if "osd" not in state.data or "dump" not in state.data["osd"]:
kv_state_data["ceph osd dump"] = "Not analyzed yet"
if "node" not in state.data or "ls" not in state.data["node"]:
kv_state_data["Ceph node ls"] = "Not analyzed yet"
else:
kv_state_data["ceph osd dump"] = self._get_readable_json_dump(
state.data["osd"]["dump"]
kv_state_data["Ceph node ls"] = self._get_readable_json_dump(
state.data["node"]["ls"]
)

if "device" not in state.data or "ls" not in state.data["device"]:
kv_state_data["OSD devices"] = "Not analyzed yet"
if "fs" not in state.data or "ls" not in state.data["fs"]:
kv_state_data["Ceph fs ls"] = "Not analyzed yet"
else:
kv_state_data["OSD devices"] = self._get_readable_json_dump(
state.data["device"]["ls"]
kv_state_data["Ceph fs ls"] = self._get_readable_json_dump(
state.data["fs"]["ls"]
)

return kv_state_data
Expand Down
2 changes: 1 addition & 1 deletion src/rookify/modules/cephx_auth_config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


class CephXAuthHandler(ModuleHandler):
def preflight(self) -> Any:
def preflight(self) -> None:
if not self.is_cephx_set(self.ceph.conf_get("auth_cluster_required")):
raise ModuleException(
"Ceph config value auth_cluster_required does not contain cephx"
Expand Down
4 changes: 2 additions & 2 deletions src/rookify/modules/create_rook_resources/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __create_configmap_definition(self) -> None:
configmap_mon_list = ""
mapping = {}

for mon in state_data["mon"]["dump"]["mons"]:
for mon in state_data["report"]["monmap"]["mons"]:
if configmap_mon_list != "":
configmap_mon_list += ","

Expand Down Expand Up @@ -120,7 +120,7 @@ def execute(self) -> None:
secret_data = {
"admin-secret": admin_auth["key"],
"cluster-name": self._config["rook"]["cluster"]["name"],
"fsid": state_data["mon"]["dump"]["fsid"],
"fsid": state_data["report"]["monmap"]["fsid"],
"mon-secret": mon_auth["key"],
}

Expand Down
4 changes: 3 additions & 1 deletion src/rookify/modules/migrate_mds_pools/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ def get_readable_key_value_state(self) -> Dict[str, str]:
"MigrateMdsPoolsHandler", "migrated_mds_pools", default_value=[]
)

pools = self.machine.get_preflight_state("MigrateMdsPoolsHandler").pools
pools = self.machine.get_preflight_state_data(
"MigrateMdsPoolsHandler", "pools", default_value={}
)

kv_state_data = OrderedDict()

Expand Down
6 changes: 3 additions & 3 deletions src/rookify/modules/migrate_mons/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ def execute(self) -> None:
"MigrateMonsHandler", "migrated_mons", default_value=[]
)

if len(migrated_mons) >= len(state_data["mon"]["dump"]["mons"]):
if len(migrated_mons) >= len(state_data["report"]["monmap"]["mons"]):
return

for mon in state_data["mon"]["dump"]["mons"]:
for mon in state_data["report"]["monmap"]["mons"]:
self._migrate_mon(mon)

def get_readable_key_value_state(self) -> Dict[str, str]:
state_data = self.machine.get_preflight_state("AnalyzeCephHandler").data

return {
"ceph mon daemons": self._get_readable_json_dump(
state_data["mon"]["dump"]["mons"]
state_data["report"]["monmap"]["mons"]
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/rookify/modules/migrate_osd_pools/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def _get_filtered_osd_pools_list(self) -> List[Dict[str, Any]]:
state_data = self.machine.get_preflight_state("AnalyzeCephHandler").data

osd_pool_configurations = self.ceph.get_osd_pool_configurations_from_osd_dump(
state_data["osd"]["dump"]
state_data["report"]["osdmap"]
)

pools = []
Expand Down
13 changes: 11 additions & 2 deletions src/rookify/modules/migrate_osds/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@


class MigrateOSDsHandler(ModuleHandler):
REQUIRES = ["migrate_mons"]
REQUIRES = ["analyze_ceph", "migrate_mons"]

def _get_devices_of_hosts(self) -> Dict[str, Dict[str, str]]:
state_data = self.machine.get_preflight_state("AnalyzeCephHandler").data

osd_devices: Dict[str, Dict[str, str]] = {}
osd_metadata = {
str(osd_data["id"]): osd_data for osd_data in state_data["osd_metadata"]
}

for osd_host, osds in state_data["node"]["ls"]["osd"].items():
osd_devices[osd_host] = {}
Expand All @@ -23,7 +27,12 @@ def _get_devices_of_hosts(self) -> Dict[str, Dict[str, str]]:
From there we try to get the encrypted volume partition UUID for later use in Rook.
"""
for osd_id in osds:
osd_data = self.ceph.mon_command("osd metadata", id=osd_id)
if osd_id not in osd_metadata:
raise ModuleException(
"Found Ceph OSD ID {0} without metadata".format(osd_id)
)

osd_data = osd_metadata[osd_id]

result = self.ssh.command(
osd_host,
Expand Down
14 changes: 9 additions & 5 deletions src/rookify/modules/migrate_rgw_pools/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ def preflight(self) -> None:
if len(zones) > 0:
return

service_data = self.ceph.mon_command("service dump")

rgw_daemons = service_data["services"].get("rgw", {}).get("daemons", {})
rgw_daemons = (
state_data["report"]["servicemap"]["services"]
.get("rgw", {})
.get("daemons", {})
)

for rgw_daemon in rgw_daemons.values():
if not isinstance(rgw_daemon, dict):
Expand All @@ -36,7 +38,7 @@ def preflight(self) -> None:
zones[zone_name] = {"osd_pools": {}, "rgw_count": 1}

osd_pools = self.ceph.get_osd_pool_configurations_from_osd_dump(
state_data["osd"]["dump"]
state_data["report"]["osdmap"]
)

for zone_name in zones:
Expand Down Expand Up @@ -76,7 +78,9 @@ def get_readable_key_value_state(self) -> Dict[str, str]:
"MigrateRgwPoolsHandler", "migrated_pools", default_value=[]
)

zones = self.machine.get_preflight_state("MigrateRgwPoolsHandler").zones
zones = self.machine.get_preflight_state_data(
"MigrateRgwPoolsHandler", "zones", default_value={}
)

kv_state_data = OrderedDict()

Expand Down
8 changes: 5 additions & 3 deletions src/rookify/modules/migrate_rgws/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@


class MigrateRgwsHandler(ModuleHandler):
REQUIRES = ["migrate_rgw_pools"]
REQUIRES = ["analyze_ceph", "migrate_rgw_pools"]

def _get_rgw_daemon_hosts(self) -> List[str]:
ceph_status = self.ceph.mon_command("status")
state_data = self.machine.get_preflight_state("AnalyzeCephHandler").data

rgw_daemons = ceph_status["servicemap"]["services"]["rgw"]["daemons"]
rgw_daemons = state_data["report"]["servicemap"]["services"]["rgw"]["daemons"]
rgw_daemon_hosts = []

if "summary" in rgw_daemons:
del rgw_daemons["summary"]

Expand All @@ -23,6 +24,7 @@ def _get_rgw_daemon_hosts(self) -> List[str]:
raise ModuleException(
"Unexpected ceph-rgw daemon metadata: {0}".format(rgw_daemon)
)

if rgw_daemon["metadata"]["hostname"] not in rgw_daemon_hosts:
rgw_daemon_hosts.append(rgw_daemon["metadata"]["hostname"])

Expand Down

0 comments on commit 7d464bc

Please sign in to comment.