Skip to content

Commit 75d25aa

Browse files
committed
add lab and installer asset validation checks
1 parent 6c432a9 commit 75d25aa

11 files changed

Lines changed: 253 additions & 1 deletion

‎README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ Useful commands after the repository is populated with local inputs. The install
136136
./scripts/verify/verify-rendered-config-integrity.ksh
137137
./scripts/verify/verify-host-service-integrity.ksh
138138
./scripts/verify/verify-documentation-integrity.ksh
139+
./scripts/verify/verify-lab-assets.ksh
140+
./scripts/verify/verify-autonomous-installer-assets.ksh
139141
./maint/validate-public-hardening-surface.ksh
140142
./scripts/verify/run-repo-ci-gates.ksh
141143
```

‎docs/install/06-qemu-lab-and-vm-testing.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,14 @@ Do not place live provider secrets into the tracked repository while using the l
136136
## Next step
137137

138138
After the lab VM is working, continue with the phase-driven workflow as you would on a real host, but keep all provider secrets in protected local files only. When the VM path is stable, move to `docs/install/11-first-production-deployment-sequence.md`.
139+
140+
141+
## Asset validation
142+
143+
The repository now includes a dedicated QEMU lab asset verifier:
144+
145+
```sh
146+
./scripts/verify/verify-lab-assets.ksh
147+
```
148+
149+
Use it to confirm that the public QEMU rehearsal layer is internally complete before you start a VM build.

‎docs/install/07-openbsd-autonomous-installer.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,14 @@ Generated outputs include:
127127
- do not place real provider credentials in tracked files
128128
- do not place private keys in the rendered public pack
129129
- keep your real profile file local and untracked
130+
131+
132+
## Asset validation
133+
134+
The repository now includes a dedicated autonomous installer verifier:
135+
136+
```sh
137+
./scripts/verify/verify-autonomous-installer-assets.ksh
138+
```
139+
140+
When an installer pack has been rendered, this verifier also checks the generated output set for completeness and unresolved placeholder drift.

‎docs/install/19-public-repo-readiness-check.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ At minimum, the public checks should validate:
5656
- the absence of unresolved `__PLACEHOLDER__` tokens in concrete generated examples
5757
- the continued use of gitignored `.work/` paths for live operator-generated outputs
5858
- essential service wiring patterns in tracked sanitized examples and live render trees
59+
- QEMU lab asset integrity for the public rehearsal layer
60+
- autonomous installer asset integrity, including generated pack outputs when rendered
5961

6062
The current repo-side semantic verifier is:
6163

@@ -69,6 +71,18 @@ The current rendered config verifier is:
6971
./scripts/verify/verify-rendered-config-integrity.ksh
7072
```
7173

74+
The current QEMU lab asset verifier is:
75+
76+
```sh
77+
./scripts/verify/verify-lab-assets.ksh
78+
```
79+
80+
The current autonomous installer asset verifier is:
81+
82+
```sh
83+
./scripts/verify/verify-autonomous-installer-assets.ksh
84+
```
85+
7286

7387
## E. Automated public repo gates
7488

@@ -85,6 +99,8 @@ It should be able to:
8599
- create temporary example-backed operator inputs
86100
- render live runtime trees into temporary gitignored paths
87101
- run repo semantic integrity checks
102+
- validate QEMU lab assets
103+
- render and validate an autonomous installer pack in a temporary build root
88104
- exercise the public-safe render and phase surfaces that are valid to prove in CI
89105

90106
## F. Intentional boundaries

‎maint/openbsd-autonomous-installer/README.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,12 @@ The profile file itself is local and untracked. The build directory is generated
5050
## Safety rule
5151

5252
Do not commit local profiles or live secrets.
53+
54+
55+
## Validation
56+
57+
Before serving or using a rendered installer pack, run:
58+
59+
```sh
60+
./scripts/verify/verify-autonomous-installer-assets.ksh
61+
```

