Skip to content

Commit

Permalink
run pre-commit hook on all files
Browse files Browse the repository at this point in the history
Signed-off-by: Jan-Marten Brüggemann <[email protected]>
  • Loading branch information
brueggemann committed Mar 7, 2024
1 parent f616634 commit 3e00f77
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 96 deletions.
22 changes: 15 additions & 7 deletions src/rookify/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,46 @@
from types import MappingProxyType
from .yaml import load_yaml, save_yaml


def main():
try:
config = load_yaml("config.yaml")
except FileNotFoundError as err:
raise SystemExit(f'Could not load config: {err}')
preflight_modules, migration_modules = rookify.modules.load_modules(config['migration_modules'])
raise SystemExit(f"Could not load config: {err}")
preflight_modules, migration_modules = rookify.modules.load_modules(
config["migration_modules"]
)

module_data = dict()
try:
module_data.update(load_yaml(config['general']['module_data_file']))
module_data.update(load_yaml(config["general"]["module_data_file"]))
except FileNotFoundError:
pass

# Run preflight requirement modules
for preflight_module in preflight_modules:
handler = preflight_module.HANDLER_CLASS(config=MappingProxyType(config), data=MappingProxyType(module_data))
handler = preflight_module.HANDLER_CLASS(
config=MappingProxyType(config), data=MappingProxyType(module_data)
)
result = handler.run()
module_data[preflight_module.MODULE_NAME] = result

# Run preflight checks and append handlers to list
handlers = list()
for migration_module in migration_modules:
handler = migration_module.HANDLER_CLASS(config=MappingProxyType(config), data=MappingProxyType(module_data))
handler = migration_module.HANDLER_CLASS(
config=MappingProxyType(config), data=MappingProxyType(module_data)
)
handler.preflight_check()
handlers.append((migration_module, handler))

# Run migration modules
for migration_module, handler in handlers:
result = handler.run()
module_data[migration_module.MODULE_NAME] = result

save_yaml(config['general']['module_data_file'], module_data)
save_yaml(config["general"]["module_data_file"], module_data)


if __name__ == "__main__":
main()
49 changes: 34 additions & 15 deletions src/rookify/modules/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# -*- coding: utf-8 -*-

import functools
import importlib
import types

from typing import Optional
from collections import OrderedDict
from .module import ModuleHandler


class ModuleLoadException(Exception):
"""
ModuleLoadException is an exception class that can be raised during the dynamic load process for modules.
"""

