From f44551093e767a21386549bf94ebce37baf303a8 Mon Sep 17 00:00:00 2001 From: Tobias Wolf Date: Thu, 21 Nov 2024 17:41:35 +0100 Subject: [PATCH 1/2] Add support to change behaviour based on feature flags This commit supports feature flags for: - Ceph - Kubernetes - Rook As we do not have feature flags for Ceph or Kubernetes yet any key is currently accepted. This will change once needed. Signed-off-by: Tobias Wolf --- config.example.osism.yaml | 2 ++ config.example.yaml | 3 +++ src/rookify/config.schema.yaml | 6 ++++++ src/rookify/modules/ceph.py | 4 ++++ src/rookify/modules/k8s.py | 13 +++++++++++++ 5 files changed, 28 insertions(+) diff --git a/config.example.osism.yaml b/config.example.osism.yaml index a9b4909..0640852 100644 --- a/config.example.osism.yaml +++ b/config.example.osism.yaml @@ -39,6 +39,8 @@ rook: rgw_placement_label: node-role.osism.tech/rook-rgw ceph: image: quay.io/ceph/ceph:v18.2.1 + flags: + mds_support_metadata_name: False migration_modules: - example diff --git a/config.example.yaml b/config.example.yaml index e6c95a3..34679da 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -40,6 +40,8 @@ rook: namespace: rook-ceph ceph: image: quay.io/ceph/ceph:v18.2.1 + flags: + mds_support_metadata_name: False migration_modules: - example @@ -48,5 +50,6 @@ migration_modules: - migrate_osd_pools - migrate_mds - migrate_mds_pools +- migrate_mgrs - migrate_rgws - migrate_rgw_pools diff --git a/src/rookify/config.schema.yaml b/src/rookify/config.schema.yaml index 8f9da4f..5112e7c 100644 --- a/src/rookify/config.schema.yaml +++ b/src/rookify/config.schema.yaml @@ -9,6 +9,7 @@ logging: ceph: config: str() + flags: map(key=str(), required=False) # @TODO: Replace with include once we support at least one Ceph flag keyring: str() systemd_file_name_templates: include("systemd_file_name_templates", required=False) @@ -18,6 +19,7 @@ ssh: kubernetes: config: str() + flags: map(key=str(), required=False) # @TODO: Replace with include once we support at least one Kubernetes flag rook: cluster: @@ -34,9 +36,13 @@ rook: image: str() public_network: regex("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|2[0-9]|1[0-9]|[0-9]))?$", required=False) cluster_network: regex("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|2[0-9]|1[0-9]|[0-9]))?$", required=False) + flags: include("rook_flags", required=False) migration_modules: list(str()) --- +rook_flags: + mds_support_metadata_name: bool() +--- ssh_host: address: ip() user: str() diff --git a/src/rookify/modules/ceph.py b/src/rookify/modules/ceph.py index 0f180aa..f1819a5 100644 --- a/src/rookify/modules/ceph.py +++ b/src/rookify/modules/ceph.py @@ -18,6 +18,7 @@ def __init__(self, config: Dict[str, Any]): status_data = self.mon_command("status") + self._flags: Dict[str, bool] = config.get("flags", {}) self._fsid = status_data["fsid"] self._systemd_file_name_templates = config.get( @@ -40,6 +41,9 @@ def _json_command(self, handler: Any, *args: Any) -> Any: return data + def get_flag(self, name: str, default_value: bool = False) -> bool: + return self._flags.get(name, default_value) + def get_systemd_mds_file_name(self, host: str) -> str: return self._get_systemd_template_file_name( self._systemd_file_name_templates.get("mds", "ceph-mds.target"), diff --git a/src/rookify/modules/k8s.py b/src/rookify/modules/k8s.py index 17edc11..9ec814d 100644 --- a/src/rookify/modules/k8s.py +++ b/src/rookify/modules/k8s.py @@ -11,7 +11,9 @@ def __init__(self, config: Dict[str, Any]): config_file=config["kubernetes"]["config"] ) + self._flags: Dict[str, bool] = config["kubernetes"].get("flags", {}) self._rook_config = config["rook"] + self._rook_flags: Dict[str, bool] = config["rook"].get("flags", {}) self.__client = kubernetes.client.ApiClient(k8s_config) self.__dynamic_client: Optional[kubernetes.dynamic.DynamicClient] = None @@ -116,6 +118,17 @@ def crd_api_apply( except kubernetes.dynamic.exceptions.NotFoundError: return crd_api.create(body=manifest, namespace=namespace) + def _get_flag( + self, flags: Dict[str, bool], name: str, default_value: bool = False + ) -> bool: + return flags.get(name, default_value) + + def get_flag(self, name: str, default_value: bool = False) -> bool: + return self._get_flag(self._flags, name, default_value) + + def get_rook_flag(self, name: str, default_value: bool = False) -> bool: + return self._get_flag(self._rook_flags, name, default_value) + def watch_events( self, callback_func: Callable[[Any], Any], From 4f2b569abf96948a7f8adfdd8c85af27b7d8574a Mon Sep 17 00:00:00 2001 From: Tobias Wolf Date: Fri, 22 Nov 2024 04:44:10 +0100 Subject: [PATCH 2/2] Add logic to handle Rook flag for MDS metadata pool names support Signed-off-by: Tobias Wolf --- src/rookify/modules/migrate_mds_pools/main.py | 47 ++++++++++++------- .../templates/filesystem.yaml.j2 | 3 ++ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/rookify/modules/migrate_mds_pools/main.py b/src/rookify/modules/migrate_mds_pools/main.py index bd84cf5..be8f64d 100644 --- a/src/rookify/modules/migrate_mds_pools/main.py +++ b/src/rookify/modules/migrate_mds_pools/main.py @@ -20,29 +20,22 @@ def preflight(self) -> None: state_data["report"]["osdmap"] ) + are_custom_metadata_pool_names_supported = self.k8s.get_rook_flag( + "mds_support_metadata_name", True + ) + for mds_fs_data in state_data["fs"]["ls"]: - if not mds_fs_data["metadata_pool"].endswith("-metadata"): + if not ( + are_custom_metadata_pool_names_supported + and mds_fs_data["metadata_pool"].endswith("-metadata") + ): self.logger.warn( "ceph-mds filesystem '{0}' uses an incompatible pool metadata name '{1}' and can not be migrated to Rook automatically".format( mds_fs_data["name"], mds_fs_data["metadata_pool"] ) ) - # Store pools for incompatible MDS filesystem as migrated ones - migrated_pools = self.machine.get_execution_state_data( - "MigrateMdsPoolsHandler", "migrated_pools", default_value=[] - ) - - if mds_fs_data["metadata_pool"] not in migrated_pools: - migrated_pools.append(mds_fs_data["metadata_pool"]) - - for pool_data_osd_name in mds_fs_data["data_pools"]: - if pool_data_osd_name not in migrated_pools: - migrated_pools.append(pool_data_osd_name) - - state = self.machine.get_execution_state("MigrateMdsPoolsHandler") - if state is not None: - state.migrated_pools = migrated_pools + self._handle_mds_metadata_pool_not_supported(mds_fs_data) continue @@ -92,6 +85,23 @@ def get_readable_key_value_state(self) -> Dict[str, str]: return kv_state_data + def _handle_mds_metadata_pool_not_supported(self, mds_fs_data: Any) -> None: + # Store pools for incompatible MDS filesystem as migrated ones + migrated_pools = self.machine.get_execution_state_data( + "MigrateMdsPoolsHandler", "migrated_pools", default_value=[] + ) + + if mds_fs_data["metadata_pool"] not in migrated_pools: + migrated_pools.append(mds_fs_data["metadata_pool"]) + + for pool_data_osd_name in mds_fs_data["data_pools"]: + if pool_data_osd_name not in migrated_pools: + migrated_pools.append(pool_data_osd_name) + + state = self.machine.get_execution_state("MigrateMdsPoolsHandler") + if state is not None: + state.migrated_pools = migrated_pools + def _migrate_pool(self, pool: Dict[str, Any]) -> None: migrated_mds_pools = self.machine.get_execution_state_data( "MigrateMdsPoolsHandler", "migrated_mds_pools", default_value=[] @@ -118,6 +128,11 @@ def _migrate_pool(self, pool: Dict[str, Any]) -> None: "mds_placement_label": self.k8s.mds_placement_label, } + if self.k8s.get_rook_flag("mds_support_metadata_name", True): + filesystem_definition_values["mds_name"] = pool_metadata_osd_configuration[ + "pool_name" + ] + filesystem_definition_values["data_pools"] = [] for pool_data_osd_name in pool["data"]: diff --git a/src/rookify/modules/migrate_mds_pools/templates/filesystem.yaml.j2 b/src/rookify/modules/migrate_mds_pools/templates/filesystem.yaml.j2 index 2657642..e8853eb 100644 --- a/src/rookify/modules/migrate_mds_pools/templates/filesystem.yaml.j2 +++ b/src/rookify/modules/migrate_mds_pools/templates/filesystem.yaml.j2 @@ -14,6 +14,9 @@ metadata: spec: # The metadata pool spec. Must use replication. metadataPool: + {% if mds_name %} + name: {{ mds_name }} + {% endif %} replicated: size: {{ mds_size }} requireSafeReplicaSize: true