From ab3d1471a6105fb43b50a0f5d795b127661babd6 Mon Sep 17 00:00:00 2001 From: rishabkumar7 Date: Mon, 1 Jun 2026 15:33:16 -0500 Subject: [PATCH 01/10] Update README and main.tf for CTF setup improvements and troubleshooting guidance --- azure/README.md | 10 +++++- azure/main.tf | 94 +++++++++++++++++++++++++------------------------ 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/azure/README.md b/azure/README.md index 8cfa09c..29a5ff9 100644 --- a/azure/README.md +++ b/azure/README.md @@ -93,9 +93,17 @@ Type `yes` when prompted. ## Troubleshooting 1. Ensure your Azure CLI is logged in with valid credentials -2. Check that you're using Terraform v1.9.0 or later +2. Check that you're using Terraform v1.14.0 or later 3. Verify you have permissions to create VMs, VNets, and Network Security Groups +If release setup fails during `terraform apply`, Azure reports the failure through the VM Custom Script Extension. Useful VM-side logs are: + +```text +/var/log/ctf_setup.log +/var/log/waagent.log +/var/log/azure/custom-script/handler.log +``` + If problems persist, please open an issue: https://github.com/learntocloud/linux-ctfs/issues diff --git a/azure/main.tf b/azure/main.tf index 2edc825..ecdf873 100644 --- a/azure/main.tf +++ b/azure/main.tf @@ -73,7 +73,7 @@ locals { rm -f "$${FAILED_MARKER}" fail_setup() { - echo "CTF setup failed. Check /var/log/cloud-init-output.log and /var/log/ctf_setup.log." >&2 + echo "CTF setup failed. Check /var/log/ctf_setup.log and Azure Custom Script Extension logs." >&2 touch "$${FAILED_MARKER}" } trap fail_setup ERR @@ -92,8 +92,28 @@ locals { return 1 } - apt-get update - apt-get install -y ca-certificates curl tar gzip coreutils + wait_for_cloud_init() { + if command -v cloud-init >/dev/null 2>&1; then + cloud-init status --wait || true + fi + } + + apt_get_update_with_retry() { + local attempt + for attempt in 1 2 3 4 5; do + if apt-get -o DPkg::Lock::Timeout=120 -o Acquire::Retries=3 update; then + return 0 + fi + echo "apt-get update failed. Attempt $${attempt}/5." + rm -rf /var/lib/apt/lists/partial/* + sleep 10 + done + return 1 + } + + wait_for_cloud_init + apt_get_update_with_retry + apt-get -o DPkg::Lock::Timeout=120 -o Acquire::Retries=3 install -y ca-certificates curl tar gzip coreutils cd "$${WORK_DIR}" download_with_retry "$${SETUP_URL}" "$${ASSET_NAME}" @@ -111,26 +131,11 @@ locals { trap - ERR EOF - release_readiness_script = <<-EOF - set -eu - echo "Waiting for CTF setup to finish..." - for attempt in $(seq 1 180); do - if test -f /var/lib/linux-ctfs/setup.failed; then - echo "CTF setup failed. Check /var/log/ctf_setup.log and /var/log/cloud-init-output.log." >&2 - exit 1 - fi - - if test -f /var/lib/linux-ctfs/setup.done || test -f /var/lib/cloud/instance/ctf-setup.done || test -f /var/log/setup_complete; then - echo "CTF setup is complete." - exit 0 - fi - - echo "CTF setup is still running. Attempt $attempt/180." - sleep 10 - done - - echo "Timed out waiting for CTF setup. Check /var/log/ctf_setup.log and /var/log/cloud-init-output.log." >&2 - exit 1 + azure_release_extension_script = <<-EOF + #!/bin/sh + exec /bin/bash <<'LINUX_CTFS_SETUP' + ${local.release_setup_script} + LINUX_CTFS_SETUP EOF } @@ -270,7 +275,24 @@ resource "azurerm_linux_virtual_machine" "ctf_vm" { version = "latest" } - custom_data = base64encode(var.use_local_setup ? local.local_bootstrap_script : local.release_setup_script) + custom_data = var.use_local_setup ? base64encode(local.local_bootstrap_script) : null +} + +resource "azurerm_virtual_machine_extension" "release_setup" { + count = var.use_local_setup ? 0 : 1 + name = "linux-ctfs-release-setup" + virtual_machine_id = azurerm_linux_virtual_machine.ctf_vm.id + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.1" + + protected_settings = jsonencode({ + script = base64encode(local.azure_release_extension_script) + }) + + tags = { + setup_release_tag = var.setup_release_tag + } } action "azurerm_virtual_machine_power" "ctf_power_off" { @@ -323,28 +345,8 @@ resource "null_resource" "local_setup" { } } -resource "null_resource" "release_setup_ready" { - count = var.use_local_setup ? 0 : 1 - depends_on = [azurerm_linux_virtual_machine.ctf_vm] - - triggers = { - instance_id = azurerm_linux_virtual_machine.ctf_vm.id - } - - connection { - host = azurerm_linux_virtual_machine.ctf_vm.public_ip_address - user = "ctf_user" - password = "CTFpassword123!" - timeout = "30m" - } - - provisioner "remote-exec" { - inline = [local.release_readiness_script] - } -} - # Output the public IP address output "public_ip_address" { value = azurerm_linux_virtual_machine.ctf_vm.public_ip_address - depends_on = [null_resource.local_setup, null_resource.release_setup_ready] -} \ No newline at end of file + depends_on = [null_resource.local_setup, azurerm_virtual_machine_extension.release_setup] +} From 6d91186d8cd014297d24654343faff1f871de576 Mon Sep 17 00:00:00 2001 From: rishabkumar7 Date: Mon, 1 Jun 2026 16:48:27 -0500 Subject: [PATCH 02/10] Update CONTRIBUTING.md to clarify setup readiness differences by provider --- CONTRIBUTING.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 973a6fe..7601855 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -120,6 +120,12 @@ Most contributors only need to know this: - Contributor testing uses local files. - `deploy_and_test.sh` handles contributor mode for you. +Setup readiness differs by provider: + +- Azure release mode uses VM Custom Script Extension, so Terraform waits for extension success or failure. +- AWS and GCP release mode still use the shared SSH marker wait. +- Contributor mode stays on `use_local_setup=true`, uploading local files over SSH for test runs. + If you manually run Terraform to test local setup changes, pass: ```bash From fc8e50df6b81a180d831bb1803f628700ece1225 Mon Sep 17 00:00:00 2001 From: rishabkumar7 Date: Tue, 2 Jun 2026 14:04:24 -0500 Subject: [PATCH 03/10] Fix post-reboot CTF test flow Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/skills/ctf-testing/deploy_and_test.sh | 49 +++++++++++++------ .../skills/ctf-testing/test_ctf_challenges.sh | 36 ++++++++++---- 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/.github/skills/ctf-testing/deploy_and_test.sh b/.github/skills/ctf-testing/deploy_and_test.sh index 7182faa..edf9336 100755 --- a/.github/skills/ctf-testing/deploy_and_test.sh +++ b/.github/skills/ctf-testing/deploy_and_test.sh @@ -398,7 +398,8 @@ _reboot_vm() { local provider="$1" local ip="$2" - _log INFO "Rebooting VM (${provider})..." + # This function returns the VM IP via stdout, so logs must go to stderr. + _log INFO "Rebooting VM (${provider})..." >&2 case "${provider}" in aws) @@ -416,10 +417,10 @@ _reboot_vm() { return 1 fi - echo " Stopping instance ${instance_id}..." + echo " Stopping instance ${instance_id}..." >&2 aws ec2 stop-instances --instance-ids "${instance_id}" > /dev/null aws ec2 wait instance-stopped --instance-ids "${instance_id}" - echo " Starting instance ${instance_id}..." + echo " Starting instance ${instance_id}..." >&2 aws ec2 start-instances --instance-ids "${instance_id}" > /dev/null aws ec2 wait instance-running --instance-ids "${instance_id}" # IP may change, get new one @@ -427,7 +428,7 @@ _reboot_vm() { ip=$(_get_public_ip "${provider}") ;; azure) - echo " Restarting Azure VM..." + echo " Restarting Azure VM..." >&2 az vm restart --resource-group ctf-resources --name ctf-vm # az vm restart waits by default, but add explicit wait for running state az vm wait \ @@ -437,7 +438,7 @@ _reboot_vm() { --timeout 120 2>/dev/null || true ;; gcp) - echo " Restarting GCP VM..." + echo " Restarting GCP VM..." >&2 local zone zone=$(cd "${REPO_ROOT}/${provider}" \ && terraform output -raw zone 2>/dev/null \ @@ -467,6 +468,19 @@ _reboot_vm() { # TEST EXECUTION # ============================================================================= +# Copy test script to VM and execute it +# Arguments: +# $1 - Cloud provider name +# $2 - IP address of the VM +_copy_test_script() { + local provider="$1" + local ip="$2" + + _log INFO "Copying test script to VM..." + # shellcheck disable=SC2086 + _sshpass_cmd scp ${SSH_OPTS} "${TEST_SCRIPT}" "${SSH_USER}@${ip}:/tmp/test_ctf_challenges.sh" +} + # Copy test script to VM and execute it # Arguments: # $1 - Cloud provider name @@ -482,9 +496,7 @@ _run_tests() { test_flags="${test_flags} --with-reboot" fi - _log INFO "Copying test script to VM..." - # shellcheck disable=SC2086 - _sshpass_cmd scp ${SSH_OPTS} "${TEST_SCRIPT}" "${SSH_USER}@${ip}:/tmp/test_ctf_challenges.sh" + _copy_test_script "${provider}" "${ip}" _log INFO "Running tests on ${provider} VM (${ip})..." echo "" @@ -508,11 +520,14 @@ _run_post_reboot_tests() { local provider="$1" local ip="$2" + _copy_test_script "${provider}" "${ip}" + _log INFO "Running post-reboot verification on ${provider}..." local exit_code=0 # shellcheck disable=SC2086 - _sshpass_cmd ssh ${SSH_OPTS} "${SSH_USER}@${ip}" "/tmp/test_ctf_challenges.sh" \ + _sshpass_cmd ssh ${SSH_OPTS} "${SSH_USER}@${ip}" \ + "chmod +x /tmp/test_ctf_challenges.sh && /tmp/test_ctf_challenges.sh --post-reboot" \ || exit_code=$? return "${exit_code}" @@ -592,13 +607,15 @@ _test_provider() { _log WARN "Reboot requested - performing VM reboot..." local new_ip - new_ip=$(_reboot_vm "${provider}" "${ip}") - - # Wait for SSH after reboot - _wait_for_ssh "${new_ip}" - - # Run post-reboot tests - _run_post_reboot_tests "${provider}" "${new_ip}" || test_exit_code=$? + if ! new_ip=$(_reboot_vm "${provider}" "${ip}"); then + _log ERROR "VM reboot failed for ${provider}" + result=1 + elif ! _wait_for_ssh "${new_ip}"; then + _log ERROR "SSH connection failed after reboot for ${provider}" + result=1 + elif ! _run_post_reboot_tests "${provider}" "${new_ip}"; then + result=1 + fi elif [[ ${test_exit_code} -ne 0 ]]; then result=1 fi diff --git a/.github/skills/ctf-testing/test_ctf_challenges.sh b/.github/skills/ctf-testing/test_ctf_challenges.sh index 25a29dc..5f2fb02 100644 --- a/.github/skills/ctf-testing/test_ctf_challenges.sh +++ b/.github/skills/ctf-testing/test_ctf_challenges.sh @@ -9,11 +9,12 @@ # can complete the CTF. # # Usage: -# ./test_ctf_challenges.sh [--with-reboot] +# ./test_ctf_challenges.sh [--with-reboot|--post-reboot] # DEBUG=true ./test_ctf_challenges.sh # Enable debug tracing # # Flags: # --with-reboot After tests pass, signal reboot to verify services persist +# --post-reboot Run only the post-reboot verification phase # # Exit codes: # 0 - All tests passed @@ -44,9 +45,10 @@ readonly GREEN='\033[0;32m' readonly YELLOW='\033[1;33m' readonly NC='\033[0m' # No Color -# File paths for reboot test coordination -readonly REBOOT_MARKER="/tmp/.ctf_reboot_test_marker" -readonly PROGRESS_SNAPSHOT="/tmp/.ctf_progress_snapshot" +# File paths for reboot test coordination. These must survive a VM reboot. +readonly TEST_STATE_DIR="${HOME}/.linux-ctfs-test" +readonly REBOOT_MARKER="${TEST_STATE_DIR}/.ctf_reboot_test_marker" +readonly PROGRESS_SNAPSHOT="${TEST_STATE_DIR}/.ctf_progress_snapshot" # ============================================================================= # GLOBAL STATE @@ -58,12 +60,17 @@ FAILED=0 # Parse arguments WITH_REBOOT=false +POST_REBOOT=false for arg in "$@"; do case $arg in --with-reboot) WITH_REBOOT=true shift ;; + --post-reboot) + POST_REBOOT=true + shift + ;; esac done @@ -130,11 +137,18 @@ _verify_flag() { # ============================================================================ # POST-REBOOT VERIFICATION # ============================================================================ -if [[ -f "${REBOOT_MARKER}" ]]; then +if [[ "${POST_REBOOT}" == true ]]; then _section "POST-REBOOT VERIFICATION" - + + if [[ ! -f "${REBOOT_MARKER}" ]]; then + _fail "Reboot marker not found - reboot verification was not prepared" + echo "" + echo "Passed: ${PASSED} | Failed: ${FAILED}" + exit 1 + fi + echo "Verifying services survived reboot..." - + for service in ctf-secret-service ctf-monitor-directory ctf-ping-message ctf-secret-process nginx; do if systemctl is-active "${service}" &>/dev/null; then _pass "${service} is running after reboot" @@ -142,7 +156,7 @@ if [[ -f "${REBOOT_MARKER}" ]]; then _fail "${service} failed to start after reboot - SETUP BUG" fi done - + if [ -f "$PROGRESS_SNAPSHOT" ]; then EXPECTED=$(cat "$PROGRESS_SNAPSHOT") ACTUAL=$(sort -u /var/ctf/completed_challenges 2>/dev/null | wc -l) @@ -152,9 +166,10 @@ if [[ -f "${REBOOT_MARKER}" ]]; then _fail "Progress lost after reboot (expected ${EXPECTED}, got ${ACTUAL})" fi fi - + rm -f "${REBOOT_MARKER}" "${PROGRESS_SNAPSHOT}" - + rmdir "${TEST_STATE_DIR}" 2>/dev/null || true + echo "" echo "Passed: ${PASSED} | Failed: ${FAILED}" [[ ${FAILED} -eq 0 ]] && exit 0 || exit 1 @@ -644,6 +659,7 @@ echo "Flags captured: ${#FLAGS[@]}" echo "" if [ "$WITH_REBOOT" = true ] && [ $FAILED -eq 0 ]; then + mkdir -p "${TEST_STATE_DIR}" sort -u /var/ctf/completed_challenges 2>/dev/null | wc -l > "$PROGRESS_SNAPSHOT" touch "$REBOOT_MARKER" echo "Reboot marker created. Re-run after reboot to verify services." From 7d56841063e9d0610d862ae37064481f7419737f Mon Sep 17 00:00:00 2001 From: rishabkumar7 Date: Thu, 4 Jun 2026 09:32:46 -0500 Subject: [PATCH 04/10] Update documentation and scripts for clarity on Terraform requirements and reboot verification --- .github/skills/ctf-testing/deploy_and_test.sh | 10 ++-------- .github/skills/ctf-testing/test_ctf_challenges.sh | 2 +- CONTRIBUTING.md | 4 ++-- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/.github/skills/ctf-testing/deploy_and_test.sh b/.github/skills/ctf-testing/deploy_and_test.sh index edf9336..8bc24bb 100755 --- a/.github/skills/ctf-testing/deploy_and_test.sh +++ b/.github/skills/ctf-testing/deploy_and_test.sh @@ -15,7 +15,7 @@ # reboot and progress persists # # Prerequisites: -# - terraform (>= 1.0) +# - terraform (>= 1.0; Azure requires >= 1.14.0) # - jq (for AWS terraform config) # - sshpass (macOS: brew install hudochenkov/sshpass/sshpass) # - aws CLI (for AWS, must be logged in) @@ -430,12 +430,6 @@ _reboot_vm() { azure) echo " Restarting Azure VM..." >&2 az vm restart --resource-group ctf-resources --name ctf-vm - # az vm restart waits by default, but add explicit wait for running state - az vm wait \ - --resource-group ctf-resources \ - --name ctf-vm \ - --created \ - --timeout 120 2>/dev/null || true ;; gcp) echo " Restarting GCP VM..." >&2 @@ -468,7 +462,7 @@ _reboot_vm() { # TEST EXECUTION # ============================================================================= -# Copy test script to VM and execute it +# Copy test script to VM # Arguments: # $1 - Cloud provider name # $2 - IP address of the VM diff --git a/.github/skills/ctf-testing/test_ctf_challenges.sh b/.github/skills/ctf-testing/test_ctf_challenges.sh index 5f2fb02..434afb4 100644 --- a/.github/skills/ctf-testing/test_ctf_challenges.sh +++ b/.github/skills/ctf-testing/test_ctf_challenges.sh @@ -662,7 +662,7 @@ if [ "$WITH_REBOOT" = true ] && [ $FAILED -eq 0 ]; then mkdir -p "${TEST_STATE_DIR}" sort -u /var/ctf/completed_challenges 2>/dev/null | wc -l > "$PROGRESS_SNAPSHOT" touch "$REBOOT_MARKER" - echo "Reboot marker created. Re-run after reboot to verify services." + echo "Reboot marker created. After reboot, re-run with --post-reboot to verify services." exit 100 fi diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7601855..51dc3c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,7 +71,7 @@ All PRs that change setup, challenges, verify behavior, or Terraform should be t Install: -1. `terraform` 1.0 or newer +1. `terraform` 1.0 or newer; Azure requires Terraform 1.14.0 or newer 2. `jq` 3. `sshpass` 4. The cloud CLI for the provider you want to test @@ -122,7 +122,7 @@ Most contributors only need to know this: Setup readiness differs by provider: -- Azure release mode uses VM Custom Script Extension, so Terraform waits for extension success or failure. +- Azure release mode uses VM Custom Script Extension (Terraform 1.14.0 or newer), so Terraform waits for extension success or failure. - AWS and GCP release mode still use the shared SSH marker wait. - Contributor mode stays on `use_local_setup=true`, uploading local files over SSH for test runs. From e4a4bdd643147cda7a053524ae8b791ff49e5307 Mon Sep 17 00:00:00 2001 From: rishabkumar7 Date: Thu, 4 Jun 2026 09:44:59 -0500 Subject: [PATCH 05/10] Improve logging messages for Azure VM restart and test script copying --- .github/skills/ctf-testing/deploy_and_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/skills/ctf-testing/deploy_and_test.sh b/.github/skills/ctf-testing/deploy_and_test.sh index 8bc24bb..1f2cabb 100755 --- a/.github/skills/ctf-testing/deploy_and_test.sh +++ b/.github/skills/ctf-testing/deploy_and_test.sh @@ -429,7 +429,7 @@ _reboot_vm() { ;; azure) echo " Restarting Azure VM..." >&2 - az vm restart --resource-group ctf-resources --name ctf-vm + az vm restart --resource-group ctf-resources --name ctf-vm >&2 ;; gcp) echo " Restarting GCP VM..." >&2 @@ -470,7 +470,7 @@ _copy_test_script() { local provider="$1" local ip="$2" - _log INFO "Copying test script to VM..." + _log INFO "Copying test script to ${provider} VM..." # shellcheck disable=SC2086 _sshpass_cmd scp ${SSH_OPTS} "${TEST_SCRIPT}" "${SSH_USER}@${ip}:/tmp/test_ctf_challenges.sh" } From e2cb4b09bd5f79c698ee2f7379bc7260292b3ce3 Mon Sep 17 00:00:00 2001 From: rishabkumar7 Date: Thu, 4 Jun 2026 09:52:05 -0500 Subject: [PATCH 06/10] Enhance argument parsing in test_ctf_challenges.sh to handle unknown flags --- .github/skills/ctf-testing/test_ctf_challenges.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/skills/ctf-testing/test_ctf_challenges.sh b/.github/skills/ctf-testing/test_ctf_challenges.sh index 434afb4..1bff329 100644 --- a/.github/skills/ctf-testing/test_ctf_challenges.sh +++ b/.github/skills/ctf-testing/test_ctf_challenges.sh @@ -61,17 +61,21 @@ FAILED=0 # Parse arguments WITH_REBOOT=false POST_REBOOT=false -for arg in "$@"; do - case $arg in +while [[ $# -gt 0 ]]; do + case "$1" in --with-reboot) WITH_REBOOT=true - shift ;; --post-reboot) POST_REBOOT=true - shift + ;; + *) + echo "Unknown argument: $1" + echo "Usage: $0 [--with-reboot|--post-reboot]" + exit 1 ;; esac + shift done # ============================================================================= From f68b1696787a4228f8a6114feea1f5b10edfdef7 Mon Sep 17 00:00:00 2001 From: rishabkumar7 Date: Thu, 4 Jun 2026 16:09:37 -0500 Subject: [PATCH 07/10] Refactor argument parsing in test_ctf_challenges.sh to improve usage clarity and prevent conflicting flags --- .github/skills/ctf-testing/test_ctf_challenges.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/skills/ctf-testing/test_ctf_challenges.sh b/.github/skills/ctf-testing/test_ctf_challenges.sh index 1bff329..688ece8 100644 --- a/.github/skills/ctf-testing/test_ctf_challenges.sh +++ b/.github/skills/ctf-testing/test_ctf_challenges.sh @@ -61,6 +61,10 @@ FAILED=0 # Parse arguments WITH_REBOOT=false POST_REBOOT=false +usage() { + echo "Usage: $0 [--with-reboot|--post-reboot]" +} + while [[ $# -gt 0 ]]; do case "$1" in --with-reboot) @@ -71,13 +75,19 @@ while [[ $# -gt 0 ]]; do ;; *) echo "Unknown argument: $1" - echo "Usage: $0 [--with-reboot|--post-reboot]" + usage exit 1 ;; esac shift done +if [[ "${WITH_REBOOT}" == true && "${POST_REBOOT}" == true ]]; then + echo "--with-reboot and --post-reboot cannot be used together." + usage + exit 1 +fi + # ============================================================================= # HELPER FUNCTIONS # ============================================================================= From 1f66560f2db80af012547e2d918460a4bdfb5b84 Mon Sep 17 00:00:00 2001 From: rishabkumar7 Date: Fri, 5 Jun 2026 08:56:24 -0500 Subject: [PATCH 08/10] Fix Azure VM restart command to return error on failure and adjust script formatting in main.tf --- .github/skills/ctf-testing/deploy_and_test.sh | 2 +- azure/main.tf | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/skills/ctf-testing/deploy_and_test.sh b/.github/skills/ctf-testing/deploy_and_test.sh index 1f2cabb..1490794 100755 --- a/.github/skills/ctf-testing/deploy_and_test.sh +++ b/.github/skills/ctf-testing/deploy_and_test.sh @@ -429,7 +429,7 @@ _reboot_vm() { ;; azure) echo " Restarting Azure VM..." >&2 - az vm restart --resource-group ctf-resources --name ctf-vm >&2 + az vm restart --resource-group ctf-resources --name ctf-vm >&2 || return 1 ;; gcp) echo " Restarting GCP VM..." >&2 diff --git a/azure/main.tf b/azure/main.tf index ecdf873..8733f2c 100644 --- a/azure/main.tf +++ b/azure/main.tf @@ -132,10 +132,10 @@ locals { EOF azure_release_extension_script = <<-EOF - #!/bin/sh - exec /bin/bash <<'LINUX_CTFS_SETUP' - ${local.release_setup_script} - LINUX_CTFS_SETUP +#!/bin/sh +exec /bin/bash <<'LINUX_CTFS_SETUP' +${local.release_setup_script} +LINUX_CTFS_SETUP EOF } From e596fb3b1050db06198fd1244abc30fb79b26cc2 Mon Sep 17 00:00:00 2001 From: rishabkumar7 Date: Fri, 5 Jun 2026 16:37:55 -0500 Subject: [PATCH 09/10] Redirect gcloud command error output to stderr and return error on failure in _reboot_vm function --- .github/skills/ctf-testing/deploy_and_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/skills/ctf-testing/deploy_and_test.sh b/.github/skills/ctf-testing/deploy_and_test.sh index 1490794..f5f64ca 100755 --- a/.github/skills/ctf-testing/deploy_and_test.sh +++ b/.github/skills/ctf-testing/deploy_and_test.sh @@ -437,7 +437,7 @@ _reboot_vm() { zone=$(cd "${REPO_ROOT}/${provider}" \ && terraform output -raw zone 2>/dev/null \ || echo "us-central1-a") - gcloud compute instances reset ctf-instance --zone="${zone}" --quiet + gcloud compute instances reset ctf-instance --zone="${zone}" --quiet >&2 || return 1 # Wait for VM to be running local attempts=0 while [[ ${attempts} -lt 30 ]]; do From ea632ca9bc7346d6b0c01266952a7f4eaa5a8200 Mon Sep 17 00:00:00 2001 From: Rishab Kumar <45825464+rishabkumar7@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:45:43 -0500 Subject: [PATCH 10/10] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .github/skills/ctf-testing/test_ctf_challenges.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/skills/ctf-testing/test_ctf_challenges.sh b/.github/skills/ctf-testing/test_ctf_challenges.sh index 688ece8..dbd465d 100644 --- a/.github/skills/ctf-testing/test_ctf_challenges.sh +++ b/.github/skills/ctf-testing/test_ctf_challenges.sh @@ -173,7 +173,7 @@ if [[ "${POST_REBOOT}" == true ]]; then if [ -f "$PROGRESS_SNAPSHOT" ]; then EXPECTED=$(cat "$PROGRESS_SNAPSHOT") - ACTUAL=$(sort -u /var/ctf/completed_challenges 2>/dev/null | wc -l) + ACTUAL=$( { sort -u /var/ctf/completed_challenges 2>/dev/null || true; } | wc -l ) if [ "$ACTUAL" -ge "$EXPECTED" ]; then _pass "Progress persisted after reboot ($ACTUAL checks)" else