From 654306d2c19b965510e0b7ca9c87520e36e01aa5 Mon Sep 17 00:00:00 2001 From: Daniel Hilst <392820+dhilst@users.noreply.github.com> Date: Wed, 16 Sep 2026 18:29:28 -0300 Subject: [PATCH] test(xcat-core): the error-command test writes the log archive to /run The first subiquity error command redirects tar's output into /run/#HOSTNAME#-logs.tar. The test shadows tar, but the redirection belongs to the shell and happens whether or not tar runs: $ bash -c 'tar() { :; }; ( tar ... >/run/testnode-logs.tar 2>/dev/null; exit 0 )' bash: line 1: /run/testnode-logs.tar: Permission denied exit=0 Unprivileged the open fails, "exit 0" swallows it and the test passes. CI runs as root, where the same line creates or truncates that file on the host. The archive path now comes from the environment, the way XCAT_ERROR_CONSOLE already does in the same block, and points inside BATS_TEST_TMPDIR. The tar shadow emits a marker so the test can tell the output reached the file it named, and a second assertion says the default path under /run was not touched. The new case fails until the template reads that variable. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com> (cherry picked from commit ac63d37843ba9c5207a8be7e750ed924426342ae) --- .../bats/ubuntu_subiquity_error_commands.bats | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/xCAT-test/bats/ubuntu_subiquity_error_commands.bats b/xCAT-test/bats/ubuntu_subiquity_error_commands.bats index 6c9ffd74a..677a7be3c 100644 --- a/xCAT-test/bats/ubuntu_subiquity_error_commands.bats +++ b/xCAT-test/bats/ubuntu_subiquity_error_commands.bats @@ -39,6 +39,11 @@ error_commands() # bash resolves a function ahead of PATH, so the commands run as written while nothing reaches # the host or the network. The nc shadow waits the way a listener with no collector waits. +# +# Shadowing a command does not stop the shell opening the file the command redirects into: the +# redirection is the shell's, and it happens whether or not tar runs. So the archive path is +# taken from the environment too, and pointed inside the test's own directory. Without that, +# this test truncates /run/testnode-logs.tar on the host running it, and CI runs as root. run_error_commands() { local script="${BATS_TEST_TMPDIR}/error-commands.sh" command @@ -46,8 +51,9 @@ run_error_commands() : >"$script" { printf "export XCAT_ERROR_CONSOLE='%s'\n" "$CONSOLE" + printf "export XCAT_ERROR_ARCHIVE='%s'\n" "$ARCHIVE" printf 'nc() { sleep 300; }\n' - printf 'tar() { :; }\n' + printf 'tar() { echo XCAT_LOGS_ARCHIVE; }\n' printf 'tail() { echo XCAT_CURTIN_LOG_TAIL; }\n' } >>"$script" @@ -63,8 +69,26 @@ run_error_commands() @test "the error commands return instead of waiting for someone to collect the logs" { [ -n "$(error_commands)" ] CONSOLE="${BATS_TEST_TMPDIR}/console" + ARCHIVE="${BATS_TEST_TMPDIR}/logs.tar" run run_error_commands [ "$status" -ne 124 ] grep -q XCAT_CURTIN_LOG_TAIL "$CONSOLE" } + +@test "the log archive is written where the caller points, and nowhere else" { + CONSOLE="${BATS_TEST_TMPDIR}/console" + ARCHIVE="${BATS_TEST_TMPDIR}/logs.tar" + + run run_error_commands + [ "$status" -ne 124 ] + + # The archive command redirects into the path it was given, so its output is the proof + # that the redirection went there and not to the default under /run. + grep -q XCAT_LOGS_ARCHIVE "$ARCHIVE" + + # And the default path is untouched. This assertion is what an unprivileged run cannot + # make for itself -- there the write fails silently and "exit 0" hides it -- but CI runs + # as root, where the same redirection truncates the file. + [ ! -e /run/testnode-logs.tar ] +}