From 758e650a280803bbe56469b78123cc37250e33c3 Mon Sep 17 00:00:00 2001 From: Hyounggyu Choi Date: Thu, 15 Aug 2024 13:37:11 +0200 Subject: [PATCH] tests: Ensure exec_host() consistently captures command output The `exec_host()` function often fails to capture the output of a given command because the node debugger pod is prematurely terminated. To address this issue, the function has been refactored to ensure consistent output capture by adjusting the `kubectl debug` process as follows: - Keep the node debugger pod running - Wait until the pod is fully ready - Execute the command using `kubectl exec` - Capture the output and terminate the pod This commit refactors `exec_host()` to implement the above steps, improving its reliability. Fixes: #10081 Signed-off-by: Hyounggyu Choi --- tests/integration/kubernetes/tests_common.sh | 52 +++++++++++--------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/tests/integration/kubernetes/tests_common.sh b/tests/integration/kubernetes/tests_common.sh index a93022d8aa..c88b4adecd 100644 --- a/tests/integration/kubernetes/tests_common.sh +++ b/tests/integration/kubernetes/tests_common.sh @@ -76,17 +76,17 @@ get_one_kata_node() { echo "${resource_name/"node/"}" } -# Deletes new_pod it wasn't present in the old_pods array. -delete_pod_if_new() { - declare -r new_pod="$1" - shift - declare -r old_pods=("$@") +# Get the new debugger pod that wasn't present in the old_pods array. +get_new_debugger_pod() { + local old_pods=("$@") + local new_pod_list=($(kubectl get pods -o name | grep node-debugger)) - for old_pod in "${old_pods[@]}"; do - [ "${old_pod}" == "${new_pod}" ] && return 0 - done - - kubectl delete "${new_pod}" >&2 + for new_pod in "${new_pod_list[@]}"; do + if [[ ! " ${old_pods[*]} " =~ " ${new_pod} " ]]; then + echo "${new_pod}" + return + fi + done } # Runs a command in the host filesystem. @@ -95,14 +95,24 @@ delete_pod_if_new() { # $1 - the node name # exec_host() { - node="$1" + local node="$1" # `kubectl debug` always returns 0, so we hack it to return the right exit code. - command="${@:2}" + local command="${@:2}" command+='; echo -en \\n$?' - # Get the already existing debugger pods. - declare -a old_debugger_pods=( $(kubectl get pods -o name | grep node-debugger) ) + # Get the already existing debugger pods + local old_debugger_pods=($(kubectl get pods -o name | grep node-debugger)) + # Run a debug pod + kubectl debug -q "node/${node}" --image=quay.io/bedrock/ubuntu:latest -- chroot /host bash -c "sleep infinity" >&2 + + # Identify the new debugger pod + local new_debugger_pod=$(get_new_debugger_pod "${old_debugger_pods[@]}") + + # Wait for the newly created pod to be ready + kubectl wait --timeout="30s" --for=condition=ready "${new_debugger_pod}" > /dev/null + + # Execute the command and capture the output # We're trailing the `\r` here due to: https://github.com/kata-containers/kata-containers/issues/8051 # tl;dr: When testing with CRI-O we're facing the following error: # ``` @@ -112,17 +122,13 @@ exec_host() { # [bats-exec-test:38] INFO: k8s configured to use runtimeclass # bash: line 1: $'\r': command not found # ``` - output="$(kubectl debug -qi "node/${node}" --image=quay.io/bedrock/ubuntu:latest -- chroot /host bash -c "${command}" | tr -d '\r')" + local output="$(kubectl exec -qi "${new_debugger_pod}" -- chroot /host bash -c "${command}" | tr -d '\r')" - # Get the updated list of debugger pods. - declare -a new_debugger_pods=( $(kubectl get pods -o name | grep node-debugger) ) + # Delete the newly created pod + kubectl delete "${new_debugger_pod}" >&2 - # Delete the debugger pod created above. - for new_pod in "${new_debugger_pods[@]}"; do - delete_pod_if_new "${new_pod}" "${old_debugger_pods[@]}" - done - - exit_code="$(echo "${output}" | tail -1)" + # Output the command result + local exit_code="$(echo "${output}" | tail -1)" echo "$(echo "${output}" | head -n -1)" return ${exit_code} }