Promote v0.1.18 to production

This commit is contained in:
GPU Kitchen delivery
2026-09-29 01:45:50 +00:00
parent 2b476b4e5f
commit cd50796883
3 changed files with 94 additions and 16 deletions
+82 -4
View File
@@ -87,6 +87,15 @@ arch_asset() {
esac
}
# [INS-19] A (re)install has just replaced the binary under a daemon that may be
# running: `systemctl enable --now` is a no-op on an active unit and would leave the
# OLD process in memory, speaking the old protocol to the new controller. Enable, then
# restart — which also starts a daemon that was not running.
start_daemon() {
systemctl enable "$SERVICE_NAME"
systemctl restart "$SERVICE_NAME"
}
install_binary() { # [local-path]
if [ -n "${1:-}" ]; then
[ -f "$1" ] || die "binary not found: $1"
@@ -630,7 +639,7 @@ cmd_install() {
echo " for automatic admission or administrator approval."
fi
fi
systemctl enable --now "$SERVICE_NAME"
start_daemon
echo "==> $SERVICE_NAME enabled and started"
echo
echo "Done. The worker daemon is running${ENROLL_TOKEN:+ and enrolled}."
@@ -640,7 +649,7 @@ cmd_install() {
fi
# ── Controller: start the daemon, then bring up the app container ──
systemctl enable --now "$SERVICE_NAME"
start_daemon
echo "==> $SERVICE_NAME enabled and started"
# The pull is the long part of a first install (a multi-GB image) and workerd
# runs docker with its output captured, so pulling from inside `apply` is
@@ -1110,6 +1119,67 @@ cmd_apply() {
# Worker: the signed-binary self-update is DRIVEN FROM THE CONTROLLER (its Update
# button → POST /api/nodes/:id/host/update → cmd:host_update → verified swap).
# There is no local unverified swap path.
# [INS-03] `gpuk update` moves the WHOLE host to the release the signed channel
# vouches for: the root daemon as well as the app container. Updating only the
# container leaves the co-located worker on the previous protocol, which the new
# controller refuses — and a refused worker cannot receive the UI's Update either.
# The binary is held to the same chain as install.sh's: minisign signature by the
# pinned key, trusted comment naming the build the channel designates for this
# architecture, never older than the daemon already installed. Sets DAEMON_UPDATED.
DAEMON_UPDATED=0
update_daemon() {
_base=$(channel_field "$CHANNEL_DOC" workerBase)
case "$(uname -m)" in
x86_64|amd64) _bkey="workerBuildIdX86_64" ;;
aarch64|arm64) _bkey="workerBuildIdAarch64" ;;
*) die "unsupported architecture: $(uname -m)" ;;
esac
_build=$(channel_field "$CHANNEL_DOC" "$_bkey")
if [ -z "$_base" ] || [ -z "$_build" ]; then
die "the signed release channel names no gpu-kitchen-worker build for $(uname -m) — refusing to leave the daemon on another release (OPS-20)"
fi
_installed=$("$BIN_DEST" --version 2>/dev/null | sed -n 's/^gpu-kitchen-worker //p' | head -1)
if [ "$_installed" = "$_build" ]; then
echo "==> worker daemon already on build $_build"
return 0
fi
case "$_installed" in
[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-*)
# buildId = YYYYMMDDHHMMSS-<commit>: the timestamp orders builds.
[ "${_build%%-*}" -ge "${_installed%%-*}" ] \
|| die "the channel's gpu-kitchen-worker $_build is OLDER than the installed $_installed — refusing a downgrade" ;;
esac
_url="$_base/$(arch_asset)"
echo "==> gpu-kitchen-worker ${_installed:-(unknown build)} → $_build"
command -v curl >/dev/null || die "curl is required to download the daemon"
curl -fL --progress-bar "$_url" -o "$BIN_DEST.new" \
|| { rm -f "$BIN_DEST.new"; die "cannot download $_url"; }
if [ "${GPUK_CHANNEL_INSECURE:-}" = "1" ]; then
echo "WARNING: GPUK_CHANNEL_INSECURE=1 — $_url NOT verified" >&2
else
require_release_key
curl -fsSL "$_url.minisig" -o "$BIN_DEST.new.minisig" \
|| { rm -f "$BIN_DEST.new" "$BIN_DEST.new.minisig"; die "no signature at $_url.minisig — refusing an unsigned daemon binary"; }
_comment=$("$MINISIGN" -V -m "$BIN_DEST.new" -x "$BIN_DEST.new.minisig" -P "$CHANNEL_PUBKEY" 2>/dev/null \
| sed -n 's/^Trusted comment: //p' | head -1)
rm -f "$BIN_DEST.new.minisig"
[ "$_comment" = "gpu-kitchen-worker@$_build" ] \
|| { rm -f "$BIN_DEST.new"; die "$_url is signed for '${_comment:-nothing}', not gpu-kitchen-worker@$_build — refusing it (OPS-20)"; }
echo "==> signature verified (build $_build)"
fi
chmod 0755 "$BIN_DEST.new"
mv "$BIN_DEST.new" "$BIN_DEST"
DAEMON_UPDATED=1
}
# The running daemon still executes the replaced binary until it restarts.
restart_updated_daemon() {
[ "$DAEMON_UPDATED" -eq 1 ] || return 0
systemctl restart "$SERVICE_NAME" \
|| die "the daemon binary was updated but $SERVICE_NAME did not restart — run: systemctl restart $SERVICE_NAME"
echo "==> $SERVICE_NAME restarted on the new build"
}
cmd_update() {
need_root
_want=""; _check=0
@@ -1123,8 +1193,12 @@ cmd_update() {
_image=$(manifest_image)
if [ -z "$_image" ]; then
echo "This is a worker node. Worker self-update is driven from the controller UI"
echo "(the node's Update button), which pushes a minisign-verified binary swap."
# A worker node: the daemon is the whole install. The controller UI's Update
# button drives the same swap, but only for a worker it still accepts.
[ "$_check" -eq 0 ] || { echo "This is a worker node: 'gpuk update' moves its daemon to the channel's build."; return 0; }
channel_fetch || die "cannot read the release channel at $CHANNEL_URL"
update_daemon
restart_updated_daemon
return 0
fi
@@ -1193,10 +1267,14 @@ cmd_update() {
else
echo "==> already on $_current — re-pulling and recreating"
fi
# The daemon follows the release it is pinned to — only the channel's own one
# carries a designated, signed build.
[ "$_want" != "$_latest" ] || update_daemon
GPUK_MANIFEST_PATH="$MANIFEST" "$BIN_DEST" apply \
|| die "the update did not apply — the [worker] lines above say why. A manifest refused for a field
an older release wrote is repaired by re-running the same install command with --reset-manifest:
the file is archived beside itself and rebuilt from this install's settings."
restart_updated_daemon
}
# ── uninstall ──────────────────────────────────────────────────────────────────