2026-08-15 17:34:30 +08:00
#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
die( ) {
echo " GUANGHU_LINUX_SUBCONTROL_FAIL_0: $* " >& 2
exit 1
}
test_mode = ${ GH_SUBCONTROL_TEST_MODE :- 0 }
if [ [ " ${ test_mode } " = = 1 ] ] ; then
config_path = ${ GH_SUBCONTROL_CONFIG : ?test config is required }
docker_bin = ${ GH_SUBCONTROL_DOCKER : ?test docker is required }
dmi_path = ${ GH_SUBCONTROL_DMI_PATH : ?test DMI path is required }
grub_cfg = ${ GH_SUBCONTROL_GRUB_CFG : ?test GRUB path is required }
state_root = ${ GH_SUBCONTROL_STATE_ROOT : ?test state root is required }
receipt_root = ${ GH_SUBCONTROL_RECEIPT_ROOT : ?test receipt root is required }
else
[ [ " ${ EUID } " = = 0 ] ] || die "root execution is required"
for override in \
GH_SUBCONTROL_CONFIG GH_SUBCONTROL_DOCKER GH_SUBCONTROL_DMI_PATH \
GH_SUBCONTROL_GRUB_CFG GH_SUBCONTROL_STATE_ROOT GH_SUBCONTROL_RECEIPT_ROOT; do
[ [ -z " ${ !override :- } " ] ] || die " production path override is forbidden: ${ override } "
done
config_path = /etc/guanghu/linux-subcontrol.conf
docker_bin = /usr/bin/docker
dmi_path = /sys/class/dmi/id/product_uuid
grub_cfg = /boot/grub/grub.cfg
state_root = /run/guanghu/linux-subcontrol
receipt_root = /guanghu/receipts/linux-subcontrol
[ [ -f " ${ config_path } " && ! -L " ${ config_path } " ] ] || die "root-owned backend config is missing"
[ [ " $( stat -c '%u:%a' " ${ config_path } " ) " = ~ ^0:( 600| 640| 644) $ ] ] ||
die "backend config owner or mode is unsafe"
fi
schema =
node_id =
instance_id =
backend_id =
container_name =
image =
rescue_slot_id =
while IFS = '=' read -r key value; do
[ [ -n " ${ key } " ] ] || continue
case " ${ key } " in
schema| node_id| instance_id| backend_id| container_name| image| rescue_slot_id)
printf -v " ${ key } " '%s' " ${ value } "
; ;
*) die " unknown config field: ${ key } " ; ;
esac
done <" ${ config_path } "
[ [ " ${ schema } " = = "guanghu.linux-subcontrol-docker-backend/v1" ] ] || die "config schema mismatch"
[ [ " ${ node_id } " = = "JD-FD-PRIMARY" ] ] || die "target node mismatch"
[ [ " ${ instance_id } " = ~ ^[ 0-9a-f-] { 36} $ ] ] || die "instance id is invalid"
[ [ " ${ backend_id } " = ~ ^[ a-z0-9-] +$ ] ] || die "backend id is invalid"
[ [ " ${ container_name } " = ~ ^[ a-z0-9-] +$ ] ] || die "container name is invalid"
2026-08-15 17:53:33 +08:00
[ [ " ${ image } " = ~ ^( ubuntu| docker\. m\. daocloud\. io/library/ubuntu) @sha256:[ 0-9a-f] { 64} $ ] ] || die "image must use an immutable Ubuntu digest from the direct or approved proxy repository"
2026-08-15 17:34:30 +08:00
[ [ " ${ rescue_slot_id } " = ~ ^[ A-Za-z0-9._-] +$ ] ] || die "rescue slot id is invalid"
[ [ -x " ${ docker_bin } " ] ] || die "docker executable is unavailable"
requested_backend = ${ 2 :- }
[ [ -n " ${ requested_backend } " && " ${ requested_backend } " = = " ${ backend_id } " ] ] ||
die "backend binding mismatch"
verify_machine( ) {
local observed
observed = $( tr '[:upper:]' '[:lower:]' <" ${ dmi_path } " )
[ [ " ${ observed } " = = " ${ instance_id } " ] ] || die "machine identity mismatch"
}
verify_rescue( ) {
2026-08-15 18:01:01 +08:00
grep -F -- 'menuentry ' " ${ grub_cfg } " | grep -Fq -- " ' ${ rescue_slot_id } ' " ||
2026-08-15 17:34:30 +08:00
die "independent Linux rescue slot is unavailable"
}
container_running( ) {
[ [ " $( " ${ docker_bin } " inspect --format '{{.State.Running}}' " ${ container_name } " 2>/dev/null || true ) " = = true ] ]
}
observe( ) {
if container_running; then
echo ready
else
echo dormant
fi
}
action = ${ 1 :- }
case " ${ action } " in
preflight)
verify_machine
verify_rescue
" ${ docker_bin } " image inspect " ${ image } " >/dev/null
echo "GUANGHU_LINUX_SUBCONTROL_PREFLIGHT_OK"
; ;
observe)
observe
; ;
wake)
verify_machine
verify_rescue
[ [ " $( observe) " = = dormant ] ] || die "backend is not dormant before wake"
" ${ docker_bin } " image inspect " ${ image } " >/dev/null
mkdir -p " ${ state_root } " " ${ receipt_root } "
" ${ docker_bin } " run \
--detach \
--pull never \
--name " ${ container_name } " \
--hostname jd-linux-subcontrol \
--label guanghu.owner= GUANGHU_OS \
--label " guanghu.node= ${ node_id } " \
--label " guanghu.backend= ${ backend_id } " \
--network none \
--read-only \
--tmpfs /run:rw,nosuid,nodev,noexec,size= 16m \
--tmpfs /tmp:rw,nosuid,nodev,noexec,size= 16m \
--cap-drop ALL \
--security-opt no-new-privileges \
--pids-limit 64 \
--memory 256m \
--cpus 0.50 \
" ${ image } " \
/bin/sh -ceu 'trap "exit 0" TERM INT; while :; do sleep 3600 & wait $!; done' \
>/dev/null
container_running || die "backend failed readiness readback"
echo "GUANGHU_LINUX_SUBCONTROL_READY"
; ;
execute| verify)
capability = ${ 3 :- }
request_id = ${ 4 :- }
[ [ " ${ capability } " = = runtime-identity-readback ] ] || die "capability is not allowlisted"
[ [ " ${ request_id } " = ~ ^[ A-Za-z0-9._-] +$ ] ] || die "request id is invalid"
container_running || die "backend is not ready"
mkdir -p " ${ state_root } " " ${ receipt_root } "
target_file = " ${ state_root } / ${ request_id } .target "
if [ [ " ${ action } " = = execute ] ] ; then
temporary = " ${ target_file } .tmp "
" ${ docker_bin } " exec " ${ container_name } " /bin/sh -ceu \
'. /etc/os-release; printf "ID=%s\nVERSION_ID=%s\n" "$ID" "$VERSION_ID"' \
>" ${ temporary } "
chmod 600 " ${ temporary } "
mv " ${ temporary } " " ${ target_file } "
echo "GUANGHU_LINUX_SUBCONTROL_EXECUTED"
else
[ [ -f " ${ target_file } " ] ] || die "target readback is missing"
expected = $'ID=ubuntu\nVERSION_ID=22.04'
stored = $( cat " ${ target_file } " )
live = $( " ${ docker_bin } " exec " ${ container_name } " /bin/sh -ceu \
'. /etc/os-release; printf "ID=%s\nVERSION_ID=%s\n" "$ID" "$VERSION_ID"' )
[ [ " ${ stored } " = = " ${ expected } " && " ${ live } " = = " ${ expected } " ] ] ||
die "target readback mismatch"
echo "GUANGHU_LINUX_SUBCONTROL_TARGET_VERIFIED"
fi
; ;
reclaim)
if container_running; then
" ${ docker_bin } " rm --force " ${ container_name } " >/dev/null
fi
[ [ " $( observe) " = = dormant ] ] || die "backend reclaim failed"
echo "GUANGHU_LINUX_SUBCONTROL_DORMANT"
; ;
*)
die " usage: $0 <preflight|observe|wake|execute|verify|reclaim> <backend-id> [capability] [request-id] "
; ;
esac