]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mgr/rook: implement `orch device zap` in rook orchestrator
authorJoseph Sawaya <jsawaya@redhat.com>
Thu, 9 Sep 2021 19:14:29 +0000 (15:14 -0400)
committerJoseph Sawaya <jsawaya@redhat.com>
Mon, 18 Oct 2021 19:06:03 +0000 (15:06 -0400)
This commit implements orch device zap by creating a pod on the target
host that mounts the /dev directory and runs either overwrites the first
few blocks of the device with zeros if it's a raw device or if it's not
a raw device it will use `ceph-volume lvm zap`.

Signed-off-by: Joseph Sawaya <jsawaya@redhat.com>
src/pybind/mgr/rook/module.py
src/pybind/mgr/rook/rook_cluster.py

index d1412a708374daf7fe6b09f0b2586dec355e499f..b08f6aa161dce20b9423186a07b0fa657ae70a9b 100644 (file)
@@ -1,3 +1,5 @@
+from logging import error
+import logging
 import threading
 import functools
 import os
@@ -442,6 +444,14 @@ class RookOrchestrator(MgrModule, orchestrator.Orchestrator):
         else:
             raise orchestrator.OrchestratorError(f'Service type {service_type} not supported')
 
+    def zap_device(self, host: str, path: str) -> OrchResult[str]:
+        try:
+            self.rook_cluster.create_zap_job(host, path)
+        except Exception as e:
+            logging.error(e)
+            return OrchResult(None, Exception("Unable to zap device: " + str(e.with_traceback(None))))
+        return OrchResult(f'{path} on {host} zapped') 
+
     @handle_orch_error
     def apply_mon(self, spec):
         # type: (ServiceSpec) -> str
index 1a28093509386cdb93fc762b5033db1137022a5f..8bc3561fbe19c75aef0db630b24e3a395ace212a 100644 (file)
@@ -1127,6 +1127,87 @@ class RookCluster(object):
             ret.append(spec)
         return ret
 
+    def create_zap_job(self, host: str, path: str) -> None:
+        body = client.V1Job(
+            api_version="batch/v1",
+            metadata=client.V1ObjectMeta(
+                name="rook-ceph-device-zap",
+                namespace="rook-ceph"
+            ),
+            spec=client.V1JobSpec(
+                template=client.V1PodTemplateSpec(
+                    spec=client.V1PodSpec(
+                        containers=[
+                            client.V1Container(
+                                name="device-zap",
+                                image="rook/ceph:master",
+                                command=["bash"],
+                                args=["-c", f"ceph-volume raw list {path} && dd if=/dev/zero of=\"{path}\" bs=1M count=1 oflag=direct,dsync || ceph-volume lvm zap --destroy {path}"],
+                                env=[
+                                    client.V1EnvVar(
+                                        name="ROOK_CEPH_USERNAME",
+                                        value_from=client.V1EnvVarSource(
+                                            secret_key_ref=client.V1SecretKeySelector(
+                                                key="ceph-username",
+                                                name="rook-ceph-mon"
+                                            )
+                                        )
+                                    ),
+                                    client.V1EnvVar(
+                                        name="ROOK_CEPH_SECRET",
+                                        value_from=client.V1EnvVarSource(
+                                            secret_key_ref=client.V1SecretKeySelector(
+                                                key="ceph-secret",
+                                                name="rook-ceph-mon"
+                                            )
+                                        )
+                                    )
+                                ],
+                                security_context=client.V1SecurityContext(
+                                    privileged=True
+                                ),
+                                volume_mounts=[
+                                    client.V1VolumeMount(
+                                        mount_path="/etc/ceph",
+                                        name="ceph-conf-emptydir"
+                                    ),
+                                    client.V1VolumeMount(
+                                        mount_path="/etc/rook",
+                                        name="rook-config"
+                                    ),
+                                    client.V1VolumeMount(
+                                        mount_path="/dev",
+                                        name="devices"
+                                    )
+                                ]
+                            )
+                        ],
+                        volumes=[
+                            client.V1Volume(
+                                name="ceph-conf-emptydir",
+                                empty_dir=client.V1EmptyDirVolumeSource()
+                            ),
+                            client.V1Volume(
+                                name="rook-config",
+                                empty_dir=client.V1EmptyDirVolumeSource()
+                            ),
+                            client.V1Volume(
+                                name="devices",
+                                host_path=client.V1HostPathVolumeSource(
+                                    path="/dev"
+                                )
+                            ),
+                        ],
+                        node_selector={
+                            "kubernetes.io/hostname": host
+                        },
+                        restart_policy="Never"
+                    )
+                )
+            )
+        )
+        self.batchV1_api.create_namespaced_job('rook-ceph', body)
+
     def _patch(self, crd: Type, crd_name: str, cr_name: str, func: Callable[[CrdClassT, CrdClassT], CrdClassT]) -> str:
         current_json = self.rook_api_get(
             "{}/{}".format(crd_name, cr_name)