def __init__(self, module_name: str, message: str):
"""
Construct a new 'ModuleLoadException' object.
Expand All @@ -21,6 +22,7 @@ def __init__(self, module_name: str, message: str):
self.module_name = module_name
self.message = message


def load_modules(module_names: list) -> tuple[list, list]:
"""
Dynamically loads modules from the 'modules' package.
Expand All @@ -30,60 +32,76 @@ def load_modules(module_names: list) -> tuple[list, list]:
"""

# Sanity checks for modules
def check_module_sanity(module_name: str, module: module):
def check_module_sanity(module_name: str, module: types.ModuleType):
for attr_type, attr_name in (
(ModuleHandler, 'HANDLER_CLASS'),
(str, 'MODULE_NAME'),
(list, 'REQUIRES'),
(list, 'AFTER'),
(list, 'PREFLIGHT_REQUIRES')
(ModuleHandler, "HANDLER_CLASS"),
(str, "MODULE_NAME"),
(list, "REQUIRES"),
(list, "AFTER"),
(list, "PREFLIGHT_REQUIRES"),
):
if not hasattr(module, attr_name):
raise ModuleLoadException(module_name, f'Module has no attribute {attr_name}')
raise ModuleLoadException(
module_name, f"Module has no attribute {attr_name}"
)

attr = getattr(module, attr_name)
if not isinstance(attr, attr_type) and not issubclass(attr, attr_type):
raise ModuleLoadException(module_name, f'Attribute {attr_name} is not type {attr_type}')
raise ModuleLoadException(
module_name, f"Attribute {attr_name} is not type {attr_type}"
)

# Load the modules in the given list and recursivley load required modules
required_modules = OrderedDict()

def load_required_modules(modules_out: OrderedDict, module_names: list) -> None:
for module_name in module_names:
if module_name in modules_out:
continue

module = importlib.import_module(f".{module_name}", 'rookify.modules')
module = importlib.import_module(f".{module_name}", "rookify.modules")
check_module_sanity(module_name, module)

load_required_modules(modules_out, module.REQUIRES)
module.AFTER.extend(module.REQUIRES)

modules_out[module_name] = module

load_required_modules(required_modules, module_names)

# Recursively load the modules in the PREFLIGHT_REQUIRES attribute of the given modules
preflight_modules = OrderedDict()
def load_preflight_modules(modules_in: OrderedDict, modules_out: OrderedDict, module_names: list) -> None:

def load_preflight_modules(
modules_in: OrderedDict, modules_out: OrderedDict, module_names: list
) -> None:
for module_name in module_names:
if module_name in modules_out:
continue

module = importlib.import_module(f".{module_name}", 'rookify.modules')
module = importlib.import_module(f".{module_name}", "rookify.modules")
check_module_sanity(module_name, module)

# We have to check, if the preflight_requires list is already loaded as migration requirement
for preflight_requirement in module.PREFLIGHT_REQUIRES:
if preflight_requirement in modules_in:
raise ModuleLoadException(module_name, f'Module {preflight_requirement} is already loaded as migration requirement')
raise ModuleLoadException(
module_name,
f"Module {preflight_requirement} is already loaded as migration requirement",
)

load_preflight_modules(modules_in, modules_out, module.PREFLIGHT_REQUIRES)
if module_name not in modules_in:
modules_out[module_name] = module

load_preflight_modules(required_modules, preflight_modules, required_modules.keys())

# Sort the modules by the AFTER keyword
modules = OrderedDict()
def sort_modules(modules_in: OrderedDict, modules_out: OrderedDict, module_names: list) -> None:

def sort_modules(
modules_in: OrderedDict, modules_out: OrderedDict, module_names: list
) -> None:
for module_name in module_names:
if module_name not in modules_in:
continue
Expand All @@ -95,6 +113,7 @@ def sort_modules(modules_in: OrderedDict, modules_out: OrderedDict, module_names
sort_modules(modules_in, modules_out, after_modules_name)

modules_out[module_name] = modules_in[module_name]

sort_modules(required_modules, modules, list(required_modules.keys()))

return list(preflight_modules.values()), list(modules.values())
4 changes: 2 additions & 2 deletions src/rookify/modules/analyze_ceph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

from .main import AnalyzeCephHandler

MODULE_NAME = 'analyze_ceph'
MODULE_NAME = "analyze_ceph"
HANDLER_CLASS = AnalyzeCephHandler
REQUIRES = []
AFTER = []
PREFLIGHT_REQUIRES = []
PREFLIGHT_REQUIRES = []
26 changes: 8 additions & 18 deletions src/rookify/modules/analyze_ceph/main.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
# -*- coding: utf-8 -*-

import json

from ..module import ModuleHandler

class AnalyzeCephHandler(ModuleHandler):

class AnalyzeCephHandler(ModuleHandler):
def run(self) -> dict:

commands = [
'mon dump',
'osd dump',
'device ls',
'fs dump',
'node ls'
]
commands = ["mon dump", "osd dump", "device ls", "fs dump", "node ls"]

results = dict()
for command in commands:
parts = command.split(' ')
parts = command.split(" ")
leaf = results
for idx, part in enumerate(parts):
if idx < len(parts) - 1:
Expand All @@ -27,12 +19,10 @@ def run(self) -> dict:
leaf[part] = self.ceph.mon_command(command)
leaf = leaf[part]

results['ssh'] = dict()
results['ssh']['osd'] = dict()
for node, values in results['node']['ls']['osd'].items():
devices = self.ssh.command(node, 'find /dev/ceph-*/*').stdout.splitlines()
results['ssh']['osd'][node] = {
'devices': devices
}
results["ssh"] = dict()
results["ssh"]["osd"] = dict()
for node, values in results["node"]["ls"]["osd"].items():
devices = self.ssh.command(node, "find /dev/ceph-*/*").stdout.splitlines()
results["ssh"]["osd"][node] = {"devices": devices}

return results
14 changes: 9 additions & 5 deletions src/rookify/modules/example/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

from .main import ExampleHandler

MODULE_NAME = 'example' # Name of the module
HANDLER_CLASS = ExampleHandler # Define the handler class for this module
REQUIRES = [] # A list of modules that are required to run before this module. Modules in this list will be imported, even if they are not configured
AFTER = ['migrate_monitors'] # A list of modules that should be run before this module, if they are defined in config
PREFLIGHT_REQUIRES = ['analyze_ceph'] # A list of modules that are required to run the preflight_check of this module. Modules in this list will be imported and run in preflight stage.
MODULE_NAME = "example" # Name of the module
HANDLER_CLASS = ExampleHandler # Define the handler class for this module
REQUIRES = [] # A list of modules that are required to run before this module. Modules in this list will be imported, even if they are not configured
AFTER = [
"migrate_monitors"
] # A list of modules that should be run before this module, if they are defined in config
PREFLIGHT_REQUIRES = [
"analyze_ceph"
] # A list of modules that are required to run the preflight_check of this module. Modules in this list will be imported and run in preflight stage.
4 changes: 2 additions & 2 deletions src/rookify/modules/example/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

from ..module import ModuleHandler, ModuleException

class ExampleHandler(ModuleHandler):

class ExampleHandler(ModuleHandler):
def preflight_check(self):
# Do something for checking if all needed preconditions are met else throw ModuleException
raise ModuleException('Example module was loaded, so aborting!')
raise ModuleException("Example module was loaded, so aborting!")

def run(self) -> dict:
# Run the migration tasks
Expand Down
4 changes: 2 additions & 2 deletions src/rookify/modules/migrate_monitors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

from .main import MigrateMonitorsHandler

MODULE_NAME = 'migrate_monitors'
MODULE_NAME = "migrate_monitors"
HANDLER_CLASS = MigrateMonitorsHandler
REQUIRES = []
AFTER = []
PREFLIGHT_REQUIRES = ['analyze_ceph']
PREFLIGHT_REQUIRES = ["analyze_ceph"]
1 change: 1 addition & 0 deletions src/rookify/modules/migrate_monitors/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

from ..module import ModuleHandler


class MigrateMonitorsHandler(ModuleHandler):
pass
6 changes: 3 additions & 3 deletions src/rookify/modules/migrate_osds/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

from .main import MigrateOSDsHandler

MODULE_NAME = 'migrate_osds'
MODULE_NAME = "migrate_osds"
HANDLER_CLASS = MigrateOSDsHandler
REQUIRES = []
AFTER = ['migrate_monitors']
PREFLIGHT_REQUIRES = [ 'analyze_ceph' ]
AFTER = ["migrate_monitors"]
PREFLIGHT_REQUIRES = ["analyze_ceph"]
34 changes: 17 additions & 17 deletions src/rookify/modules/migrate_osds/main.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
# -*- coding: utf-8 -*-

from ..module import ModuleHandler, ModuleException
from ..module import ModuleHandler

class MigrateOSDsHandler(ModuleHandler):

class MigrateOSDsHandler(ModuleHandler):
def preflight_check(self):
result = self.ceph.mon_command('osd dump')
#raise ModuleException('test error')
pass
# result = self.ceph.mon_command("osd dump")
# raise ModuleException('test error')

def run(self) -> dict:
osd_config = dict()
for node, osds in self._data['analyze_ceph']['node']['ls']['osd'].items():
osd_config[node] = {'osds': {}}
for node, osds in self._data["analyze_ceph"]["node"]["ls"]["osd"].items():
osd_config[node] = {"osds": {}}
for osd in osds:
osd_config[node]['osds'][osd] = dict()

osd_config[node]["osds"][osd] = dict()

for osd in self._data['analyze_ceph']['osd']['dump']['osds']:
number = osd['osd']
uuid = osd['uuid']
for osd in self._data["analyze_ceph"]["osd"]["dump"]["osds"]:
number = osd["osd"]
uuid = osd["uuid"]
for host in osd_config.values():
if number in host['osds']:
host['osds'][number]['uuid'] = uuid
if number in host["osds"]:
host["osds"][number]["uuid"] = uuid
break

for node, values in osd_config.items():
devices = self._data['analyze_ceph']['ssh']['osd'][node]['devices']
for osd in values['osds'].values():
devices = self._data["analyze_ceph"]["ssh"]["osd"][node]["devices"]
for osd in values["osds"].values():
for device in devices:
if osd['uuid'] in device:
osd['device'] = device
if osd["uuid"] in device:
osd["device"] = device
break

print(osd_config)
Loading

0 comments on commit 3e00f77

Please sign in to comment.