@@ -8,12 +8,17 @@ INSTALLER=install-dev.sh
88fail () { printf ' INSTALL-DEV SAFETY FAIL: %s\n' " $* " >&2 ; exit 1; }
99line_of () {
1010 local value
11- value=" $( grep -nF -- " $2 " " $1 " | head -1 | cut -d: -f1) "
11+ value=" $( grep -nF -- " $2 " " $1 " | head -1 | cut -d: -f1 || true ) "
1212 [ -n " $value " ] || fail " missing contract: $2 "
1313 printf ' %s\n' " $value "
1414}
1515
1616bash -n " $INSTALLER " || fail " installer has invalid shell syntax"
17+ missing_line_output=" $( (line_of " $INSTALLER " ' __install_dev_missing_contract_probe__' ) 2>&1 || true) "
18+ case " $missing_line_output " in
19+ * ' missing contract: __install_dev_missing_contract_probe__' * ) ;;
20+ * ) fail " line_of suppresses its focused missing-contract diagnostic" ;;
21+ esac
1722
1823# The local bundle is authenticated before the first remote mutation, and the
1924# lock-protected live deployment completes before flash state is created.
3742done
3843grep -qF ' case "${HOST#root@}"' " $INSTALLER " || fail " host shell syntax is not rejected"
3944if grep -qF ' set -x' " $INSTALLER " ; then fail " installer enables shell tracing" ; fi
45+ if grep -qF ' PACKAGE="$BUNDLE_DIR/$PACKAGE_FILE"' " $INSTALLER " ; then
46+ fail " installer retains the unused PACKAGE assignment"
47+ fi
4048
4149# Baseline creation is one-time and copies exactly the public canonical
4250# descriptor plus the one package it references. It must not sweep or copy the
@@ -53,6 +61,22 @@ for contract in \
5361do
5462 grep -qF -- " $contract " " $INSTALLER " || fail " missing rollback-baseline contract: $contract "
5563done
64+ cleanup_function_line=" $( line_of " $INSTALLER " ' cleanup_install_temps() {' ) "
65+ cleanup_trap_line=" $( line_of " $INSTALLER " ' trap cleanup_install_temps EXIT' ) "
66+ rollback_tmp_line=" $( line_of " $INSTALLER " ' rollback_tmp="$(mktemp -d "$dev_root/.rollback.XXXXXX")"' ) "
67+ commit_tmp_line=" $( line_of " $INSTALLER " ' commit_tmp="$(mktemp "$artifacts/.commit.XXXXXX")"' ) "
68+ [ " $cleanup_function_line " -lt " $cleanup_trap_line " ] \
69+ && [ " $cleanup_trap_line " -lt " $rollback_tmp_line " ] \
70+ && [ " $cleanup_trap_line " -lt " $commit_tmp_line " ] \
71+ || fail " temporary-path cleanup is not armed before temporary paths are created"
72+ for contract in \
73+ ' "$dev_root"/.rollback.*) rm -rf -- "$rollback_tmp" || status=1' \
74+ ' "$artifacts"/.commit.*) rm -f -- "$commit_tmp" || status=1' \
75+ ' rollback_tmp=' \
76+ ' commit_tmp='
77+ do
78+ grep -qF -- " $contract " " $INSTALLER " || fail " missing temporary cleanup contract: $contract "
79+ done
5680if grep -Eq ' cp[[:space:]]+-R.*(canonical_cfg|/boot/config/plugins/ci-runner-farm)' " $INSTALLER " ; then
5781 fail " installer recursively copies the persistent config/credential directory"
5882fi
@@ -98,6 +122,22 @@ for resource in \
98122do
99123 grep -qF -- " $resource " " $INSTALLER " || fail " rollback omits empty check: $resource "
100124done
125+ for contract in \
126+ ' legacy_name="$(docker inspect -f ' \' ' {{.Name}}' \' ' ci-runner-mirror 2>/dev/null)"' \
127+ ' legacy_image="$(docker inspect -f ' \' ' {{.Config.Image}}' \' ' ci-runner-mirror 2>/dev/null)"' \
128+ ' legacy_source="$(docker inspect -f ' \' ' {{range .Mounts}}{{if eq .Destination "/var/lib/registry"}}{{.Source}}{{end}}{{end}}' \' ' ci-runner-mirror 2>/dev/null)"' \
129+ ' REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io' \
130+ ' [ "$legacy_name" = /ci-runner-mirror ]' \
131+ ' [ "$legacy_image" = registry:2 ]' \
132+ ' [ "$legacy_source" = "$legacy_cache_root/registry-mirror" ]'
133+ do
134+ grep -qF -- " $contract " " $INSTALLER " || fail " rollback omits legacy mirror provenance: $contract "
135+ done
136+ legacy_name_line=" $( line_of " $INSTALLER " ' legacy_name="$(docker inspect' ) "
137+ legacy_tuple_line=" $( line_of " $INSTALLER " ' if [ "$legacy_name" = /ci-runner-mirror ]' ) "
138+ legacy_fail_line=" $( line_of " $INSTALLER " ' fail "fixed-name registry mirror remains after Stop"' ) "
139+ [ " $legacy_name_line " -lt " $legacy_tuple_line " ] && [ " $legacy_tuple_line " -lt " $legacy_fail_line " ] \
140+ || fail " an unrelated fixed-name mirror can still trigger rollback failure before provenance matches"
101141rollback_block=" $( awk '
102142 /^ssh -- "\$HOST" \/bin\/bash -s <<' " '" ' REMOTE_ROLLBACK' " '" ' $/ { emit=1 }
103143 emit { print }
120160# deploy/SSH commands. The remote heredocs are deliberately not executed.
121161tmp=" $( mktemp -d) "
122162trap ' rm -rf "$tmp"' EXIT
163+
164+ # Execute the install transaction's actual EXIT-trap function against both
165+ # temporary path classes. An implicit set -e failure must retain its non-zero
166+ # status while removing the baseline directory and the artifact staging file.
167+ cleanup_function=" $( awk '
168+ /^cleanup_install_temps\(\) \{$/ { emit=1 }
169+ emit { print }
170+ emit && /^}$/ { exit }
171+ ' " $INSTALLER " ) "
172+ [ -n " $cleanup_function " ] || fail " could not extract temporary cleanup function"
173+ cleanup_root=" $tmp /cleanup-probe"
174+ cleanup_artifacts=" $cleanup_root /artifacts"
175+ cleanup_rollback=" $cleanup_root /.rollback.ABC123"
176+ cleanup_commit=" $cleanup_artifacts /.commit.ABC123"
177+ mkdir -p " $cleanup_rollback " " $cleanup_artifacts "
178+ printf ' partial artifact\n' > " $cleanup_commit "
179+ cleanup_probe=" $tmp /cleanup-probe.sh"
180+ {
181+ printf ' %s\n' ' #!/usr/bin/env bash' ' set -euo pipefail'
182+ printf ' %s\n' ' dev_root="$1"' ' artifacts="$2"' ' rollback_tmp="$3"' ' commit_tmp="$4"'
183+ printf ' %s\n' " $cleanup_function "
184+ printf ' %s\n' ' trap cleanup_install_temps EXIT' ' false'
185+ } > " $cleanup_probe "
186+ if bash " $cleanup_probe " " $cleanup_root " " $cleanup_artifacts " " $cleanup_rollback " " $cleanup_commit " ; then
187+ fail " temporary cleanup probe lost the triggering failure status"
188+ fi
189+ [ ! -e " $cleanup_rollback " ] || fail " rollback temporary directory survived a transaction failure"
190+ [ ! -e " $cleanup_commit " ] || fail " artifact temporary file survived a transaction failure"
191+
123192repo=" $tmp /repo"
124193mkdir -p " $repo /tmp/dev-package" " $tmp /bin"
125194cp " $INSTALLER " " $repo /install-dev.sh"
0 commit comments