]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add a template for SSH-confirmed jobs
authorMichał Kępień <michal@isc.org>
Wed, 22 Oct 2025 07:45:29 +0000 (09:45 +0200)
committerAndoni Duarte Pintado <andoni@isc.org>
Mon, 27 Oct 2025 15:16:48 +0000 (16:16 +0100)
Add a YAML template for jobs that require an SSH connection to a
dedicated, locked-down runner for signing off on sensitive operations
(e.g. signing, publishing).

These jobs all follow a similar scheme:

 1. Runner prepares the necessary files in a well-known location (/tmp).
 2. Runner generates a shell script to be run by an authorized user.
 3. Runner sleeps while waiting for a signal that the script was run.
 4. Authorized user logs in to the runner over SSH and runs the script.
 5. Runner collects the relevant files and logs as job artifacts.

One additional complication is that each of the above steps needs to be
carried out under the assumption that GitLab Runner is running under a
different user account than the one used for logging in over SSH,
necessitating careful file permission handling.

Having a YAML template for jobs that need to follow the above scheme
significantly improves readability and reuse as each job only needs to
define (via the "variables" YAML key):

  - SSH_SCRIPT_RUNNER_PRE: the code the runner should execute before an
    authorized user logs in over SSH (typically: setting up files in a
    well-known location),

  - SSH_SCRIPT_CLIENT: contents of the shell script to be run by an
    authorized user,

  - SSH_SCRIPT_RUNNER_POST: the code the runner should execute after an
    authorized user runs the script over SSH (typically: artifact
    collection and cleanup).

.gitlab-ci.yml

index 8ee438ad33f08d80f3f6a483311a31793bd3a5ff..710b86cac5f8dab69ab02ac79a80b56b9bdce79f 100644 (file)
@@ -1639,6 +1639,31 @@ release:
       - bind-${CI_COMMIT_TAG}-release
     expire_in: "1 month"
 
+.signer-ssh-job: &signer_ssh_job
+  stage: release
+  when: manual
+  allow_failure: false
+  tags:
+    - signer
+  script:
+    - ( rm -f "/tmp/${CI_JOB_NAME}.log" "/tmp/${CI_JOB_NAME}-done" && umask 111 && touch "/tmp/${CI_JOB_NAME}.log" "/tmp/${CI_JOB_NAME}-done" )
+    - |
+      cat > "/tmp/${CI_JOB_NAME}.sh" <<EOF
+      #!/bin/sh
+      set -e -x
+      {
+        ${SSH_SCRIPT_CLIENT}
+        echo "${CI_COMMIT_TAG}" > "/tmp/${CI_JOB_NAME}-done"
+      } 2>&1 | tee "/tmp/${CI_JOB_NAME}.log"
+      EOF
+    - chmod +x "/tmp/${CI_JOB_NAME}.sh"
+    - /bin/sh -c "set -e -x; ${SSH_SCRIPT_RUNNER_PRE}"
+    - echo -e "\e[31m*** Sleeping until /tmp/${CI_JOB_NAME}.sh is executed over SSH... ⌛\e[0m"
+    - while [ "$(cat "/tmp/${CI_JOB_NAME}-done")" != "${CI_COMMIT_TAG}" ]; do sleep 10; done
+    - /bin/sh -c "set -e -x; ${SSH_SCRIPT_RUNNER_POST}"
+    - cp "/tmp/${CI_JOB_NAME}.log" "${CI_PROJECT_DIR}/${CI_JOB_NAME}-${CI_COMMIT_TAG}.log"
+    - rm -f "/tmp/${CI_JOB_NAME}.log" "/tmp/${CI_JOB_NAME}-done" "/tmp/${CI_JOB_NAME}.sh"
+
 # Job signing the source tarballs in the release directory
 
 sign: