diff --git a/opentofu/vr1-dc1-substrate/.terraform.lock.hcl b/opentofu/vr1-dc1-substrate/.terraform.lock.hcl new file mode 100644 index 0000000..f6d738b --- /dev/null +++ b/opentofu/vr1-dc1-substrate/.terraform.lock.hcl @@ -0,0 +1,35 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "registry.opentofu.org/dmacvicar/libvirt" { + version = "0.9.8" + constraints = "0.9.8" + hashes = [ + "h1:/9TSq9ibeojseTyT6Jx3z/dbvT5uw8ka3/18NKonrQc=", + "h1:BN5hy1RaHlpcV0BDJYrSOEklK4YNdZCpiXOOGn0ce9k=", + "h1:MNJ6dcFru4DwQM7maIUAADJIHn3aF+L8XsnRJlleNaM=", + "h1:P1Cx0VZGTe6cpWpQ4JFOPJJb+Z+N50t4e1VA76T1tAA=", + "h1:Pm9du7Rzsg1bhLq+XnW9VaLSjTu0Yytr9AOdP9FLQvM=", + "h1:Q/JvNhRskJqDKPJoO9DW3+Ons3mk8kc++zlT4TucyFw=", + "h1:Tzk+wRzhboY3F3wB1u0y3ySMMd4ZPtJbOYlTbbkxZc0=", + "h1:Uuk8gkDEzmXfOTW/nm8GMG2aen7n/+X5GsTAf7eVRJc=", + "h1:cRBlnB/TG4+l0y0i42QLU0JoLDBxxJEwCguLXS9Rv8A=", + "h1:jn+hA9lIJzH5T0550IaKNsHxEAbyTGtvYWm02JCxexM=", + "h1:pKAwAcCGEwsKvVy5eIxdmb1gLhTTxB0xGVi8/jqj0uI=", + "h1:wS5VlGinhpnMCva0tKwLRPRQxmMUl80L05AueWshzNg=", + "h1:yqZeKoJ+EZc3687/+ZBqBmtwzvBPLNwaEHW74+bSc6Y=", + "zh:061e5187853729e1d8ba20938402ad6e778b4097436925d0bef7741c8aa26ee1", + "zh:69a2ac8ee0cb0c1581bdc9a1296d89abcd1808229ff0a2fa20678ba4f7472944", + "zh:8b02bf349191b4e7d9529d620da9e9265de5bd01d6983bb079589acdf80dda7a", + "zh:9620872ed1da1ff421e85dd4ba2a110c284f3f0d06369c36a9aa75d501155fad", + "zh:9ae7c932b7fb6f62ff20b863a15a7cd713415faa4c789472dc403062808366cb", + "zh:a369c3e271b49e085940e6181fe6c1086c2126eebf5c7ad2b1db8fc8792dd30c", + "zh:a45ad97d7192bea104b32521839dd705a330f13364cf1007dc912b6a0b6be3c8", + "zh:b69f2a13ff688ad4b79e14deb6ef6341187864f50960bc0fd9c682f6077b4318", + "zh:c20b467ff0ac76431a7bdb99662b9414b922ea603327509518c0179416cdfea3", + "zh:c22d45913bd1f00a33d1a4b80547e4a2854409a298a0868c1730124f03a210ad", + "zh:cf82bb14884fcbdcd57620cee248994b1633ea246fa49fd668d2f1739abb982d", + "zh:ddc1cb4417206dd46eb22c3b81204b3a5edda03c4436e6a5914d541fcfd4c27f", + "zh:e6b1983b8f1b9658448d0d09635619cc75dde314e6b4d7fd16d827f9e4bdb767", + ] +} diff --git a/scripts/opentofu-validate.sh b/scripts/opentofu-validate.sh index 67dabe5..8d6bd1c 100644 --- a/scripts/opentofu-validate.sh +++ b/scripts/opentofu-validate.sh @@ -126,10 +126,34 @@ fail=$(( s1_rc | s2_rc )) -echo "== tofu fmt -check -recursive ==" -if ! tofu fmt -check -recursive -diff "$TOFU_DIR"; then - echo " [FAIL] formatting drift -- run: tofu fmt -recursive $TOFU_DIR" +echo "== tofu fmt -check -recursive (REPO-TRACKED FILES ONLY) ==" +# SCOPED TO REPO CONTENT (fixed 2026-07-30). `tofu fmt -recursive` walks EVERY .tf/.tfvars under +# the tree, including GITIGNORED local files -- per-DC `*.auto.tfvars`, which exist only on the +# host that actually runs the applies. Measured: this gate read ALL GREEN on the jumphost and +# FAILED on the Office1 headend, and the sole flagged file was +# `opentofu/vr1-dc0-substrate/d124-inner.auto.tfvars`, which is gitignored operator input, not +# repo content. So the gate was RED ON THE ONLY HOST THAT DEPLOYS and green where it did not +# matter -- the same host-dependent-verdict class as the LC_ALL manifest sort. +# The repo's formatting standard applies to what the repo carries. A local tfvars is the +# operator's file and is none of this gate's business. +FMT_DRIFT="" +while IFS= read -r _f; do + [ -n "$_f" ] || continue + # A gitignored path is not repo content -- skip it, and say so rather than silently. + if git -C "$HERE/.." check-ignore -q "$_f" 2>/dev/null; then + echo " [skip] $_f is gitignored (local input, not repo content)" + continue + fi + FMT_DRIFT="$FMT_DRIFT $_f" +done </dev/null || true) +EOF +if [ -n "${FMT_DRIFT# }" ]; then + echo " [FAIL] formatting drift in repo-tracked file(s):${FMT_DRIFT}" + echo " run: tofu fmt${FMT_DRIFT}" fail=1 +else + echo " [ok] no formatting drift in repo-tracked files" fi echo "== tofu init -backend=false (downloads providers; needs registry network access) ==" diff --git a/tests/opentofu-validate/run-tests.sh b/tests/opentofu-validate/run-tests.sh index fdd657c..8cacbe5 100644 --- a/tests/opentofu-validate/run-tests.sh +++ b/tests/opentofu-validate/run-tests.sh @@ -101,5 +101,41 @@ pin "T14 D-127 DC edge autostart=true" opentofu/vr1-dc0-substrate/main.tf 'autostart[[:space:]]+= true # D-127: the DC edge' pin "T15 D-127 node VMs autostart=FALSE" opentofu/vr1-dc0-substrate/main.tf 'autostart[[:space:]]+= false # D-127: node VMs' +# T16/T17 -- the fmt check must be scoped to REPO CONTENT. Measured 2026-07-30: this gate read +# ALL GREEN on the jumphost and FAILED on the Office1 headend, and the only flagged file was a +# GITIGNORED per-DC `*.auto.tfvars` that exists solely on the host which runs the applies. So the +# gate was RED ON THE ONLY HOST THAT DEPLOYS -- the same host-dependent-verdict class as the +# LC_ALL manifest sort. Both directions are pinned, because scoping a check is exactly the kind +# of change that can quietly turn it into a no-op. +_probe_tracked="$HERE/../../opentofu/modules/base-image/_fmtprobe.tf" +_probe_ignored="$HERE/../../opentofu/vr1-dc0-substrate/_fmtprobe.auto.tfvars" +printf 'variable "x" {\n type=string\n}\n' > "$_probe_tracked" +# CAPTURE FIRST, then grep. `bash "$SCRIPT" | grep -q ...` is wrong here: the gate correctly +# exits 1 on the planted defect, and `set -o pipefail` makes the PIPELINE inherit that 1 even +# though grep matched -- so a passing assertion reads as a failure. Same strict-bash family as +# the IFS and inherit_errexit traps this repo has hit repeatedly. +_out16="$(bash "$SCRIPT" 2>&1 || true)" +if printf '%s' "$_out16" | grep -q "\[FAIL\] formatting drift in repo-tracked"; then + PASS=$((PASS+1)); echo " PASS T16 a badly-formatted REPO-TRACKED file still FAILS the fmt gate" +else + FAIL=$((FAIL+1)); echo " FAIL T16 scoping the fmt check must not turn it into a no-op" +fi +rm -f "$_probe_tracked" +# A gitignored local tfvars must be SKIPPED, not failed -- and must say so rather than go silent. +printf 'foo = "bar"\n' > "$_probe_ignored" +if git -C "$HERE/../.." check-ignore -q "$_probe_ignored" 2>/dev/null; then + _out="$(bash "$SCRIPT" 2>&1 || true)" + if printf '%s' "$_out" | grep -q "is gitignored (local input, not repo content)" \ + && ! printf '%s' "$_out" | grep -q "\[FAIL\] formatting drift"; then + PASS=$((PASS+1)); echo " PASS T17 a gitignored local tfvars is SKIPPED with the reason, not failed" + else + FAIL=$((FAIL+1)); echo " FAIL T17 a gitignored local tfvars must not fail the gate" + fi +else + # If the ignore rule ever stops covering per-DC tfvars, this case cannot test what it claims. + FAIL=$((FAIL+1)); echo " FAIL T17 fixture is not gitignored -- the ignore rule for per-DC tfvars changed" +fi +rm -f "$_probe_ignored" + echo; echo "RESULT: PASS=$PASS FAIL=$FAIL" [[ "$FAIL" -eq 0 ]] && { echo "ALL PASS"; exit 0; } || exit 1