Remove the redundant timing-dependent native Argon2 concurrency test while retaining native vector coverage and deterministic limiter coverage. Refresh stale deployment and browser contracts, make release scripts portable across Bash/macOS, and update production dependency locks for resolved security advisories.
142 lines
5.9 KiB
Bash
Executable File
142 lines
5.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Clean-install contract for the server Pi-state parent bind and its read-only child mounts.
|
|
set -euo pipefail
|
|
|
|
root="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|
tmp_parent="${TMPDIR:-/tmp}"
|
|
tmp_parent="${tmp_parent%/}"
|
|
fixture="$(mktemp -d "$tmp_parent/thoth-server-pi-state.XXXXXX")"
|
|
trap 'rm -rf "$fixture"' EXIT HUP INT TERM
|
|
|
|
pi_state="$fixture/empty pi state"
|
|
auth_config="$fixture/auth"
|
|
mkdir -p "$pi_state"
|
|
mkdir -p "$auth_config"
|
|
chmod 0700 "$auth_config"
|
|
printf 'mode: local\n' >"$auth_config/auth.yaml"
|
|
chmod 0600 "$auth_config/auth.yaml"
|
|
"$root/scripts/prepare-server-pi-state.sh" "$pi_state" "$(id -u)" "$(id -g)"
|
|
|
|
for target in auth.json models.json settings.json; do
|
|
path="$pi_state/agent/$target"
|
|
[[ -f "$path" && ! -L "$path" ]] || {
|
|
echo "server Pi-state initializer did not create regular target: $target" >&2
|
|
exit 1
|
|
}
|
|
done
|
|
|
|
printf '%s\n' preserved-placeholder >"$pi_state/agent/models.json"
|
|
"$root/scripts/prepare-server-pi-state.sh" "$pi_state" "$(id -u)" "$(id -g)"
|
|
[[ "$(cat "$pi_state/agent/models.json")" == preserved-placeholder ]] || {
|
|
echo "server Pi-state initializer overwrote an existing target" >&2
|
|
exit 1
|
|
}
|
|
|
|
printf '{}\n' >"$fixture/pi-auth.json"
|
|
printf 'THT_MODEL_API_KEY=fixture-model-key\n' >"$fixture/thothii.secrets"
|
|
printf 'schema_version: 1\n' >"$fixture/thothii-installation.yaml"
|
|
printf 'fixture-session-password\n' >"$fixture/session-runtime-password"
|
|
printf 'fixture-session-migrator-password\n' >"$fixture/session-migrator-password"
|
|
printf 'fixture-session-ca\n' >"$fixture/session-ca.pem"
|
|
cp "$root/deploy/workspaces/server-sessions.yaml.example" "$fixture/server-sessions.yaml"
|
|
chmod 0600 "$fixture"/*.json "$fixture"/*.secrets "$fixture"/*.yaml "$fixture"/*password "$fixture"/*.pem
|
|
|
|
model_projection="$fixture/generated-models"
|
|
mkdir -p "$model_projection/pi"
|
|
printf '{}\n' >"$model_projection/catalog.json"
|
|
printf '{}\n' >"$model_projection/pi/models.json"
|
|
printf '{}\n' >"$model_projection/pi/settings.json"
|
|
cat >"$model_projection/compose.models.yaml" <<EOF
|
|
services:
|
|
core:
|
|
volumes:
|
|
- type: bind
|
|
source: "$model_projection/catalog.json"
|
|
target: /run/thothii-model-catalog/catalog.json
|
|
read_only: true
|
|
- type: bind
|
|
source: "$model_projection/pi/models.json"
|
|
target: /home/thoth/.pi/agent/models.json
|
|
read_only: true
|
|
- type: bind
|
|
source: "$model_projection/pi/settings.json"
|
|
target: /home/thoth/.pi/agent/settings.json
|
|
read_only: true
|
|
EOF
|
|
chmod 0600 "$model_projection/catalog.json" "$model_projection/pi"/*.json \
|
|
"$model_projection/compose.models.yaml"
|
|
|
|
cat >"$fixture/server.env" <<EOF
|
|
THOTH_SERVER_BIND=127.0.0.1
|
|
THOTH_HTTP_PORT=0
|
|
PI_AUTH_FILE=$fixture/pi-auth.json
|
|
THT_SECRETS_FILE=$fixture/thothii.secrets
|
|
THT_INSTALLATION_CONFIG_SOURCE=$fixture/thothii-installation.yaml
|
|
THT_AUTH_CONFIG_ROOT=$auth_config
|
|
THT_DATA_ROOT=$fixture/data
|
|
THT_PI_STATE_ROOT=$pi_state
|
|
THT_WORKSPACE_REGISTRY_ROOT=$fixture/workspace-registry
|
|
THT_SERVER_WORKSPACE_CONFIG=$fixture/server-sessions.yaml
|
|
THT_WORKSPACE_GIT_REMOTE=https://git.example.invalid/task13/workspaces.git
|
|
THT_SESSION_DB_HOST=sessions.example.invalid
|
|
THT_SESSION_DB_NAME=task13
|
|
THT_SESSION_RUNTIME_USER=task13_runtime
|
|
THT_SESSION_MIGRATOR_USER=task13_migrator
|
|
THT_SESSION_RUNTIME_PASSWORD_SOURCE=$fixture/session-runtime-password
|
|
THT_SESSION_MIGRATOR_PASSWORD_SOURCE=$fixture/session-migrator-password
|
|
THT_SESSION_CA_SOURCE=$fixture/session-ca.pem
|
|
EOF
|
|
mkdir -p "$fixture/data" "$fixture/workspace-registry"
|
|
|
|
docker compose --project-directory "$root" --env-file "$fixture/server.env" \
|
|
-f "$root/compose.yaml" \
|
|
-f "$root/deploy/compose.server.yaml" \
|
|
-f "$root/deploy/compose.session-server.yaml.example" \
|
|
-f "$model_projection/compose.models.yaml" \
|
|
config --format json >"$fixture/rendered.json"
|
|
|
|
node - "$fixture/rendered.json" "$pi_state" "$fixture/pi-auth.json" "$model_projection" <<'NODE'
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const [renderedPath, piState, authSource, modelProjection] = process.argv.slice(2);
|
|
const config = JSON.parse(fs.readFileSync(renderedPath, "utf8"));
|
|
const core = config.services?.core;
|
|
if (!core) throw new Error("server render lacks core");
|
|
const mounts = core.volumes || [];
|
|
const parent = mounts.find((mount) => mount.target === "/home/thoth/.pi");
|
|
if (!parent || parent.type !== "bind" || parent.source !== piState || parent.read_only) {
|
|
throw new Error("server Pi-state parent bind is not the expected writable root");
|
|
}
|
|
const children = new Map(mounts
|
|
.filter((mount) => mount.target?.startsWith("/home/thoth/.pi/agent/"))
|
|
.map((mount) => [path.basename(mount.target), mount]));
|
|
for (const name of ["auth.json", "models.json", "settings.json"]) {
|
|
const mount = children.get(name);
|
|
if (!mount || mount.type !== "bind" || !mount.read_only) {
|
|
throw new Error(`server Pi agent child is not one read-only bind: ${name}`);
|
|
}
|
|
const hiddenTarget = path.join(piState, "agent", name);
|
|
if (!fs.statSync(hiddenTarget).isFile()) {
|
|
throw new Error(`server Pi-state root lacks nested target: ${name}`);
|
|
}
|
|
}
|
|
if (children.get("auth.json").source !== authSource) {
|
|
throw new Error("server Pi auth source changed while preparing nested targets");
|
|
}
|
|
if (children.get("models.json").source !== path.join(modelProjection, "pi", "models.json")
|
|
|| children.get("settings.json").source !== path.join(modelProjection, "pi", "settings.json")) {
|
|
throw new Error("server Pi model projection sources changed");
|
|
}
|
|
const modelCatalog = mounts.find((mount) => mount.target === "/run/thothii-model-catalog/catalog.json");
|
|
if (!modelCatalog || modelCatalog.type !== "bind" || !modelCatalog.read_only
|
|
|| modelCatalog.source !== path.join(modelProjection, "catalog.json")) {
|
|
throw new Error("server model catalog is not the expected read-only bind");
|
|
}
|
|
if (JSON.stringify(config).includes("fixture-model-key")) {
|
|
throw new Error("server render leaked a secret value");
|
|
}
|
|
NODE
|
|
|
|
echo "clean empty-root server Pi-state render contract passed."
|