release v0.1.8
This commit is contained in:
@@ -92,7 +92,9 @@ install_binary() { # [local-path]
|
||||
command -v curl >/dev/null || die "curl is required to download the binary"
|
||||
_url="$GPUK_RELEASE_BASE/$(arch_asset)"
|
||||
echo "==> downloading $_url"
|
||||
curl -fsSL "$_url" -o "$BIN_DEST.new"
|
||||
# Not -s: the binary is tens of MB and a silent download reads as a hang.
|
||||
curl -fL --progress-bar "$_url" -o "$BIN_DEST.new" \
|
||||
|| { rm -f "$BIN_DEST.new"; die "cannot download $_url"; }
|
||||
chmod 0755 "$BIN_DEST.new"
|
||||
mv "$BIN_DEST.new" "$BIN_DEST"
|
||||
elif [ -x "$BIN_DEST" ]; then
|
||||
@@ -170,6 +172,22 @@ port_owner() { # $1 = ss|netstat, $2 = port
|
||||
fi
|
||||
}
|
||||
|
||||
# This host's LAN IPv4 — what a browser, a worker or a container on the docker
|
||||
# bridge dials to reach the machine. The route to a public address names the
|
||||
# source the default route uses (never a docker or libvirt bridge); failing that,
|
||||
# the first global address on a physical-looking interface; failing that, the
|
||||
# resolver's word. Empty when nothing answers — the caller says so. Same
|
||||
# derivation as dev.sh best_host_lan_ipv4 and install.sh's banner.
|
||||
host_lan_ipv4() {
|
||||
_ip=$(ip route get 1.1.1.1 2>/dev/null | sed -n 's/.* src \([0-9.]*\).*/\1/p' | head -1)
|
||||
if [ -z "$_ip" ]; then
|
||||
_ip=$(ip -o -4 addr show scope global 2>/dev/null \
|
||||
| awk '$2 !~ /^(virbr|docker|br-|veth|mpqemubr|tun|tap|vnet)/ {sub(/\/.*/, "", $4); print $4; exit}')
|
||||
fi
|
||||
[ -n "$_ip" ] || _ip=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||||
printf '%s' "$_ip"
|
||||
}
|
||||
|
||||
seed_secrets() { # DATA_ROOT
|
||||
_sd="$1/secrets"
|
||||
mkdir -p "$_sd"; chmod 0700 "$_sd"
|
||||
@@ -307,7 +325,12 @@ hint_existing_caches() {
|
||||
|
||||
cmd_install() {
|
||||
IMAGE=""; MODE="worker"; CLUSTER="default"; DATA_ROOT="/var/lib/gpu-kitchen"
|
||||
CACHE_DIR=""; NETWORK="host"; CONTROLLER_URL=""; BIN_SRC=""; HEALTH_PORT="8001"
|
||||
# bridge, not host (INS-49): on the host network every listener the image opens
|
||||
# is a host-wide claim, and a box that already runs something on 3000 or 8000
|
||||
# killed Nitro. Bridged, only the three published ports touch the host; what
|
||||
# that costs — the host daemon must be told its LAN address and the engines'
|
||||
# docker network — is written to worker.env below. `--network host` remains.
|
||||
CACHE_DIR=""; NETWORK="bridge"; CONTROLLER_URL=""; BIN_SRC=""; HEALTH_PORT="8001"
|
||||
# 1337, not 8080: kept in lockstep with install.sh's default (INS-01). The
|
||||
# worker channel and the inference endpoint move the same way (INS-46).
|
||||
ENROLL_TOKEN=""; HTTP_PORT="1337"; MTLS_PORT="8443"; INFERENCE_PORT="8200"
|
||||
@@ -315,10 +338,11 @@ cmd_install() {
|
||||
# GPUK_MODEL_TRANSFER_PORT and GPUK_HANDOVER_DATA_PORT from worker.env and
|
||||
# announces the first two to the controller, so moving them here is complete.
|
||||
DATA_PORT="8300"; TRANSFER_PORT="8301"; HANDOVER_PORT="8302"
|
||||
PROFILE=""; DOMAIN=""; DRY_RUN=0
|
||||
PROFILE=""; DOMAIN=""; DRY_RUN=0; RESET_MANIFEST=0
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--image) IMAGE="$2"; shift 2 ;;
|
||||
--reset-manifest) RESET_MANIFEST=1; shift ;;
|
||||
--mode) MODE="$2"; shift 2 ;;
|
||||
--cluster) CLUSTER="$2"; shift 2 ;;
|
||||
--profile) PROFILE="$2"; shift 2 ;;
|
||||
@@ -514,6 +538,23 @@ cmd_install() {
|
||||
write_controller_manifest
|
||||
# The host daemon and app container share DATA_ROOT. Only controller-mode
|
||||
# workerd gets this private bootstrap channel; remote workers stay tokenless.
|
||||
#
|
||||
# A bridged app container (INS-49) needs two more lines, read by the daemon
|
||||
# from its OWN env — the daemon runs on the host, not in the container:
|
||||
# - GPUK_DATA_HOST: the daemon dials the published mTLS port through docker
|
||||
# NAT, so the controller sees it arrive from the bridge gateway (172.17.0.1)
|
||||
# and would persist THAT as the node's address (WRK-93). The LAN address is
|
||||
# what peers, the proxy and the UI must dial instead.
|
||||
# - BACKEND_DOCKER_NETWORK: the engines the daemon launches join the app
|
||||
# container's docker network, so the backend and gpuk-proxy reach them by
|
||||
# container IP (apps/worker/src/modules/docker.rs, staging/engine.rs).
|
||||
# Exactly what dev.sh hands the dev worker; host networking needs neither.
|
||||
_data_host=""
|
||||
if [ "$NETWORK" != "host" ]; then
|
||||
_data_host="${GPUK_DATA_HOST:-$(host_lan_ipv4)}"
|
||||
[ -n "$_data_host" ] || echo "==> warning: this host's LAN IPv4 could not be determined (no ip, no hostname -I)." \
|
||||
"Set GPUK_DATA_HOST=<lan ip> in $WORKER_ENV, or the controller will address its own worker through the docker bridge."
|
||||
fi
|
||||
{
|
||||
echo "GPUK_CLUSTER=$CLUSTER"
|
||||
echo "GPUK_WORKER_HEALTH_PORT=$HEALTH_PORT"
|
||||
@@ -521,9 +562,13 @@ cmd_install() {
|
||||
echo "GPUK_CONTROLLER_URLS=wss://127.0.0.1:$MTLS_PORT"
|
||||
echo "GPUK_SELF_ENROLL_FILE=$SELF_ENROLL_FILE"
|
||||
echo "NODE_DISPLAY_NAME=$(hostname)"
|
||||
if [ "$NETWORK" != "host" ]; then
|
||||
[ -z "$_data_host" ] || echo "GPUK_DATA_HOST=$_data_host"
|
||||
echo "BACKEND_DOCKER_NETWORK=$NETWORK"
|
||||
fi
|
||||
} > "$WORKER_ENV"
|
||||
chmod 0600 "$WORKER_ENV"
|
||||
echo "==> wrote $MANIFEST (controller: app container $IMAGE)"
|
||||
echo "==> wrote $MANIFEST (controller: app container $IMAGE, network $NETWORK)"
|
||||
fi
|
||||
chmod 0600 "$MANIFEST"
|
||||
[ -z "$DOMAIN" ] || write_caddyfile
|
||||
@@ -561,11 +606,25 @@ cmd_install() {
|
||||
# ── Controller: start the daemon, then bring up the app container ──
|
||||
systemctl enable --now "$SERVICE_NAME"
|
||||
echo "==> $SERVICE_NAME enabled and started"
|
||||
echo "==> applying manifest (first app-container start) ..."
|
||||
# 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
|
||||
# minutes of silence that read as a hang. Pull here, on the terminal, where
|
||||
# docker's own per-layer progress is what the operator sees; `apply` then finds
|
||||
# the image present and skips its pull (INS-03).
|
||||
# Feedback only, never the verdict: `apply` pulls again whatever happened here
|
||||
# and reports the cause itself (the CI shell gate installs a stub daemon against
|
||||
# an image that does not exist anywhere — the daemon's pull is the one that counts).
|
||||
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
|
||||
echo "==> pulling $IMAGE (docker shows the progress per layer) ..."
|
||||
docker pull "$IMAGE" \
|
||||
|| echo "==> the pull did not complete here; the daemon retries it during apply and reports the cause if it fails again"
|
||||
fi
|
||||
echo "==> applying manifest — starting the app container and waiting for its health check (up to 60s) ..."
|
||||
# No unix socket any more: workerd reconciles the app container in-process from
|
||||
# the on-disk manifest (there is no backend to relay through on the very first
|
||||
# boot). Steady-state updates go through the daemon over WS.
|
||||
GPUK_MANIFEST_PATH="$MANIFEST" "$BIN_DEST" apply || die "apply failed. Check: gpuk logs"
|
||||
GPUK_MANIFEST_PATH="$MANIFEST" "$BIN_DEST" apply \
|
||||
|| die "the app container did not come up — the [worker] lines above say why (a [controller] FATAL line names the component and the fix). Full container logs: gpuk logs"
|
||||
echo
|
||||
echo "Done. The worker daemon is running and the app container is up."
|
||||
echo " Status : gpuk status App logs: gpuk logs Daemon: journalctl -u $SERVICE_NAME"
|
||||
@@ -605,12 +664,31 @@ INSTALL_ENV_KEYS="NODE_ENV,GPUK_MODE,GPUK_CLUSTER,GPUK_SELF_ENROLL_FILE,NODE_DIS
|
||||
# cluster, network, data root, ports, secret references, the primary cache disk,
|
||||
# the env keys above) and keeps the rest. The first write is the render as-is.
|
||||
write_manifest() { # $1 = render function
|
||||
if [ -f "$MANIFEST" ]; then
|
||||
if [ -f "$MANIFEST" ] && [ "$RESET_MANIFEST" -eq 1 ]; then
|
||||
# The operator's explicit regeneration (WRK-191): the daemon archives the
|
||||
# existing document — readable or not — writes the render as-is and NAMES what
|
||||
# the archive carried that the render does not. The flags install.sh inherited
|
||||
# from the old file (ports, profile, data root) are already in the render.
|
||||
"$1" > "$MANIFEST.new"
|
||||
chmod 0600 "$MANIFEST.new"
|
||||
GPUK_MANIFEST_PATH="$MANIFEST" "$BIN_DEST" install-manifest \
|
||||
--from "$MANIFEST.new" --reset >/dev/null \
|
||||
|| { rm -f "$MANIFEST.new"; die "could not reset $MANIFEST — the [worker] line above names the cause"; }
|
||||
rm -f "$MANIFEST.new"
|
||||
echo "==> $MANIFEST rebuilt from this install's settings (--reset-manifest); the previous file is archived beside it"
|
||||
elif [ -f "$MANIFEST" ]; then
|
||||
"$1" > "$MANIFEST.new"
|
||||
chmod 0600 "$MANIFEST.new"
|
||||
GPUK_MANIFEST_PATH="$MANIFEST" "$BIN_DEST" install-manifest \
|
||||
--from "$MANIFEST.new" --own-env "$INSTALL_ENV_KEYS" >/dev/null \
|
||||
|| { rm -f "$MANIFEST.new"; die "could not merge the new settings into $MANIFEST"; }
|
||||
|| {
|
||||
rm -f "$MANIFEST.new"
|
||||
die "could not merge the new settings into $MANIFEST — the [worker] line above names the cause.
|
||||
A manifest written by an older release can carry a field this release removed. Re-run the same
|
||||
command with --reset-manifest: the file is archived beside itself as manifest.json.before-reset.<time>,
|
||||
rebuilt from this install's settings, and every setting the archive carried that the rebuild does
|
||||
not (extra cache disks, LED binary, eviction…) is listed so you can set it again from the UI."
|
||||
}
|
||||
rm -f "$MANIFEST.new"
|
||||
echo "==> merged into the existing $MANIFEST (controller-owned settings kept)"
|
||||
else
|
||||
@@ -1017,7 +1095,7 @@ cmd_update() {
|
||||
# ── uninstall ──────────────────────────────────────────────────────────────────
|
||||
# Plain: stop and remove the service, touch nothing else (a pause, reversible by
|
||||
# `gpuk install`). --purge: everything the installer created goes — the app
|
||||
# container (and a leftover -old twin), $ETC_DIR with the manifest and the
|
||||
# container (and its -old / -failed twins), $ETC_DIR with the manifest and the
|
||||
# enrolled identity, the binary — EXCEPT the data root: database, models and the
|
||||
# secrets (ENCRYPTION_KEY above all, OPS-04) are the operator's to delete, by
|
||||
# hand, knowingly. After a purge the next install is a first install (INS-03);
|
||||
@@ -1043,7 +1121,7 @@ cmd_uninstall() {
|
||||
return 0
|
||||
fi
|
||||
if [ -n "$_cn" ] && command -v docker >/dev/null 2>&1; then
|
||||
for _c in "$_cn" "$_cn-old"; do
|
||||
for _c in "$_cn" "$_cn-old" "$_cn-failed"; do
|
||||
docker rm -f "$_c" >/dev/null 2>&1 && echo "==> removed container $_c"
|
||||
done
|
||||
fi
|
||||
@@ -1065,7 +1143,10 @@ gpuk — GPU Kitchen host daemon (gpu-kitchen-worker)
|
||||
gpuk install --mode controller --image <ref> [--profile homelab|studio|enterprise|public]
|
||||
[--cluster N] [--cache-dir P] [--data-root P]
|
||||
[--http-port P] [--mtls-port P] [--inference-port P]
|
||||
[--network host|bridge|<net>] [--binary <path>]
|
||||
[--network bridge|host|<net>] [--binary <path>] [--reset-manifest]
|
||||
--network: bridge by default — the container publishes its three
|
||||
ports and nothing else it listens on touches the host; host makes
|
||||
every listener a host-wide claim (a re-run keeps the mode installed)
|
||||
gpuk install --mode worker --controller wss://<host>:<port> --enroll-token gk_enroll_...
|
||||
[--cluster N] [--cache-dir P] [--binary <path>]
|
||||
[--health-port P] [--data-port P] [--transfer-port P] [--handover-port P]
|
||||
@@ -1079,7 +1160,8 @@ gpuk — GPU Kitchen host daemon (gpu-kitchen-worker)
|
||||
gpuk channel Fetch + VERIFY the release channel and print what it offers
|
||||
gpuk backup [DIR] (controller) Cold snapshot of the embedded pgdata (stop → tar → restart)
|
||||
gpuk manifest Print the current manifest
|
||||
gpuk logs Follow the app container logs (controller) or the daemon journal
|
||||
gpuk logs Follow the app container logs (controller) or the daemon journal;
|
||||
after a failed start, the kept <container>-failed log
|
||||
gpuk uninstall Remove the systemd service, leave everything else in place
|
||||
gpuk uninstall --purge Also remove the app container, /etc/gpu-kitchen and the binary
|
||||
(never the data root: database, models, secrets)
|
||||
@@ -1102,7 +1184,21 @@ case "$cmd" in
|
||||
manifest) cat "$MANIFEST" ;;
|
||||
logs)
|
||||
_img=$(manifest_image)
|
||||
if [ -n "$_img" ]; then exec docker logs -f "$(container_name)"; else exec journalctl -u "$SERVICE_NAME" -f; fi
|
||||
if [ -n "$_img" ]; then
|
||||
_cn=$(container_name)
|
||||
if docker inspect "$_cn" >/dev/null 2>&1; then
|
||||
exec docker logs -f "$_cn"
|
||||
elif docker inspect "$_cn-failed" >/dev/null 2>&1; then
|
||||
# No live app container, but the last failed start was kept (INS-15):
|
||||
# its whole log is the diagnosis, not the daemon journal.
|
||||
echo "==> no running app container; showing the full log of the last failed start ($_cn-failed)" >&2
|
||||
exec docker logs "$_cn-failed"
|
||||
else
|
||||
exec journalctl -u "$SERVICE_NAME" -f
|
||||
fi
|
||||
else
|
||||
exec journalctl -u "$SERVICE_NAME" -f
|
||||
fi
|
||||
;;
|
||||
uninstall) cmd_uninstall "$@" ;;
|
||||
help|-h|--help) usage ;;
|
||||
|
||||
+51
-5
@@ -56,6 +56,10 @@ PORT="${GPUK_PORT:-1337}"
|
||||
MTLS_PORT="${GPUK_MTLS_PORT:-8443}"
|
||||
INFERENCE_PORT="${GPUK_INFERENCE_PORT:-8200}"
|
||||
CLUSTER="${GPUK_CLUSTER:-default}"
|
||||
# The app container's docker network. Empty = gpuk's default (bridge, INS-49);
|
||||
# an existing install keeps the mode it runs in (INS-03) — flipping the default
|
||||
# must never move a host-mode install to bridge on its next re-run.
|
||||
NETWORK="${GPUK_NETWORK:-}"
|
||||
# Which of those came from the operator (flag or env) — an existing install keeps
|
||||
# its own value for everything the operator did not ask to change (INS-03).
|
||||
PORT_GIVEN=0; [ -z "${GPUK_PORT:-}" ] || PORT_GIVEN=1
|
||||
@@ -64,6 +68,7 @@ INFERENCE_GIVEN=0; [ -z "${GPUK_INFERENCE_PORT:-}" ] || INFERENCE_GIVEN=1
|
||||
DATA_ROOT_GIVEN=0; [ -z "${GPUK_DATA_ROOT:-}" ] || DATA_ROOT_GIVEN=1
|
||||
CACHE_GIVEN=0; [ -z "${GPUK_CACHE_DIR:-}" ] || CACHE_GIVEN=1
|
||||
CLUSTER_GIVEN=0; [ -z "${GPUK_CLUSTER:-}" ] || CLUSTER_GIVEN=1
|
||||
NETWORK_GIVEN=0; [ -z "${GPUK_NETWORK:-}" ] || NETWORK_GIVEN=1
|
||||
# Where an existing install keeps its manifest. Same override as gpuk's, and for
|
||||
# the same reason: it is the only way to exercise the re-run path without root.
|
||||
ETC_DIR="${GPUK_ETC_DIR:-/etc/gpu-kitchen}"
|
||||
@@ -71,6 +76,7 @@ MANIFEST="$ETC_DIR/manifest.json"
|
||||
UNIT_DEST="${GPUK_UNIT_DEST:-/etc/systemd/system/gpu-kitchen-worker.service}"
|
||||
BIN_DEST="${GPUK_BIN_DEST:-/usr/local/bin/gpu-kitchen-worker}"
|
||||
PROFILE=""
|
||||
RESET_MANIFEST=0
|
||||
DOMAIN=""
|
||||
VERSION=""
|
||||
IMAGE=""
|
||||
@@ -124,10 +130,17 @@ Options:
|
||||
--data-root <path> Where the database and secrets live (default /var/lib/gpu-kitchen)
|
||||
--cache-dir <path> Model cache (default <data-root>/hf)
|
||||
--cluster <name> Cluster name workers join (default "default")
|
||||
--network <mode> bridge (default) | host. Bridged, only the three ports above
|
||||
touch the host; host makes every listener of the container a
|
||||
host-wide claim. An existing install keeps its mode.
|
||||
--profile <p> homelab | studio | enterprise | public (no flag + a terminal
|
||||
= the script asks; no flag + no terminal = first-run asks)
|
||||
--domain <d> Domain for the public profile: writes a filled TLS
|
||||
reverse-proxy example to <data-root>/caddy/Caddyfile
|
||||
--reset-manifest Rebuild /etc/gpu-kitchen/manifest.json from this run's settings
|
||||
when the daemon refuses the existing one (a field an older
|
||||
release wrote); the old file is archived beside it and what
|
||||
it carried that the rebuild does not is listed
|
||||
--non-interactive Never ask anything, even with a terminal attached
|
||||
--worker-binary <p> Use a locally-built gpu-kitchen-worker instead of downloading one
|
||||
--gpuk-script <p> Use a local copy of the gpuk installer
|
||||
@@ -150,9 +163,11 @@ while [ $# -gt 0 ]; do
|
||||
--data-root) DATA_ROOT="$2"; DATA_ROOT_GIVEN=1; shift 2 ;;
|
||||
--cache-dir) CACHE_DIR="$2"; CACHE_GIVEN=1; shift 2 ;;
|
||||
--cluster) CLUSTER="$2"; CLUSTER_GIVEN=1; shift 2 ;;
|
||||
--network) NETWORK="$2"; NETWORK_GIVEN=1; shift 2 ;;
|
||||
--profile) PROFILE="$2"; shift 2 ;;
|
||||
--domain) DOMAIN="$2"; shift 2 ;;
|
||||
--non-interactive) NON_INTERACTIVE=1; shift ;;
|
||||
--reset-manifest) RESET_MANIFEST=1; shift ;;
|
||||
--worker-binary) WORKER_BINARY="$2"; shift 2 ;;
|
||||
--gpuk-script) GPUK_SCRIPT="$2"; shift 2 ;;
|
||||
--skip-gpu-check) SKIP_GPU_CHECK=1; shift ;;
|
||||
@@ -177,6 +192,13 @@ case "$DOMAIN" in
|
||||
*[!A-Za-z0-9.-]*) die "--domain must be a bare domain name (got '$DOMAIN')" ;;
|
||||
esac
|
||||
|
||||
# bridge, host, or the name of a docker network gpuk hands to `docker create
|
||||
# --network` — never a value that could be read as another flag or as whitespace.
|
||||
case "$NETWORK" in
|
||||
""|bridge|host) ;;
|
||||
-*|*[!A-Za-z0-9_.-]*) die "--network must be bridge, host or a docker network name (got '$NETWORK')" ;;
|
||||
esac
|
||||
|
||||
for _pv in "$PORT" "$MTLS_PORT" "$INFERENCE_PORT"; do
|
||||
case "$_pv" in
|
||||
''|*[!0-9]*) die "not a port number: '$_pv'" ;;
|
||||
@@ -274,11 +296,17 @@ case "$EXISTING" in
|
||||
[ "$PORT_GIVEN" -eq 1 ] || PORT="$OURS_UI"
|
||||
[ "$MTLS_GIVEN" -eq 1 ] || MTLS_PORT="$OURS_MTLS"
|
||||
[ "$INFERENCE_GIVEN" -eq 1 ] || INFERENCE_PORT="$OURS_INF"
|
||||
# The network mode is a setting like the ports: an install that runs on the
|
||||
# host network stays there when the default is bridge (INS-49), and the
|
||||
# reverse — only --network moves it. An old manifest without the field is
|
||||
# read as the daemon reads it (host).
|
||||
[ "$NETWORK_GIVEN" -eq 1 ] || NETWORK="${C_NETMODE:-host}"
|
||||
case "$_profile" in
|
||||
homelab|studio|enterprise|public) [ -n "$PROFILE" ] || PROFILE="$_profile" ;;
|
||||
esac
|
||||
ok "data root $DATA_ROOT"
|
||||
ok "ports UI $OURS_UI, worker channel $OURS_MTLS, inference $OURS_INF"
|
||||
ok "network ${C_NETMODE:-host}"
|
||||
[ -z "$_profile" ] || ok "profile $_profile"
|
||||
ok "re-running updates it in place. Its settings are kept unless a flag says otherwise."
|
||||
;;
|
||||
@@ -606,6 +634,7 @@ if [ "$DRY_RUN" -eq 1 ]; then
|
||||
echo " UI port : $PORT"
|
||||
echo " worker channel: $MTLS_PORT"
|
||||
echo " inference : $INFERENCE_PORT"
|
||||
echo " network : ${NETWORK:-bridge}"
|
||||
case "$EXISTING" in
|
||||
manifest) echo " existing : yes — updated in place" ;;
|
||||
leftovers) echo " existing : traces of a previous install — taken over" ;;
|
||||
@@ -728,6 +757,10 @@ set -- install \
|
||||
|
||||
[ -z "$PROFILE" ] || set -- "$@" --profile "$PROFILE"
|
||||
[ -z "$DOMAIN" ] || set -- "$@" --domain "$DOMAIN"
|
||||
[ "$RESET_MANIFEST" -eq 0 ] || set -- "$@" --reset-manifest
|
||||
# Inherited from the manifest or given by flag; unset on a first install, so
|
||||
# gpuk's own default (bridge, INS-49) applies and this script never restates it.
|
||||
[ -z "$NETWORK" ] || set -- "$@" --network "$NETWORK"
|
||||
|
||||
if [ -n "$WORKER_BINARY" ]; then
|
||||
[ -f "$WORKER_BINARY" ] || die "no such worker binary: $WORKER_BINARY"
|
||||
@@ -741,7 +774,11 @@ fi
|
||||
# else: gpuk reuses an already-installed binary, or fails with its own message.
|
||||
|
||||
step "Installing — this pulls the image, so it can take a few minutes"
|
||||
sh "$GPUK_SCRIPT" "$@" || die "the install failed. See: journalctl -u gpu-kitchen-worker"
|
||||
# gpuk names its own failure on stderr before exiting (a refused manifest, a
|
||||
# failed apply, a missing binary…), so the cause is the line right above this
|
||||
# one. journalctl only has something to say once the daemon has started, and
|
||||
# gpuk points at `gpuk logs` itself in that case.
|
||||
sh "$GPUK_SCRIPT" "$@" || die "the install failed — gpuk reported the cause just above"
|
||||
|
||||
# ── 5. Wait for the app, then say where it is ────────────────────────────────
|
||||
step "Waiting for the controller to answer"
|
||||
@@ -776,10 +813,19 @@ else
|
||||
echo " ${BOLD}Claim code:${RESET} consumed (the first account already exists)"
|
||||
fi
|
||||
echo
|
||||
# The wizard's first step asks for a Kitchen ACCOUNT key (CPT-04). It is the
|
||||
# person's credential, never the machine's — this script cannot create or print
|
||||
# it, and the browser must not receive it in a URL (CPT-05/06). What it can do
|
||||
# is say so, and say where the key comes from, before the page does.
|
||||
echo " ${BOLD}Next:${RESET} open the URL above. Its first step asks for your GPU Kitchen account key"
|
||||
echo " (gpuk_…). Sign in to your GPU Kitchen account and create one under Install keys:"
|
||||
echo " https://gpu.kitchen/account#install-keys"
|
||||
echo " That key is yours, not this machine's: the installer never sees it,"
|
||||
echo " and the page exchanges it for a revocable installation token."
|
||||
|
||||
case "$PROFILE" in
|
||||
public)
|
||||
echo " ${BOLD}Next:${RESET} create the first administrator in the UI"
|
||||
echo " ${BOLD}Then:${RESET} create the first administrator in the UI"
|
||||
echo
|
||||
# The public profile REQUIRES a TLS reverse proxy (OPS-13, INS-47) — the UI
|
||||
# port speaks plain HTTP. The product cannot verify the proxy's presence
|
||||
@@ -799,15 +845,15 @@ case "$PROFILE" in
|
||||
echo
|
||||
;;
|
||||
enterprise)
|
||||
echo " ${BOLD}Next:${RESET} create the first administrator in the UI"
|
||||
echo " ${BOLD}Then:${RESET} create the first administrator in the UI"
|
||||
echo
|
||||
;;
|
||||
homelab|studio)
|
||||
echo " ${BOLD}Next:${RESET} finish first-run in the UI"
|
||||
echo " ${BOLD}Then:${RESET} finish first-run in the UI"
|
||||
echo
|
||||
;;
|
||||
"")
|
||||
echo " ${BOLD}Next:${RESET} choose an installation profile in the first-run assistant"
|
||||
echo " ${BOLD}Then:${RESET} choose an installation profile in the first-run assistant"
|
||||
echo
|
||||
;;
|
||||
esac
|
||||
|
||||
+5
-5
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"version": "v0.1.5",
|
||||
"semver": "0.1.5",
|
||||
"version": "v0.1.8",
|
||||
"semver": "0.1.8",
|
||||
"controllerImage": "repo.byterain.io/gpukitchen/gpukitchen-controller",
|
||||
"controllerImageEnterprise": "repo.byterain.io/gpukitchen-private/gpukitchen-controller-ee",
|
||||
"controllerImageDigest": "sha256:5a126247a2f24a29338ba2a84414a3ef8e270a1696dd7a32a3894889836594b1",
|
||||
"controllerImageDigestEnterprise": "sha256:a8f55534aa09a1f077dc5d72116db2b1f2f153b0e2f3c6299d777a1d80c3dfab",
|
||||
"workerBase": "https://repo.byterain.io/api/packages/gpukitchen/generic/gpu-kitchen-worker/v0.1.5",
|
||||
"controllerImageDigest": "sha256:4bceef1f73703ddd4dbcf2af45627dfa15e268f7d94929daf0b70989977324fd",
|
||||
"controllerImageDigestEnterprise": "sha256:32eaf7a7ce4203d5d723af95f2d55c1fb9370b2a74fe4524997cb3f6b21c9894",
|
||||
"workerBase": "https://repo.byterain.io/api/packages/gpukitchen/generic/gpu-kitchen-worker/v0.1.8",
|
||||
"gpukScript": "https://repo.byterain.io/gpukitchen/channel/raw/branch/main/gpuk",
|
||||
"releaseNotes": "https://repo.byterain.io/gpukitchen/channel"
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
untrusted comment: signature from minisign secret key
|
||||
RUQ7BKXJqGX2jabBqcSYwUGmejKh6OS+qKIyVqxpzwJ4PwIBVDAAuoxgF6CkfyxiNgQvpS63RUIRE485PVdRvHTW8UQd10fuIAQ=
|
||||
trusted comment: gpu-kitchen channel v0.1.5
|
||||
f+6uK6GJBgurIcd7L2l53/SPV/VqRv9DfJfRaFbc5tJTBVRL5I2zgzEF66YytLXHUHScAM7MZsJi9VUCeoGxAw==
|
||||
RUQ7BKXJqGX2jXfsXMmaGO2bObez5DagrH233W/mWwx1u3yu+MuMkzbtyVc59cCwGk97UTG5l2qwvZ9cpWpvWxFHvdmiibMRkgo=
|
||||
trusted comment: gpu-kitchen channel v0.1.8
|
||||
GWhwdOcKDhFj2nPvMYY1NDiTha2SGawzERQYs2tdf4i2uqlrfcWJLhnVZirrGtBewBOwcC+oRCEXX56I1si3Cg==
|
||||
|
||||
Reference in New Issue
Block a user