‎maint/openbsd-autonomous-installer/render-installer-pack.ksh‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ set -eu
55
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
66
PROFILE=""
77
PROFILE_NAME=""
8-
BUILD_ROOT="${SCRIPT_DIR}/build"
8+
: "${OPENBSD_MAILSTACK_AUTOINSTALL_BUILD_ROOT:=${SCRIPT_DIR}/build}"
9+
BUILD_ROOT="${OPENBSD_MAILSTACK_AUTOINSTALL_BUILD_ROOT}"
910

1011
usage() {
1112
cat <<'USAGE'

‎maint/qemu/README.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,12 @@ It exists so operators can:
4343

4444
- Copy `qemu-lab.conf.example` to `qemu-lab.conf.local` when you want a local lab-specific config. That `.local` file is intentionally operator-local and untracked.
4545
- This directory is public and reusable. It must never contain live secrets, private keys, or customer-specific state.
46+
47+
48+
## Validation
49+
50+
Before beginning a lab rehearsal, run:
51+
52+
```sh
53+
./scripts/verify/verify-lab-assets.ksh
54+
```

‎scripts/verify/run-repo-ci-gates.ksh‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ prepare_ci_environment() {
6565
export OPENBSD_MAILSTACK_ADVANCED_SBOM_ROOT="${TMP_ROOT}/advanced/sbom"
6666
export OPENBSD_MAILSTACK_BACKUP_DR_WORK_ROOT="${TMP_ROOT}/backup-dr"
6767
export OPENBSD_MAILSTACK_OPERATIONS_WORK_ROOT="${TMP_ROOT}/operations"
68+
export OPENBSD_MAILSTACK_AUTOINSTALL_BUILD_ROOT="${TMP_ROOT}/autoinstall-build"
6869
}
6970

7071
main() {
@@ -73,6 +74,10 @@ main() {
7374
run "${PROJECT_ROOT}/scripts/verify/verify-documentation-integrity.ksh"
7475
run "${PROJECT_ROOT}/scripts/verify/verify-repo-semantic-integrity.ksh"
7576
run "${PROJECT_ROOT}/scripts/verify/verify-public-repo-readiness.ksh"
77+
run "${PROJECT_ROOT}/scripts/verify/verify-lab-assets.ksh"
78+
run "${PROJECT_ROOT}/maint/openbsd-autonomous-installer/guided-profile-builder.ksh" --noninteractive --output "${TMP_ROOT}/installer-profile.local.env"
79+
run "${PROJECT_ROOT}/maint/openbsd-autonomous-installer/render-installer-pack.ksh" --profile "${TMP_ROOT}/installer-profile.local.env"
80+
run "${PROJECT_ROOT}/scripts/verify/verify-autonomous-installer-assets.ksh"
7681

7782
run "${PROJECT_ROOT}/scripts/install/render-core-runtime-configs.ksh"
7883
run "${PROJECT_ROOT}/scripts/verify/verify-core-runtime-assets.ksh"
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/bin/ksh
2+
set -eu
3+
( set -o pipefail ) 2>/dev/null && set -o pipefail
4+
5+
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)"
6+
PROJECT_ROOT="$(CDPATH= cd -- "${SCRIPT_DIR}/../.." && pwd -P)"
7+
COMMON_LIB="${PROJECT_ROOT}/scripts/lib/common.ksh"
8+
9+
[ -f "${COMMON_LIB}" ] || {
10+
print -- "ERROR missing shared library: ${COMMON_LIB}" >&2
11+
exit 1
12+
}
13+
14+
. "${COMMON_LIB}"
15+
16+
FAIL=0
17+
PASS=0
18+
BUILD_ROOT="${OPENBSD_MAILSTACK_AUTOINSTALL_BUILD_ROOT:-${PROJECT_ROOT}/maint/openbsd-autonomous-installer/build}"
19+
20+
pass() { print -- "[$(timestamp)] PASS $*"; PASS=$((PASS + 1)); }
21+
fail() { print -- "[$(timestamp)] FAIL $*"; FAIL=$((FAIL + 1)); }
22+
23+
check_file() {
24+
_path="$1"
25+
_label="$2"
26+
if [ -f "${_path}" ]; then
27+
pass "${_label}: ${_path#${PROJECT_ROOT}/}"
28+
else
29+
fail "${_label} missing: ${_path#${PROJECT_ROOT}/}"
30+
fi
31+
}
32+
33+
check_var_in_example() {
34+
_var="$1"
35+
_file="$2"
36+
if grep -Eq '^'"${_var}"'=' "${_file}"; then
37+
pass "installer example defines ${_var}"
38+
else
39+
fail "installer example missing ${_var}"
40+
fi
41+
}
42+
43+
check_no_placeholders() {
44+
_file="$1"
45+
_label="$2"
46+
if grep -Eq '__[A-Z0-9_][A-Z0-9_]*__' "${_file}"; then
47+
fail "${_label} still contains unresolved placeholders: ${_file}"
48+
else
49+
pass "${_label} free of unresolved placeholders: ${_file}"
50+
fi
51+
}
52+
53+
check_build_outputs() {
54+
[ -d "${BUILD_ROOT}" ] || {
55+
pass "no rendered autonomous installer build root present, repo asset checks only"
56+
return 0
57+
}
58+
_found=0
59+
for _dir in "${BUILD_ROOT}"/*; do
60+
[ -d "${_dir}" ] || continue
61+
_found=1
62+
check_file "${_dir}/install.conf.78.lab" "installer build output"
63+
check_file "${_dir}/install.conf.78.real" "installer build output"
64+
check_file "${_dir}/disklabel-root-swap.template" "installer build output"
65+
check_file "${_dir}/site78.tgz" "installer build output"
66+
check_file "${_dir}/ACCOUNT-READINESS.md" "installer build output"
67+
[ -f "${_dir}/install.conf.78.lab" ] && check_no_placeholders "${_dir}/install.conf.78.lab" "installer lab config"
68+
[ -f "${_dir}/install.conf.78.real" ] && check_no_placeholders "${_dir}/install.conf.78.real" "installer real config"
69+
[ -f "${_dir}/ACCOUNT-READINESS.md" ] && check_no_placeholders "${_dir}/ACCOUNT-READINESS.md" "installer readiness summary"
70+
done
71+
[ "${_found}" -eq 1 ] || pass "autonomous installer build root exists but contains no rendered profiles yet"
72+
}
73+
74+
main() {
75+
_dir="${PROJECT_ROOT}/maint/openbsd-autonomous-installer"
76+
_example="${_dir}/installer-profile.example.env"
77+
78+
for _file in "${_dir}/README.md" "${_dir}/installer-profile.example.env" "${_dir}/guided-profile-builder.ksh" "${_dir}/render-installer-pack.ksh" "${_dir}/install.conf.78.lab.template" "${_dir}/install.conf.78.real.template" "${_dir}/disklabel-root-swap.template" "${_dir}/serve-autoinstall.sh" "${_dir}/site78_root/install.site.template" "${_dir}/site78_root/root/phase00-firstboot.sh.template"
79+
do
80+
check_file "${_file}" "autonomous installer asset present"
81+
done
82+
83+
for _var in PROFILE_NAME OPENBSD_VERSION OPENBSD_ARCH SYSTEM_HOSTNAME DNS_DOMAIN TIMEZONE OPERATOR_USER OPERATOR_HOME ROOT_PASSWORD_BCRYPT PARROT_PUBKEY LAN_IF_DEFAULT LAN_NET_DEFAULT HOST_IP_DEFAULT HOST_IP_CIDR_REAL HOST_GATEWAY_DEFAULT NAMESERVER_DEFAULT AUTOINSTALL_HTTP_HOST AUTOINSTALL_HTTP_PORT MAILSTACK_REPO_CLONE_URL; do
84+
check_var_in_example "${_var}" "${_example}"
85+
done
86+
87+
if grep -Fq 'installer-profile.local.env' "${PROJECT_ROOT}/docs/install/07-openbsd-autonomous-installer.md" && grep -Eq 'local and untracked|intentionally local and untracked' "${PROJECT_ROOT}/docs/install/07-openbsd-autonomous-installer.md"; then
88+
pass "autonomous installer doc correctly describes local untracked profile"
89+
else
90+
fail "autonomous installer doc does not clearly describe local untracked profile"
91+
fi
92+
93+
check_build_outputs
94+
95+
print
96+
print -- "Autonomous installer asset validation summary"
97+
print -- " PASS count : ${PASS}"
98+
print -- " FAIL count : ${FAIL}"
99+
print
100+
[ "${FAIL}" -eq 0 ]
101+
}
102+
103+
main "$@"
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/ksh
2+
set -eu
3+
( set -o pipefail ) 2>/dev/null && set -o pipefail
4+
5+
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)"
6+
PROJECT_ROOT="$(CDPATH= cd -- "${SCRIPT_DIR}/../.." && pwd -P)"
7+
COMMON_LIB="${PROJECT_ROOT}/scripts/lib/common.ksh"
8+
9+
[ -f "${COMMON_LIB}" ] || {
10+
print -- "ERROR missing shared library: ${COMMON_LIB}" >&2
11+
exit 1
12+
}
13+
14+
. "${COMMON_LIB}"
15+
16+
FAIL=0
17+
PASS=0
18+
19+
pass() { print -- "[$(timestamp)] PASS $*"; PASS=$((PASS + 1)); }
20+
fail() { print -- "[$(timestamp)] FAIL $*"; FAIL=$((FAIL + 1)); }
21+
22+
check_file() {
23+
_path="$1"
24+
_label="$2"
25+
if [ -f "${_path}" ]; then
26+
pass "${_label}: ${_path#${PROJECT_ROOT}/}"
27+
else
28+
fail "${_label} missing: ${_path#${PROJECT_ROOT}/}"
29+
fi
30+
}
31+
32+
check_var_in_example() {
33+
_var="$1"
34+
_file="$2"
35+
if grep -Eq '^'"${_var}"'=' "${_file}"; then
36+
pass "qemu example defines ${_var}"
37+
else
38+
fail "qemu example missing ${_var}"
39+
fi
40+
}
41+
42+
main() {
43+
_qemu_dir="${PROJECT_ROOT}/maint/qemu"
44+
_example="${_qemu_dir}/qemu-lab.conf.example"
45+
46+
for _file in "${_qemu_dir}/README.md" "${_qemu_dir}/qemu-lab.conf.example" "${_qemu_dir}/fetch-openbsd-amd64-media.ksh" "${_qemu_dir}/lab-install.sh" "${_qemu_dir}/lab-install.expect" "${_qemu_dir}/lab-bootstrap.expect" "${_qemu_dir}/lab-ssh-bootstrap.expect" "${_qemu_dir}/lab-openbsd78-build.ksh" "${_qemu_dir}/lab-phase-runner.ksh" "${_qemu_dir}/lab-ssh-guard.ksh" "${_qemu_dir}/lab-vm-ssh.ksh" "${_qemu_dir}/vm-phase-report-runner.ksh" "${_qemu_dir}/lab-dr-restore-runner.ksh" "${_qemu_dir}/lab-openbsd78-upgrade.ksh"
47+
do
48+
check_file "${_file}" "qemu asset present"
49+
done
50+
51+
for _var in OPENBSD_VERSION OPENBSD_ARCH OPENBSD_MIRROR QEMU_ISO_DIR QEMU_VM_DIR QEMU_DISK QEMU_ISO QEMU_MEM QEMU_SMP LAB_SSH_HOST LAB_SSH_PORT LAB_VM_NAME HOST_REPO_PATH; do
52+
check_var_in_example "${_var}" "${_example}"
53+
done
54+
55+
if grep -Fq 'qemu-lab.conf.local' "${PROJECT_ROOT}/docs/install/06-qemu-lab-and-vm-testing.md" && grep -Eq 'local and untracked|intentionally not tracked' "${PROJECT_ROOT}/docs/install/06-qemu-lab-and-vm-testing.md"; then
56+
pass "qemu install doc correctly describes local lab config"
57+
else
58+
fail "qemu install doc does not clearly describe local untracked lab config"
59+
fi
60+
61+
print
62+
print -- "QEMU lab asset validation summary"
63+
print -- " PASS count : ${PASS}"
64+
print -- " FAIL count : ${FAIL}"
65+
print
66+
[ "${FAIL}" -eq 0 ]
67+
}
68+
69+
main "$@"

0 commit comments

Comments
 (0)