feat(hololake): provision signed in-app update bootstrap
This commit is contained in:
parent
7414810862
commit
cfa8fdefc2
15 changed files with 144 additions and 31 deletions
|
|
@ -17,6 +17,7 @@ readonly AI_DISCOVERY=/opt/guanghu/ai-discovery/server.js
|
|||
readonly PNCC_RUNTIME=/usr/local/libexec/guanghu/pncc-runtime.mjs
|
||||
readonly PNCC_REPOSITORY=/var/lib/guanghu/personas/ICE-P-ZY001/pncc/repository
|
||||
readonly PNCC_STATE_ROOT=/run/guanghu/pncc
|
||||
readonly HOLOLAKE_RELEASE_BRIDGE=/usr/local/libexec/guanghu/hololake-release-bridge
|
||||
|
||||
declare -a CHILDREN=()
|
||||
RECOVERY_ARMED=0
|
||||
|
|
@ -125,6 +126,7 @@ start_bridge() {
|
|||
require_file "$AI_DISCOVERY"
|
||||
require_file "$PNCC_RUNTIME"
|
||||
require_file "$PNCC_REPOSITORY/.hololake/persona/manifest.json"
|
||||
require_file "$HOLOLAKE_RELEASE_BRIDGE"
|
||||
|
||||
start_root sshd /usr/sbin/sshd -D -e \
|
||||
-o UsePAM=no -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no \
|
||||
|
|
@ -163,6 +165,9 @@ start_bridge() {
|
|||
--repository "$PNCC_REPOSITORY" --state-root "$PNCC_STATE_ROOT" \
|
||||
--node-id "$NODE_ID" --host 127.0.0.1 --port 3923
|
||||
wait_http pncc-runtime http://127.0.0.1:3923/health 200 30
|
||||
|
||||
start_root hololake-release-bridge "$HOLOLAKE_RELEASE_BRIDGE"
|
||||
wait_http hololake-release-broadcast http://127.0.0.1:3940/health 200 30
|
||||
}
|
||||
|
||||
runtime_watch() {
|
||||
|
|
@ -183,6 +188,7 @@ runtime_watch() {
|
|||
listen_ready 8088 || fatal "runtime_projection_lost"
|
||||
listen_ready 3922 || fatal "runtime_navigation_lost"
|
||||
listen_ready 3923 || fatal "runtime_pncc_lost"
|
||||
listen_ready 3940 || fatal "runtime_hololake_release_lost"
|
||||
done
|
||||
}
|
||||
|
||||
|
|
@ -203,6 +209,7 @@ preflight() {
|
|||
getent passwd guanghu | grep -q '^guanghu:x:998:998:'
|
||||
for path in "$HLCC" "$APP_HUB" "$AI_DISCOVERY" "$PNCC_RUNTIME" \
|
||||
"$PNCC_REPOSITORY/.hololake/persona/manifest.json" /usr/sbin/sshd \
|
||||
"$HOLOLAKE_RELEASE_BRIDGE" \
|
||||
/usr/bin/node /usr/bin/python3 /usr/bin/setpriv /usr/bin/grub-editenv; do
|
||||
[[ -e $path && ! -L $path || $path == /usr/bin/python3 ]]
|
||||
done
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
#!/bin/bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
# Resident HoloLake update bridge for JD-FD-PRIMARY under the Guanghu
|
||||
# supervisor. The release origin remains loopback-only. A dedicated,
|
||||
# port-forwarding-only SSH identity exposes exactly one loopback port on the
|
||||
# registered BS-GZ-006 HTTPS front door.
|
||||
|
||||
readonly RELEASE_SERVER=/opt/guanghu/hololake-release-broadcast-candidate/current/server.mjs
|
||||
readonly RELEASE_STATE_ROOT=/var/lib/guanghu/hololake-release-broadcast
|
||||
readonly RELEASE_PORT=3940
|
||||
readonly TUNNEL_KEY=/etc/guanghu/secrets/hololake-release-tunnel-ed25519
|
||||
readonly TUNNEL_KNOWN_HOSTS=/etc/guanghu/secrets/hololake-release-tunnel-known-hosts
|
||||
readonly FRONT_DOOR_HOST=43.139.217.141
|
||||
readonly FRONT_DOOR_USER=hololake-tunnel
|
||||
readonly FRONT_DOOR_PORT=19440
|
||||
|
||||
declare -a CHILDREN=()
|
||||
|
||||
cleanup() {
|
||||
trap - EXIT INT TERM
|
||||
for pid in "${CHILDREN[@]:-}"; do
|
||||
kill "$pid" 2>/dev/null || true
|
||||
done
|
||||
wait 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
require_exact_runtime() {
|
||||
[[ -f $RELEASE_SERVER && ! -L $RELEASE_SERVER ]] || {
|
||||
# current is an audited immutable-release symlink; resolve it and reject a
|
||||
# non-regular final target rather than following arbitrary path material.
|
||||
local resolved
|
||||
resolved=$(readlink -f "$RELEASE_SERVER")
|
||||
[[ $resolved == /opt/guanghu/hololake-release-broadcast-candidate/*/server.mjs ]]
|
||||
[[ -f $resolved && ! -L $resolved ]]
|
||||
}
|
||||
[[ -f $TUNNEL_KEY && ! -L $TUNNEL_KEY ]]
|
||||
[[ -f $TUNNEL_KNOWN_HOSTS && ! -L $TUNNEL_KNOWN_HOSTS ]]
|
||||
[[ $(stat -c '%a' "$TUNNEL_KEY") == 600 ]]
|
||||
}
|
||||
|
||||
start_pair() {
|
||||
CHILDREN=()
|
||||
/usr/bin/setpriv --reuid=989 --regid=989 --init-groups --inh-caps=-all --reset-env \
|
||||
/usr/bin/env HOME=/nonexistent USER=hololake-release LOGNAME=hololake-release \
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
|
||||
HOLOLAKE_RELEASE_HOST=127.0.0.1 HOLOLAKE_RELEASE_PORT="$RELEASE_PORT" \
|
||||
HOLOLAKE_RELEASE_STATE_ROOT="$RELEASE_STATE_ROOT" \
|
||||
/usr/bin/node "$RELEASE_SERVER" &
|
||||
CHILDREN+=("$!")
|
||||
|
||||
/usr/bin/ssh -N \
|
||||
-i "$TUNNEL_KEY" -o IdentitiesOnly=yes -o BatchMode=yes \
|
||||
-o UserKnownHostsFile="$TUNNEL_KNOWN_HOSTS" -o StrictHostKeyChecking=yes \
|
||||
-o ExitOnForwardFailure=yes -o ServerAliveInterval=20 -o ServerAliveCountMax=3 \
|
||||
-R "127.0.0.1:${FRONT_DOOR_PORT}:127.0.0.1:${RELEASE_PORT}" \
|
||||
"${FRONT_DOOR_USER}@${FRONT_DOOR_HOST}" &
|
||||
CHILDREN+=("$!")
|
||||
}
|
||||
|
||||
main() {
|
||||
require_exact_runtime
|
||||
while :; do
|
||||
start_pair
|
||||
wait -n "${CHILDREN[@]}" || true
|
||||
for pid in "${CHILDREN[@]}"; do kill "$pid" 2>/dev/null || true; done
|
||||
wait 2>/dev/null || true
|
||||
sleep 2
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
@ -27,6 +27,9 @@ grep -Fq 'wait_http navigation-bridge http://127.0.0.1:3922/v1/anchor 200' "$sub
|
|||
grep -Fq 'wait_http pncc-runtime http://127.0.0.1:3923/health 200' "$subject"
|
||||
grep -Fq '\"pncc\":\"RESIDENT_BOUND_CARRIER_SEPARATE\"' "$subject"
|
||||
grep -Fq 'listen_ready 3923 || fatal "runtime_pncc_lost"' "$subject"
|
||||
grep -Fq 'start_root hololake-release-bridge "$HOLOLAKE_RELEASE_BRIDGE"' "$subject"
|
||||
grep -Fq 'wait_http hololake-release-broadcast http://127.0.0.1:3940/health 200 30' "$subject"
|
||||
grep -Fq 'listen_ready 3940 || fatal "runtime_hololake_release_lost"' "$subject"
|
||||
if grep -Eq '(^|[[:space:]])(systemd|/sbin/init)([[:space:]]|$)' "$subject"; then
|
||||
echo 'full Linux init must remain dormant' >&2
|
||||
exit 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue