]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
backport: https://github.com/ceph/ceph/pull/54056
authorRedouane Kachach <rkachach@redhat.com>
Tue, 7 Nov 2023 12:26:25 +0000 (13:26 +0100)
committerRedouane Kachach <rkachach@redhat.com>
Tue, 7 Nov 2023 12:26:25 +0000 (13:26 +0100)
Signed-off-by: Redouane Kachach <rkachach@redhat.com>
src/pybind/mgr/rook/ci/Dockerfile [new file with mode: 0644]
src/pybind/mgr/rook/ci/run-rook-e2e-tests.sh [new file with mode: 0755]
src/pybind/mgr/rook/ci/scripts/bootstrap-rook-cluster.sh [new file with mode: 0755]
src/pybind/mgr/rook/ci/tests/features/rook.feature [new file with mode: 0644]
src/pybind/mgr/rook/ci/tests/features/steps/implementation.py [new file with mode: 0644]
src/pybind/mgr/rook/ci/tests/features/steps/utils.py [new file with mode: 0644]
src/pybind/mgr/tox.ini

diff --git a/src/pybind/mgr/rook/ci/Dockerfile b/src/pybind/mgr/rook/ci/Dockerfile
new file mode 100644 (file)
index 0000000..30ebea5
--- /dev/null
@@ -0,0 +1,3 @@
+FROM quay.io/ceph/daemon-base:latest-main
+COPY ./tmp_build/orchestrator /usr/share/ceph/mgr/orchestrator
+COPY ./tmp_build/rook /usr/share/ceph/mgr/rook
diff --git a/src/pybind/mgr/rook/ci/run-rook-e2e-tests.sh b/src/pybind/mgr/rook/ci/run-rook-e2e-tests.sh
new file mode 100755 (executable)
index 0000000..a43e01a
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+set -ex
+
+# Execute tests
+: ${CEPH_DEV_FOLDER:=${PWD}}
+${CEPH_DEV_FOLDER}/src/pybind/mgr/rook/ci/scripts/bootstrap-rook-cluster.sh
+cd ${CEPH_DEV_FOLDER}/src/pybind/mgr/rook/ci/tests
+behave
diff --git a/src/pybind/mgr/rook/ci/scripts/bootstrap-rook-cluster.sh b/src/pybind/mgr/rook/ci/scripts/bootstrap-rook-cluster.sh
new file mode 100755 (executable)
index 0000000..4b97df6
--- /dev/null
@@ -0,0 +1,135 @@
+#!/usr/bin/env bash
+
+set -eEx
+
+: ${CEPH_DEV_FOLDER:=${PWD}}
+KUBECTL="minikube kubectl --"
+
+# We build a local ceph image that contains the latest code
+# plus changes from the PR. This image will be used by the docker
+# running inside the minikube to start the different ceph pods
+LOCAL_CEPH_IMG="local/ceph"
+
+on_error() {
+    echo "on error"
+    minikube delete
+}
+
+configure_libvirt(){
+    sudo usermod -aG libvirt $(id -un)
+    sudo su -l $USER  # Avoid having to log out and log in for group addition to take effect.
+    sudo systemctl enable --now libvirtd
+    sudo systemctl restart libvirtd
+    sleep 10 # wait some time for libvirtd service to restart
+}
+
+setup_minikube_env() {
+
+    # Check if Minikube is running
+    if minikube status > /dev/null 2>&1; then
+       echo "Minikube is running"
+       minikube stop
+       minikube delete
+    else
+       echo "Minikube is not running"
+    fi
+
+    rm -rf ~/.minikube
+    minikube start --memory="4096" --cpus="2" --disk-size=10g --extra-disks=1 --driver kvm2
+    # point Docker env to use docker daemon running on minikube
+    eval $(minikube docker-env -p minikube)
+}
+
+build_ceph_image() {
+    wget -q -O cluster-test.yaml https://raw.githubusercontent.com/rook/rook/master/deploy/examples/cluster-test.yaml
+    CURR_CEPH_IMG=$(grep -E '^\s*image:\s+' cluster-test.yaml | sed 's/.*image: *\([^ ]*\)/\1/')
+
+    cd ${CEPH_DEV_FOLDER}/src/pybind/mgr/rook/ci
+    mkdir -p tmp_build/rook
+    mkdir -p tmp_build/orchestrator
+    cp ./../../orchestrator/*.py tmp_build/orchestrator
+    cp ../*.py tmp_build/rook
+
+    # we use the following tag to trick the Docker
+    # running inside minikube so it uses this image instead
+    # of pulling it from the registry
+    docker build --tag ${LOCAL_CEPH_IMG} .
+    docker tag ${LOCAL_CEPH_IMG} ${CURR_CEPH_IMG}
+
+    # cleanup
+    rm -rf tmp_build
+    cd ${CEPH_DEV_FOLDER}
+}
+
+create_rook_cluster() {
+    wget -q -O cluster-test.yaml https://raw.githubusercontent.com/rook/rook/master/deploy/examples/cluster-test.yaml
+    $KUBECTL create -f https://raw.githubusercontent.com/rook/rook/master/deploy/examples/crds.yaml
+    $KUBECTL create -f https://raw.githubusercontent.com/rook/rook/master/deploy/examples/common.yaml
+    $KUBECTL create -f https://raw.githubusercontent.com/rook/rook/master/deploy/examples/operator.yaml
+    $KUBECTL create -f cluster-test.yaml
+    $KUBECTL create -f https://raw.githubusercontent.com/rook/rook/master/deploy/examples/dashboard-external-http.yaml
+    $KUBECTL create -f https://raw.githubusercontent.com/rook/rook/master/deploy/examples/toolbox.yaml
+}
+
+wait_for_rook_operator() {
+    local max_attempts=10
+    local sleep_interval=20
+    local attempts=0
+    $KUBECTL rollout status deployment rook-ceph-operator -n rook-ceph --timeout=180s
+    PHASE=$($KUBECTL get cephclusters.ceph.rook.io -n rook-ceph -o jsonpath='{.items[?(@.kind == "CephCluster")].status.phase}')
+    echo "PHASE: $PHASE"
+    while ! $KUBECTL get cephclusters.ceph.rook.io -n rook-ceph -o jsonpath='{.items[?(@.kind == "CephCluster")].status.phase}' | grep -q "Ready"; do
+       echo "Waiting for cluster to be ready..."
+       sleep $sleep_interval
+       attempts=$((attempts+1))
+        if [ $attempts -ge $max_attempts ]; then
+            echo "Maximum number of attempts ($max_attempts) reached. Exiting..."
+            return 1
+        fi
+    done
+}
+
+wait_for_ceph_cluster() {
+    local max_attempts=10
+    local sleep_interval=20
+    local attempts=0
+    $KUBECTL rollout status deployment rook-ceph-tools -n rook-ceph --timeout=30s
+    while ! $KUBECTL get cephclusters.ceph.rook.io -n rook-ceph -o jsonpath='{.items[?(@.kind == "CephCluster")].status.ceph.health}' | grep -q "HEALTH_OK"; do
+       echo "Waiting for Ceph cluster installed"
+       sleep $sleep_interval
+       attempts=$((attempts+1))
+        if [ $attempts -ge $max_attempts ]; then
+            echo "Maximum number of attempts ($max_attempts) reached. Exiting..."
+            return 1
+        fi
+    done
+    echo "Ceph cluster installed and running"
+}
+
+show_info() {
+    DASHBOARD_PASSWORD=$($KUBECTL -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo)
+    IP_ADDR=$($KUBECTL get po --selector="app=rook-ceph-mgr" -n rook-ceph --output jsonpath='{.items[*].status.hostIP}')
+    PORT="$($KUBECTL -n rook-ceph -o=jsonpath='{.spec.ports[?(@.name == "dashboard")].nodePort}' get services rook-ceph-mgr-dashboard-external-http)"
+    BASE_URL="http://$IP_ADDR:$PORT"
+    echo "==========================="
+    echo "Ceph Dashboard:  "
+    echo "   IP_ADDRESS: $BASE_URL"
+    echo "   PASSWORD: $DASHBOARD_PASSWORD"
+    echo "==========================="
+}
+
+####################################################################
+####################################################################
+
+trap 'on_error $? $LINENO' ERR
+
+configure_libvirt
+setup_minikube_env
+build_ceph_image
+create_rook_cluster
+wait_for_rook_operator
+wait_for_ceph_cluster
+show_info
+
+####################################################################
+####################################################################
diff --git a/src/pybind/mgr/rook/ci/tests/features/rook.feature b/src/pybind/mgr/rook/ci/tests/features/rook.feature
new file mode 100644 (file)
index 0000000..ae0478f
--- /dev/null
@@ -0,0 +1,12 @@
+Feature: Testing Rook orchestrator commands
+    Ceph has been installed using the cluster CRD available in deploy/examples/cluster-test.yaml and
+
+    Scenario: Verify ceph cluster health
+      When I run
+          """
+          ceph health | grep HEALTH
+          """
+      Then I get
+          """
+          HEALTH_OK
+          """
diff --git a/src/pybind/mgr/rook/ci/tests/features/steps/implementation.py b/src/pybind/mgr/rook/ci/tests/features/steps/implementation.py
new file mode 100644 (file)
index 0000000..adde61a
--- /dev/null
@@ -0,0 +1,21 @@
+from behave import *
+from utils import *
+import re
+
+@when("I run")
+def run_step(context):
+    context.output = run_commands(context.text)
+
+@then("I get")
+def verify_result_step(context):
+    print(f"Output is:\n{context.output}\n--------------\n")
+    assert context.text == context.output
+
+@then("I get something like")
+def verify_fuzzy_result_step(context):
+    output_lines = context.output.split("\n")
+    expected_lines = context.text.split("\n")
+    num_lines = min(len(output_lines), len(expected_lines))
+    for n in range(num_lines):
+        if not re.match(expected_lines[n], output_lines[n]):
+            raise
diff --git a/src/pybind/mgr/rook/ci/tests/features/steps/utils.py b/src/pybind/mgr/rook/ci/tests/features/steps/utils.py
new file mode 100644 (file)
index 0000000..41a71d0
--- /dev/null
@@ -0,0 +1,29 @@
+import subprocess
+
+ROOK_CEPH_COMMAND = "minikube kubectl -- -n rook-ceph exec -it deploy/rook-ceph-tools -- "
+CLUSTER_COMMAND = "minikube kubectl -- "
+
+
+def execute_command(command: str) -> str:
+    output = ""
+    try:
+        proc = subprocess.run(command, shell=True, capture_output=True, text=True)
+        output = proc.stdout
+    except Exception as ex:
+        output = f"Error executing command: {ex}"
+
+    return output
+
+
+def run_commands(commands: str) -> str:
+    commands_list = commands.split("\n")
+    output = ""
+    for cmd in commands_list:
+        if cmd.startswith("ceph"):
+            prefix = ROOK_CEPH_COMMAND
+        else:
+            prefix = CLUSTER_COMMAND
+        command = prefix + cmd
+        output = execute_command(command)
+
+    return output.strip("\n")
index 0f2fe777f055da7cd36acaa2243a2ab15f88e428..6270dbdca51e3b1cbcee059a5d68295d0b5e5141 100644 (file)
@@ -49,6 +49,7 @@ setenv =
     UNITTEST = true
     PYTHONPATH = $PYTHONPATH:..
 deps =
+    behave
     -rrequirements.txt
     -rrook/requirements.txt
 commands =