7070 echo "🚀 Testing on: ${{ matrix.container }}"
7171 chmod +x init.sh
7272
73- docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ${{ matrix.container }} /bin/sh -c '
73+ docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt " ${{ matrix.container }}" /bin/sh -s <<'CONTAINER '
7474 set -e
7575
7676 # -----------------------------------------------------------------
@@ -139,6 +139,10 @@ jobs:
139139 grep -q "BEGIN SERVER-INIT MANAGED BLOCK" /etc/ssh/sshd_config \
140140 || { echo "❌ managed block missing"; exit 1; }
141141
142+ first_line=$(sed -n '1p' /etc/ssh/sshd_config)
143+ test "$first_line" = "# BEGIN SERVER-INIT MANAGED BLOCK" \
144+ || { echo "❌ managed block is not the first line: $first_line"; exit 1; }
145+
142146 grep -Eq "^[[:space:]]*Port[[:space:]]+2222([[:space:]]|$)" /etc/ssh/sshd_config \
143147 || { echo "❌ Port 2222 not in config"; exit 1; }
144148
@@ -208,8 +212,13 @@ jobs:
208212 test "$sudoers_count" = "1" \
209213 || { echo "❌ sudoers files multiplied on re-run (count=$sudoers_count)"; exit 1; }
210214
215+ for lock in /run/server-init/script.lock /var/lib/server-init/script.lock; do
216+ test ! -d "$lock" \
217+ || { echo "❌ script lock left behind after successful run: $lock"; exit 1; }
218+ done
219+
211220 echo "✅ ALL ASSERTIONS PASSED"
212- '
221+ CONTAINER
213222
214223 # -------------------------------------------------------------------
215224 # 3. Live restart + listen + connection test on one representative distro
@@ -226,7 +235,7 @@ jobs:
226235 - name : Live test
227236 run : |
228237 chmod +x init.sh
229- docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -c '
238+ docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -s <<'CONTAINER '
230239 set -e
231240 apt-get update -qq
232241 apt-get install -y -qq curl sudo openssh-server iproute2 netcat-openbsd procps
@@ -263,8 +272,13 @@ jobs:
263272 echo "Banner: $banner"
264273 echo "$banner" | grep -q "SSH-2.0" || { echo "❌ no SSH banner on 2222"; exit 1; }
265274
275+ for lock in /run/server-init/script.lock /var/lib/server-init/script.lock; do
276+ test ! -d "$lock" \
277+ || { echo "❌ script lock left behind after live restart: $lock"; exit 1; }
278+ done
279+
266280 echo "✅ Live restart + listen + banner OK"
267- '
281+ CONTAINER
268282
269283 # -------------------------------------------------------------------
270284 # 4. Pre-existing-user safety test — ensure passwd -d does NOT clobber an
@@ -279,7 +293,7 @@ jobs:
279293 - name : Verify pre-existing user is left alone
280294 run : |
281295 chmod +x init.sh
282- docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -c '
296+ docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -s <<'CONTAINER '
283297 set -e
284298 apt-get update -qq
285299 apt-get install -y -qq curl sudo openssh-server iproute2
@@ -331,7 +345,7 @@ jobs:
331345 exit 1
332346 fi
333347 echo "✅ Pre-existing user password preserved and sudoers untouched"
334- '
348+ CONTAINER
335349
336350 # -------------------------------------------------------------------
337351 # 5. Cross-user sudoers cleanup safety — verify the legacy-glob cleanup
@@ -348,7 +362,7 @@ jobs:
348362 - name : Verify glob does not match sibling usernames
349363 run : |
350364 chmod +x init.sh
351- docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -c '
365+ docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -s <<'CONTAINER '
352366 set -e
353367 apt-get update -qq
354368 apt-get install -y -qq curl sudo openssh-server iproute2
@@ -397,7 +411,7 @@ jobs:
397411 || { echo "❌ admin stable sudoers missing"; ls /etc/sudoers.d/; exit 1; }
398412
399413 echo "✅ Cross-user sudoers glob safety + operator-file safety verified"
400- '
414+ CONTAINER
401415
402416 # -------------------------------------------------------------------
403417 # 6. Legacy v4.6.x timestamped sudoers SHOULD be cleaned on re-run.
@@ -411,7 +425,7 @@ jobs:
411425 - name : Verify legacy-pattern file is removed
412426 run : |
413427 chmod +x init.sh
414- docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -c '
428+ docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -s <<'CONTAINER '
415429 set -e
416430 apt-get update -qq
417431 apt-get install -y -qq curl sudo openssh-server iproute2
@@ -444,7 +458,7 @@ jobs:
444458 || { echo "❌ audit log missing specific path"; exit 1; }
445459
446460 echo "✅ Legacy sudoers cleanup verified"
447- '
461+ CONTAINER
448462
449463 # -------------------------------------------------------------------
450464 # 7. CLI flag smoke — --version / --help / --no-ip-probe
@@ -458,7 +472,7 @@ jobs:
458472 - name : Smoke-test CLI flags
459473 run : |
460474 chmod +x init.sh
461- docker run --rm -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -c '
475+ docker run --rm -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -s <<'CONTAINER '
462476 set -e
463477 # We need root for the script to run past the preflight check.
464478 # --version / --help exit BEFORE the root check, so they work
@@ -482,8 +496,44 @@ jobs:
482496 ./init.sh -h | grep -q -- "--help" \
483497 || { echo "❌ -h failed"; exit 1; }
484498
499+ check_no_lock() {
500+ label="$1"
501+ for lock in /run/server-init/script.lock /var/lib/server-init/script.lock; do
502+ test ! -d "$lock" \
503+ || { echo "❌ script lock leaked after $label: $lock"; exit 1; }
504+ done
505+ }
506+
507+ check_no_lock "--version/--help"
508+
509+ if ./init.sh --user=a --user=b --yes >/tmp/dup-user.out 2>&1; then
510+ echo "❌ duplicate --user unexpectedly succeeded"
511+ cat /tmp/dup-user.out
512+ exit 1
513+ fi
514+ check_no_lock "duplicate --user"
515+
516+ if ./init.sh --port= --yes >/tmp/empty-port.out 2>&1; then
517+ echo "❌ empty --port unexpectedly succeeded"
518+ cat /tmp/empty-port.out
519+ exit 1
520+ fi
521+ check_no_lock "empty --port"
522+
523+ if ./init.sh \
524+ --user=deploy \
525+ --port=03306 \
526+ --key-raw="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPQQDejyTCPJO3Jyw5UX9jmojb/zjgcqVuRO28fmpWU5 ci@test" \
527+ --no-update --no-bbr --delay-restart --no-ip-probe --yes --strict \
528+ >/tmp/leading-zero-port.out 2>&1; then
529+ echo "❌ leading-zero --port unexpectedly succeeded"
530+ cat /tmp/leading-zero-port.out
531+ exit 1
532+ fi
533+ check_no_lock "leading-zero --port"
534+
485535 echo "✅ CLI flag smoke OK"
486- '
536+ CONTAINER
487537
488538 # -------------------------------------------------------------------
489539 # 8. --no-ip-probe actually skips the ipify lookup
@@ -497,7 +547,7 @@ jobs:
497547 - name : Verify --no-ip-probe skips ipify call
498548 run : |
499549 chmod +x init.sh
500- docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -c '
550+ docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -s <<'CONTAINER '
501551 set -e
502552 apt-get update -qq
503553 apt-get install -y -qq curl sudo openssh-server iproute2
@@ -519,7 +569,7 @@ jobs:
519569 fi
520570
521571 echo "✅ --no-ip-probe verified"
522- '
572+ CONTAINER
523573
524574 # -------------------------------------------------------------------
525575 # 9. ACCOUNT_LOCKED warning fires when key deployment fails (non-strict)
@@ -533,7 +583,7 @@ jobs:
533583 - name : Verify ACCOUNT_LOCKED_REASON path
534584 run : |
535585 chmod +x init.sh
536- docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -c '
586+ docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -s <<'CONTAINER '
537587 set -e
538588 apt-get update -qq
539589 apt-get install -y -qq curl sudo openssh-server iproute2
@@ -558,8 +608,13 @@ jobs:
558608 passwd -S deploy_locked | awk "{print \$2}" | grep -qE "^L\$|^LK\$" \
559609 || { echo "❌ deploy_locked is not locked"; passwd -S deploy_locked; exit 1; }
560610
611+ for lock in /run/server-init/script.lock /var/lib/server-init/script.lock; do
612+ test ! -d "$lock" \
613+ || { echo "❌ script lock left behind after non-strict key failure: $lock"; exit 1; }
614+ done
615+
561616 echo "✅ ACCOUNT_LOCKED path verified"
562- '
617+ CONTAINER
563618
564619 # -------------------------------------------------------------------
565620 # 10. restore.sh refuses when checksums.sha256 is missing; FORCE=1 overrides
@@ -573,7 +628,7 @@ jobs:
573628 - name : Verify checksum gate + FORCE=1
574629 run : |
575630 chmod +x init.sh
576- docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -c '
631+ docker run --rm --privileged -v "$(pwd)":/mnt:ro -w /mnt ubuntu:22.04 /bin/sh -s <<'CONTAINER '
577632 set -e
578633 apt-get update -qq
579634 apt-get install -y -qq curl sudo openssh-server iproute2
@@ -605,4 +660,4 @@ jobs:
605660 exit 1
606661 fi
607662 echo "✅ FORCE=1 successfully bypassed"
608- '
663+ CONTAINER
0 commit comments