refactor(cli): rename operator command to tht
This commit is contained in:
@@ -3,14 +3,14 @@ set -euo pipefail
|
||||
export DOCKER_BUILDKIT=1
|
||||
|
||||
repository_root=$(cd "$(dirname "$0")/.." && pwd)
|
||||
output_directory="${THT_THOTHCTL_OUTPUT_DIRECTORY:-$repository_root/dist/thothctl}"
|
||||
output_directory="${THT_THT_OUTPUT_DIRECTORY:-$repository_root/dist/tht}"
|
||||
|
||||
if [[ "$output_directory" != /* || "$output_directory" == / || "$output_directory" == */ ||
|
||||
"$output_directory" == *//* || "/$output_directory/" == */../* ||
|
||||
"/$output_directory/" == */./* ]]; then
|
||||
echo "THT_THOTHCTL_OUTPUT_DIRECTORY must be an absolute canonical path" >&2
|
||||
echo "THT_THT_OUTPUT_DIRECTORY must be an absolute canonical path" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
mkdir -p "$output_directory"
|
||||
docker build --file "$repository_root/docker/thothctl.Dockerfile" --output "type=local,dest=$output_directory" "$repository_root"
|
||||
docker build --file "$repository_root/docker/tht.Dockerfile" --output "type=local,dest=$output_directory" "$repository_root"
|
||||
@@ -22,7 +22,7 @@ install -d -o 10001 -g 20002 -m 2750 /srv/thothii/secrets
|
||||
install -d -o 10001 -g 10001 -m 0750 /srv/thothii/data /srv/thothii/pi-state /srv/thothii/workspace-registry
|
||||
install -d -o 10001 -g 10001 -m 0700 /srv/thothii/data/workspace-secrets
|
||||
install -d -o 10001 -g 20002 -m 2750 /srv/thothii/source/ThothII /srv/thothii/source/ThothII/scripts
|
||||
install -o 10001 -g 20002 -m 0750 /repository/scripts/build-thothctl.sh /srv/thothii/source/ThothII/scripts/build-thothctl.sh
|
||||
install -o 10001 -g 20002 -m 0750 /repository/scripts/build-tht.sh /srv/thothii/source/ThothII/scripts/build-tht.sh
|
||||
install -o 10001 -g 20002 -m 0750 /repository/scripts/prepare-server-pi-state.sh /srv/thothii/source/ThothII/scripts/prepare-server-pi-state.sh
|
||||
/srv/thothii/source/ThothII/scripts/prepare-server-pi-state.sh /srv/thothii/pi-state 10001 10001
|
||||
|
||||
@@ -37,8 +37,8 @@ printf "%s\n" \
|
||||
"if [[ \"\${1:-}\" == build ]]; then" \
|
||||
" destination=; for argument in \"\$@\"; do case \"\$argument\" in type=local,dest=*) destination=\"\${argument#type=local,dest=}\" ;; esac; done" \
|
||||
" test -n \"\$destination\"; mkdir -p \"\$destination\"" \
|
||||
" printf \"%s\\n\" \"#!/bin/bash\" \"set -euo pipefail\" \"test -r \\\"\\\$2\\\"\" \"docker compose up --detach\" > \"\$destination/thothctl-linux-amd64\"" \
|
||||
" chmod 0750 \"\$destination/thothctl-linux-amd64\"; exit 0" \
|
||||
" printf \"%s\\n\" \"#!/bin/bash\" \"set -euo pipefail\" \"test -r \\\"\\\$2\\\"\" \"docker compose up --detach\" > \"\$destination/tht-linux-amd64\"" \
|
||||
" chmod 0750 \"\$destination/tht-linux-amd64\"; exit 0" \
|
||||
"fi" \
|
||||
"test \"\${1:-}\" = compose; : > /srv/thothii/operator/start.marker" \
|
||||
> /usr/local/bin/docker
|
||||
@@ -52,17 +52,17 @@ for protected in /srv/thothii /srv/thothii/source /srv/thothii/secrets \
|
||||
/srv/thothii/data /srv/thothii/pi-state /srv/thothii/workspace-registry; do
|
||||
if touch "$protected/operator-must-not-write" 2>/dev/null; then exit 42; fi
|
||||
done
|
||||
THT_THOTHCTL_OUTPUT_DIRECTORY=/srv/thothii/operator/build-output \
|
||||
/srv/thothii/source/ThothII/scripts/build-thothctl.sh
|
||||
if THT_THOTHCTL_OUTPUT_DIRECTORY=relative-output \
|
||||
/srv/thothii/source/ThothII/scripts/build-thothctl.sh 2>/dev/null; then exit 44; fi
|
||||
THT_THT_OUTPUT_DIRECTORY=/srv/thothii/operator/build-output \
|
||||
/srv/thothii/source/ThothII/scripts/build-tht.sh
|
||||
if THT_THT_OUTPUT_DIRECTORY=relative-output \
|
||||
/srv/thothii/source/ThothII/scripts/build-tht.sh 2>/dev/null; then exit 44; fi
|
||||
root_output_error=/srv/thothii/operator/root-output.error
|
||||
if THT_THOTHCTL_OUTPUT_DIRECTORY=/ \
|
||||
/srv/thothii/source/ThothII/scripts/build-thothctl.sh 2>"$root_output_error"; then exit 45; fi
|
||||
grep -Fq "THT_THOTHCTL_OUTPUT_DIRECTORY must be an absolute canonical path" \
|
||||
if THT_THT_OUTPUT_DIRECTORY=/ \
|
||||
/srv/thothii/source/ThothII/scripts/build-tht.sh 2>"$root_output_error"; then exit 45; fi
|
||||
grep -Fq "THT_THT_OUTPUT_DIRECTORY must be an absolute canonical path" \
|
||||
"$root_output_error" || exit 46
|
||||
rm -f "$root_output_error"
|
||||
/srv/thothii/operator/build-output/thothctl-linux-amd64 \
|
||||
/srv/thothii/operator/build-output/tht-linux-amd64 \
|
||||
--installation /srv/thothii/operator/thothii-installation.yaml start
|
||||
'\''
|
||||
|
||||
@@ -74,8 +74,8 @@ for target in auth.json models.json settings.json; do
|
||||
test "$(stat -c %u:%g /srv/thothii/pi-state/agent/$target)" = 10001:10001
|
||||
test "$(stat -c %a /srv/thothii/pi-state/agent/$target)" = 600
|
||||
done
|
||||
test "$(stat -c %u:%g /srv/thothii/operator/build-output/thothctl-linux-amd64)" = 20001:20002
|
||||
test "$(stat -c %a /srv/thothii/operator/build-output/thothctl-linux-amd64)" = 750
|
||||
test "$(stat -c %u:%g /srv/thothii/operator/build-output/tht-linux-amd64)" = 20001:20002
|
||||
test "$(stat -c %a /srv/thothii/operator/build-output/tht-linux-amd64)" = 750
|
||||
test -f /srv/thothii/operator/start.marker
|
||||
for protected in /srv/thothii /srv/thothii/source /srv/thothii/secrets \
|
||||
/srv/thothii/data /srv/thothii/pi-state /srv/thothii/workspace-registry; do
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
set -euo pipefail
|
||||
|
||||
repository_root=$(cd "$(dirname "$0")/.." && pwd)
|
||||
dockerfile="$repository_root/docker/thothctl.Dockerfile"
|
||||
dockerfile="$repository_root/docker/tht.Dockerfile"
|
||||
builder_image=$(awk '$1 == "FROM" && $3 == "AS" && $4 == "build" { print $2; exit }' "$dockerfile")
|
||||
expected_builder='golang:1.26.5-bookworm@sha256:1ecb7edf62a0408027bd5729dfd6b1b8766e578e8df93995b225dfd0944eb651'
|
||||
|
||||
if [[ "$builder_image" != "$expected_builder" ]]; then
|
||||
echo "thothctl builder must pin golang:1.26.5-bookworm by the approved multi-platform digest" >&2
|
||||
echo "tht builder must pin golang:1.26.5-bookworm by the approved multi-platform digest" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
grep -qx 'go 1.26.0' "$repository_root/tools/thothctl/go.mod"
|
||||
grep -qx 'toolchain go1.26.5' "$repository_root/tools/thothctl/go.mod"
|
||||
grep -Eq '^[[:space:]]*github.com/sirupsen/logrus v1\.9\.1$' "$repository_root/tools/thothctl/go.mod"
|
||||
grep -Eq '^[[:space:]]*golang.org/x/sys v0\.47\.0$' "$repository_root/tools/thothctl/go.mod"
|
||||
grep -qx 'go 1.26.0' "$repository_root/tools/tht/go.mod"
|
||||
grep -qx 'toolchain go1.26.5' "$repository_root/tools/tht/go.mod"
|
||||
grep -Eq '^[[:space:]]*github.com/sirupsen/logrus v1\.9\.1$' "$repository_root/tools/tht/go.mod"
|
||||
grep -Eq '^[[:space:]]*golang.org/x/sys v0\.47\.0$' "$repository_root/tools/tht/go.mod"
|
||||
|
||||
manifest=$(docker buildx imagetools inspect "$builder_image")
|
||||
printf '%s\n' "$manifest" | grep -Eq 'Platform:[[:space:]]+linux/amd64'
|
||||
@@ -24,10 +24,10 @@ temporary_output=$(mktemp -d)
|
||||
trap 'rm -rf "$temporary_output"' EXIT HUP INT TERM
|
||||
docker build --file "$dockerfile" --output "type=local,dest=$temporary_output" "$repository_root" >/dev/null
|
||||
|
||||
test -s "$temporary_output/thothctl-windows-amd64.exe"
|
||||
test -s "$temporary_output/thothctl-darwin-amd64"
|
||||
test -s "$temporary_output/thothctl-darwin-arm64"
|
||||
test -s "$temporary_output/thothctl-linux-amd64"
|
||||
test -s "$temporary_output/thothctl-linux-arm64"
|
||||
test -s "$temporary_output/tht-windows-amd64.exe"
|
||||
test -s "$temporary_output/tht-darwin-amd64"
|
||||
test -s "$temporary_output/tht-darwin-arm64"
|
||||
test -s "$temporary_output/tht-linux-amd64"
|
||||
test -s "$temporary_output/tht-linux-arm64"
|
||||
|
||||
echo "thothctl build contract passed."
|
||||
echo "tht build contract passed."
|
||||
@@ -87,7 +87,7 @@ for required in \
|
||||
}
|
||||
done
|
||||
grep -Fq '"$THTCTL" --help' "$server_guide" || {
|
||||
echo "server guide lacks plain thothctl --help" >&2
|
||||
echo "server guide lacks plain tht --help" >&2
|
||||
exit 1
|
||||
}
|
||||
if grep -Fq '"$THTCTL" --installation "$INSTALLATION" --help' "$server_guide"; then
|
||||
@@ -106,7 +106,7 @@ for manual in "$root/docs/install/local-workspace-registry.md"; do
|
||||
fi
|
||||
done
|
||||
|
||||
grep -Fq 'THTCTL=/srv/thothii/operator/thothctl' \
|
||||
grep -Fq 'THTCTL=/srv/thothii/operator/tht' \
|
||||
"$root/docs/install/server-workspace-registry.md" || {
|
||||
echo "server installation manual does not use the installation-aware operator CLI" >&2
|
||||
exit 1
|
||||
@@ -957,7 +957,7 @@ expect_guide_rejected \
|
||||
"$root/docs/install/local.md" docs/install/local.md failed-pull \
|
||||
"POSIX source update does not fail closed: source pull"
|
||||
expect_guide_rejected \
|
||||
"failed thothctl Pi status" verify_local_guide \
|
||||
"failed tht Pi status" verify_local_guide \
|
||||
"$root/docs/install/local.md" docs/install/local.md failed-status \
|
||||
"POSIX source update does not fail closed: Pi status"
|
||||
expect_guide_rejected \
|
||||
|
||||
@@ -134,11 +134,11 @@ try {
|
||||
Copy-Item -LiteralPath $source -Destination $destination
|
||||
}
|
||||
|
||||
$thothctl = Join-Path $spacedRepository "dist/thothctl/thothctl-windows-amd64.exe"
|
||||
[System.IO.Directory]::CreateDirectory([System.IO.Path]::GetDirectoryName($thothctl)) | Out-Null
|
||||
Invoke-BoundedNative -FilePath "go" -Arguments @("build", "-trimpath", "-o", $thothctl, "./cmd/thothctl") `
|
||||
-WorkingDirectory (Join-Path $spacedRepository "tools/thothctl") -Label "build native Windows thothctl in spaced path" | Out-Null
|
||||
Invoke-BoundedNative -FilePath $thothctl -Arguments @("--help") -Label "invoke native Windows thothctl from spaced path" | Out-Null
|
||||
$tht = Join-Path $spacedRepository "dist/tht/tht-windows-amd64.exe"
|
||||
[System.IO.Directory]::CreateDirectory([System.IO.Path]::GetDirectoryName($tht)) | Out-Null
|
||||
Invoke-BoundedNative -FilePath "go" -Arguments @("build", "-trimpath", "-o", $tht, "./cmd/tht") `
|
||||
-WorkingDirectory (Join-Path $spacedRepository "tools/tht") -Label "build native Windows tht in spaced path" | Out-Null
|
||||
Invoke-BoundedNative -FilePath $tht -Arguments @("--help") -Label "invoke native Windows tht from spaced path" | Out-Null
|
||||
|
||||
$piAuth = Join-Path $fixtureRoot "Pi Auth/pi-auth.json"
|
||||
$secrets = Join-Path $fixtureRoot "Secrets/thothii.secrets"
|
||||
@@ -266,7 +266,7 @@ overrides:
|
||||
if (($runningServices -join ",") -ne "core,frontend") {
|
||||
throw "bounded Windows startup did not leave exactly core and frontend running"
|
||||
}
|
||||
Invoke-BoundedNative -FilePath $thothctl -Arguments @("--installation", $installation, "status") -Label "invoke installation-aware Windows thothctl in spaced path" | Out-Null
|
||||
Invoke-BoundedNative -FilePath $tht -Arguments @("--installation", $installation, "status") -Label "invoke installation-aware Windows tht in spaced path" | Out-Null
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -311,7 +311,7 @@ if (-not $cleanupSucceeded) {
|
||||
throw "Windows cleanup proof failed; fixture path retained for recovery"
|
||||
}
|
||||
if ($DockerStartup) {
|
||||
Write-Output "Windows spaced-path build, native thothctl, bounded two-service startup, and exact cleanup passed."
|
||||
Write-Output "Windows spaced-path build, native tht, bounded two-service startup, and exact cleanup passed."
|
||||
} else {
|
||||
Write-Output "Windows spaced-path clone, LF-byte, Compose render, and native thothctl build/invocation contracts passed; Docker startup mode was not requested."
|
||||
Write-Output "Windows spaced-path clone, LF-byte, Compose render, and native tht build/invocation contracts passed; Docker startup mode was not requested."
|
||||
}
|
||||
|
||||
@@ -5,4 +5,4 @@ root="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
# shellcheck source=./unified-deployment-smoke.sh
|
||||
source "$root/scripts/unified-deployment-smoke.sh"
|
||||
|
||||
task13_supervise "$TASK13_SMOKE_TIMEOUT" "thothctl update smoke" task13_smoke_main update
|
||||
task13_supervise "$TASK13_SMOKE_TIMEOUT" "tht update smoke" task13_smoke_main update
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# End-to-end release gate for the canonical two-service Compose distribution.
|
||||
# This file is also sourced by thothctl-update-smoke.sh so both entry points use the same
|
||||
# This file is also sourced by tht-update-smoke.sh so both entry points use the same
|
||||
# isolated fixture, exact cleanup, and sanitized failure reporting.
|
||||
set -euo pipefail
|
||||
|
||||
@@ -556,23 +556,23 @@ task13_seed_registry() {
|
||||
task13_commit_registry_change 'Seed Task 13 workspace registry'
|
||||
}
|
||||
|
||||
task13_build_thothctl() {
|
||||
task13_build_tht() {
|
||||
local os arch
|
||||
mkdir -p "$TASK13_THOTHCTL_DIR"
|
||||
task13_run_logged "build thothctl cross-platform binaries" env \
|
||||
THT_THOTHCTL_OUTPUT_DIRECTORY="$TASK13_THOTHCTL_DIR" \
|
||||
bash "$TASK13_ROOT/scripts/build-thothctl.sh"
|
||||
mkdir -p "$TASK13_THT_DIR"
|
||||
task13_run_logged "build tht cross-platform binaries" env \
|
||||
THT_THT_OUTPUT_DIRECTORY="$TASK13_THT_DIR" \
|
||||
bash "$TASK13_ROOT/scripts/build-tht.sh"
|
||||
os="$(uname -s)"
|
||||
arch="$(uname -m)"
|
||||
case "$os/$arch" in
|
||||
Darwin/x86_64) TASK13_THOTHCTL="$TASK13_THOTHCTL_DIR/thothctl-darwin-amd64" ;;
|
||||
Darwin/arm64) TASK13_THOTHCTL="$TASK13_THOTHCTL_DIR/thothctl-darwin-arm64" ;;
|
||||
Linux/x86_64|Linux/amd64) TASK13_THOTHCTL="$TASK13_THOTHCTL_DIR/thothctl-linux-amd64" ;;
|
||||
Linux/aarch64|Linux/arm64) TASK13_THOTHCTL="$TASK13_THOTHCTL_DIR/thothctl-linux-arm64" ;;
|
||||
Darwin/x86_64) TASK13_THT="$TASK13_THT_DIR/tht-darwin-amd64" ;;
|
||||
Darwin/arm64) TASK13_THT="$TASK13_THT_DIR/tht-darwin-arm64" ;;
|
||||
Linux/x86_64|Linux/amd64) TASK13_THT="$TASK13_THT_DIR/tht-linux-amd64" ;;
|
||||
Linux/aarch64|Linux/arm64) TASK13_THT="$TASK13_THT_DIR/tht-linux-arm64" ;;
|
||||
*) task13_fail "unsupported smoke host: $os/$arch" ;;
|
||||
esac
|
||||
chmod 0700 "$TASK13_THOTHCTL"
|
||||
task13_run_logged "invoke host thothctl" "$TASK13_THOTHCTL" --help
|
||||
chmod 0700 "$TASK13_THT"
|
||||
task13_run_logged "invoke host tht" "$TASK13_THT" --help
|
||||
}
|
||||
|
||||
task13_assert_rendered_contract() {
|
||||
@@ -670,12 +670,12 @@ task13_assert_runtime() {
|
||||
|| task13_fail "core lacks the explicit Task 13 resource label"
|
||||
task13_compose_logged "internal Pi provider smoke" exec -T core \
|
||||
curl --connect-timeout 3 --max-time 45 -fsS -X POST \
|
||||
-H 'x-thoth-principal-issuer: thothctl' \
|
||||
-H 'x-thoth-principal-subject: thothctl-maintenance' \
|
||||
-H 'x-thoth-principal-display-name: Thothctl maintenance' \
|
||||
-H 'x-thoth-principal-issuer: tht' \
|
||||
-H 'x-thoth-principal-subject: tht-maintenance' \
|
||||
-H 'x-thoth-principal-display-name: Tht maintenance' \
|
||||
-H 'x-thoth-is-admin: 1' \
|
||||
http://127.0.0.1:8787/pi-management/test
|
||||
task13_run_logged "thothctl Pi doctor" "$TASK13_THOTHCTL" --installation "$TASK13_INSTALLATION" pi doctor
|
||||
task13_run_logged "tht Pi doctor" "$TASK13_THT" --installation "$TASK13_INSTALLATION" pi doctor
|
||||
}
|
||||
|
||||
task13_server_auth_headers() {
|
||||
@@ -950,20 +950,20 @@ task13_update_rollback() {
|
||||
TASK13_PREVIOUS_IMAGE_ID="$before_image"
|
||||
before_mounts="$(task13_mount_fingerprint)"
|
||||
before_head="$(task13_active_registry_head)"
|
||||
output="$TASK13_TMP/thothctl-update.out"
|
||||
output="$TASK13_TMP/tht-update.out"
|
||||
set +e
|
||||
"$TASK13_THOTHCTL" --installation "$TASK13_INSTALLATION" pi update \
|
||||
"$TASK13_THT" --installation "$TASK13_INSTALLATION" pi update \
|
||||
--version "$TASK13_BAD_PI_VERSION" --source pull --image "$TASK13_BAD_CANDIDATE_IMAGE" --yes \
|
||||
>"$output" 2>&1
|
||||
rc=$?
|
||||
set -e
|
||||
[[ "$rc" -ne 0 ]] || task13_fail "bad Pi candidate unexpectedly passed update verification"
|
||||
if grep -Fq "$TASK13_SECRET_VALUE" "$output"; then
|
||||
task13_fail "thothctl update output exposed the fixture secret"
|
||||
task13_fail "tht update output exposed the fixture secret"
|
||||
fi
|
||||
grep -Fq 'previous core image was restored' "$output" \
|
||||
|| { task13_sanitize <"$output" >&2; task13_fail "thothctl did not report automatic rollback"; }
|
||||
[[ -f "$TASK13_UPDATE_STATE" ]] || task13_fail "thothctl update state was not persisted"
|
||||
|| { task13_sanitize <"$output" >&2; task13_fail "tht did not report automatic rollback"; }
|
||||
[[ -f "$TASK13_UPDATE_STATE" ]] || task13_fail "tht update state was not persisted"
|
||||
phase="$(sed -n 's/.*"phase": "\([^"]*\)".*/\1/p' "$TASK13_UPDATE_STATE" | head -n 1)"
|
||||
[[ "$phase" == rolled_back ]] || task13_fail "update state phase is not rolled_back"
|
||||
if grep -Fq "$TASK13_SECRET_VALUE" "$TASK13_UPDATE_STATE"; then
|
||||
@@ -977,8 +977,8 @@ task13_update_rollback() {
|
||||
[[ "$after_mounts" == "$before_mounts" ]] || task13_fail "rollback changed persistence volume identity"
|
||||
[[ "$after_head" == "$before_head" ]] || task13_fail "rollback changed the active registry revision"
|
||||
task13_assert_sentinels
|
||||
task13_run_logged "post-rollback thothctl doctor" \
|
||||
"$TASK13_THOTHCTL" --installation "$TASK13_INSTALLATION" pi doctor
|
||||
task13_run_logged "post-rollback tht doctor" \
|
||||
"$TASK13_THT" --installation "$TASK13_INSTALLATION" pi doctor
|
||||
task13_compose exec -T core curl --connect-timeout 3 --max-time 10 -fsS \
|
||||
http://127.0.0.1:8787/workspaces \
|
||||
| grep -Fq 'Task 13 Smoke' || task13_fail "rollback lost the active workspace"
|
||||
@@ -1020,7 +1020,7 @@ task13_remove_transaction_image() {
|
||||
if ! docker image inspect "$reference" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
if [[ ! "$reference" =~ ^thothii-core:thothctl-[0-9a-f]{16}-(candidate|previous)$ \
|
||||
if [[ ! "$reference" =~ ^thothii-core:tht-[0-9a-f]{16}-(candidate|previous)$ \
|
||||
|| ! "$expected_id" =~ ^sha256:([0-9a-f]{64}|owned)$ ]]; then
|
||||
printf 'refusing to remove invalid transaction image reference %s\n' "$reference" >&2
|
||||
return 1
|
||||
@@ -1108,9 +1108,9 @@ task13_cleanup() {
|
||||
transaction="$(sed -n 's/.*"transaction": "\([^"]*\)".*/\1/p' "$TASK13_UPDATE_STATE" | head -n 1)"
|
||||
fi
|
||||
if [[ -n "$transaction" ]]; then
|
||||
task13_remove_transaction_image "thothii-core:thothctl-$transaction-candidate" \
|
||||
task13_remove_transaction_image "thothii-core:tht-$transaction-candidate" \
|
||||
"${TASK13_BAD_CANDIDATE_ID:-}" >>"${TASK13_LOG:-/dev/null}" 2>&1 || cleanup_rc=1
|
||||
task13_remove_transaction_image "thothii-core:thothctl-$transaction-previous" \
|
||||
task13_remove_transaction_image "thothii-core:tht-$transaction-previous" \
|
||||
"${TASK13_PREVIOUS_IMAGE_ID:-}" >>"${TASK13_LOG:-/dev/null}" 2>&1 || cleanup_rc=1
|
||||
fi
|
||||
for image in \
|
||||
@@ -1126,7 +1126,7 @@ task13_cleanup() {
|
||||
done < <(docker image ls -q --filter "label=io.thothii.task13.run=$TASK13_RUN_ID" | sort -u)
|
||||
fi
|
||||
if [[ -n "${TASK13_CONTROL_DIR:-}" ]]; then
|
||||
if [[ "$TASK13_CONTROL_DIR" == "$TASK13_ROOT/.thothctl/$TASK13_PROJECT" \
|
||||
if [[ "$TASK13_CONTROL_DIR" == "$TASK13_ROOT/.tht/$TASK13_PROJECT" \
|
||||
&& "$TASK13_PROJECT" =~ ^thothii-[0-9a-f]{12}$ ]]; then
|
||||
rm -rf "$TASK13_CONTROL_DIR"
|
||||
else
|
||||
@@ -1319,8 +1319,8 @@ task13_self_test_transaction_image_cleanup() {
|
||||
local calls foreign_error owned_ref foreign_ref
|
||||
calls="$(mktemp "${TMPDIR:-/tmp}/thothii-task13-transaction-cleanup-contract.XXXXXX")"
|
||||
foreign_error="$calls.foreign-error"
|
||||
owned_ref="thothii-core:thothctl-0123456789abcdef-candidate"
|
||||
foreign_ref="thothii-core:thothctl-fedcba9876543210-candidate"
|
||||
owned_ref="thothii-core:tht-0123456789abcdef-candidate"
|
||||
foreign_ref="thothii-core:tht-fedcba9876543210-candidate"
|
||||
|
||||
if ! declare -F task13_remove_transaction_image >/dev/null; then
|
||||
rm -f "$calls" "$foreign_error"
|
||||
@@ -1478,7 +1478,7 @@ task13_self_test_public_timeout_contract() {
|
||||
"$root/scripts/unified-deployment-smoke.sh" \
|
||||
|| task13_fail "direct unified smoke invocation lacks an internal supervisor"
|
||||
grep -Eq 'task13_supervise[[:space:]].*task13_smoke_main[[:space:]]+update' \
|
||||
"$root/scripts/thothctl-update-smoke.sh" \
|
||||
"$root/scripts/tht-update-smoke.sh" \
|
||||
|| task13_fail "direct update smoke invocation lacks an internal supervisor"
|
||||
grep -Eq 'task13_supervise[[:space:]].*task13_internal_semantic_smoke_main' \
|
||||
"$root/scripts/internal-semantic-smoke.sh" \
|
||||
@@ -1562,7 +1562,7 @@ task13_self_test_source_contract() {
|
||||
registry_function='task13_start_''registry'
|
||||
if rg -n 'docker[[:space:]]+(system[[:space:]]+)?prune' \
|
||||
"$root/scripts/unified-deployment-smoke.sh" \
|
||||
"$root/scripts/thothctl-update-smoke.sh" \
|
||||
"$root/scripts/tht-update-smoke.sh" \
|
||||
"$root/scripts/internal-semantic-smoke.sh" >/dev/null; then
|
||||
task13_fail "Task 13 smoke scripts must never prune global Docker state"
|
||||
fi
|
||||
@@ -1577,8 +1577,8 @@ task13_self_test_source_contract() {
|
||||
|| task13_fail "the bad rollback candidate must be an immutable digest reference"
|
||||
grep -Eq 'timeout .*scripts/unified-deployment-smoke\.sh' "$workflow" \
|
||||
|| task13_fail "CI lacks an outer timeout for the unified deployment smoke"
|
||||
grep -Eq 'timeout .*scripts/thothctl-update-smoke\.sh' "$workflow" \
|
||||
|| task13_fail "CI lacks an outer timeout for the thothctl update smoke"
|
||||
grep -Eq 'timeout .*scripts/tht-update-smoke\.sh' "$workflow" \
|
||||
|| task13_fail "CI lacks an outer timeout for the tht update smoke"
|
||||
uses_count="$(grep -Ec '^[[:space:]]+uses:' "$workflow")"
|
||||
pinned_uses_count="$(grep -Ec '^[[:space:]]+uses: [^[:space:]]+@[0-9a-f]{40}([[:space:]]|$)' "$workflow")"
|
||||
[[ "$uses_count" -gt 0 && "$uses_count" -eq "$pinned_uses_count" ]] \
|
||||
@@ -1697,8 +1697,8 @@ task13_initialize() {
|
||||
TASK13_PROFILE="local"
|
||||
TASK13_INSTALLATION="$TASK13_TMP/thothii-installation.yaml"
|
||||
TASK13_PROJECT="thothii-$(task13_sha256_text "$TASK13_INSTALLATION" | cut -c1-12)"
|
||||
TASK13_CONTROL_DIR="$TASK13_ROOT/.thothctl/$TASK13_PROJECT"
|
||||
[[ ! -e "$TASK13_CONTROL_DIR" ]] || task13_fail "unique thothctl control directory already exists"
|
||||
TASK13_CONTROL_DIR="$TASK13_ROOT/.tht/$TASK13_PROJECT"
|
||||
[[ ! -e "$TASK13_CONTROL_DIR" ]] || task13_fail "unique tht control directory already exists"
|
||||
TASK13_CURRENT_IMAGE_OVERRIDE="$TASK13_CONTROL_DIR/current-image.yaml"
|
||||
TASK13_UPDATE_STATE="$TASK13_CONTROL_DIR/update-state.json"
|
||||
TASK13_REMOTE="$TASK13_TMP/remote.git"
|
||||
@@ -1711,7 +1711,7 @@ task13_initialize() {
|
||||
TASK13_PI_MODELS="$TASK13_TMP/models.json"
|
||||
TASK13_PI_SETTINGS="$TASK13_TMP/pi-settings.json"
|
||||
TASK13_LLM_SERVER="$TASK13_TMP/fake-llm.mjs"
|
||||
TASK13_THOTHCTL_DIR="$TASK13_TMP/thothctl"
|
||||
TASK13_THT_DIR="$TASK13_TMP/tht"
|
||||
TASK13_LLM_CONTAINER="$TASK13_PROJECT-llm"
|
||||
TASK13_BAD_CANDIDATE_CONTAINER="$TASK13_PROJECT-bad-candidate"
|
||||
TASK13_CORE_IMAGE="task13-core-$TASK13_RUN_ID:local"
|
||||
@@ -1748,7 +1748,7 @@ task13_smoke_main() {
|
||||
task13_write_fixture_files
|
||||
task13_write_environment /fixtures/remote.git
|
||||
task13_seed_registry
|
||||
task13_build_thothctl
|
||||
task13_build_tht
|
||||
task13_start_stack
|
||||
task13_assert_project_ownership
|
||||
task13_assert_built_image_ownership
|
||||
|
||||
@@ -768,7 +768,7 @@ verify_local_guide() {
|
||||
"Clone and verify LF" \
|
||||
"Create the local operator files" \
|
||||
"Address external services" \
|
||||
"Build ThothII and thothctl" \
|
||||
"Build ThothII and tht" \
|
||||
"Start and verify" \
|
||||
"Update an installation" \
|
||||
"Back up and restore" \
|
||||
@@ -783,8 +783,8 @@ verify_local_guide() {
|
||||
"container 127.0.0.1" \
|
||||
"bash scripts/build-local.sh" \
|
||||
"scripts/build-local.ps1" \
|
||||
"bash scripts/build-thothctl.sh" \
|
||||
"thothctl --installation" \
|
||||
"bash scripts/build-tht.sh" \
|
||||
"tht --installation" \
|
||||
"curl --fail http://127.0.0.1:8080/health" \
|
||||
"http://127.0.0.1:8080" \
|
||||
"git pull --ff-only" \
|
||||
@@ -856,8 +856,8 @@ requirePattern("POSIX source update does not fail closed: Pi status", updateShel
|
||||
/if ! RUNNING_PI_VERSION="\$\("\$THTCTL" --installation "\$INSTALLATION" pi status\)"; then/);
|
||||
requirePattern("POSIX source update does not fail closed: local build", updateShell,
|
||||
/if ! bash scripts\/build-local\.sh; then/);
|
||||
requirePattern("POSIX source update does not fail closed: thothctl build", updateShell,
|
||||
/if ! bash scripts\/build-thothctl\.sh; then/);
|
||||
requirePattern("POSIX source update does not fail closed: tht build", updateShell,
|
||||
/if ! bash scripts\/build-tht\.sh; then/);
|
||||
requirePattern("POSIX source update lacks the same-version/no-selector path", updateShell,
|
||||
/if \[\[ "\$NEXT_PI_VERSION" == "\$RUNNING_PI_VERSION" \]\]; then[\s\S]*"\$USES_BASE_CORE" == true[\s\S]*TRANSACTIONAL_PI_UPDATE=false/);
|
||||
for (const [label, pattern] of [
|
||||
@@ -886,7 +886,7 @@ for (const [command, step] of [
|
||||
["$InstallationStatus = @(& $THTCTL --installation $INSTALLATION status)", "installation status"],
|
||||
["$RunningPiStatus = (& $THTCTL --installation $INSTALLATION pi status)", "Pi status"],
|
||||
["powershell -ExecutionPolicy Bypass -File scripts/build-local.ps1", "local image build"],
|
||||
["& \"C:\\Program Files\\Git\\bin\\bash.exe\" scripts/build-thothctl.sh", "thothctl build"],
|
||||
["& \"C:\\Program Files\\Git\\bin\\bash.exe\" scripts/build-tht.sh", "tht build"],
|
||||
["curl.exe --fail --silent --show-error http://127.0.0.1:8080/health", "frontend health check"],
|
||||
["curl.exe --fail --silent --show-error http://127.0.0.1:8787/health", "core health check"],
|
||||
["$FinalPiStatus = (& $THTCTL --installation $INSTALLATION pi status)", "final Pi status"],
|
||||
@@ -942,18 +942,18 @@ NODE
|
||||
'exit 0' >"$update_fixture/bin/bash"
|
||||
printf '%s\n' \
|
||||
'#!/bin/sh' \
|
||||
'printf "thothctl %s\n" "$*" >>"$CALLS"' \
|
||||
'printf "tht %s\n" "$*" >>"$CALLS"' \
|
||||
'case " $* " in' \
|
||||
' *" pi status "*) [ "$FAIL_STEP" != status ] || exit 7; printf "Pi version: 0.80.3\n" ;;' \
|
||||
' *" status "*) printf "[{\"Service\":\"core\",\"Image\":\"thothii-core:local\"}]\n" ;;' \
|
||||
'esac' \
|
||||
'exit 0' >"$update_fixture/bin/thothctl"
|
||||
'exit 0' >"$update_fixture/bin/tht"
|
||||
printf '%s\n' \
|
||||
'#!/bin/sh' \
|
||||
'printf "curl %s\n" "$*" >>"$CALLS"' \
|
||||
'exit 0' >"$update_fixture/bin/curl"
|
||||
chmod 0700 "$update_fixture/bin/git" "$update_fixture/bin/bash" \
|
||||
"$update_fixture/bin/thothctl" "$update_fixture/bin/curl"
|
||||
"$update_fixture/bin/tht" "$update_fixture/bin/curl"
|
||||
|
||||
for fixture_step in clean dirty pull status build; do
|
||||
calls="$update_fixture/calls-$fixture_step"
|
||||
@@ -963,7 +963,7 @@ NODE
|
||||
(
|
||||
cd "$update_fixture/project"
|
||||
env PATH="$update_fixture/bin:$PATH" CALLS="$calls" FAIL_STEP="$fixture_step" \
|
||||
THTCTL="$update_fixture/bin/thothctl" INSTALLATION="$update_fixture/installation.yaml" \
|
||||
THTCTL="$update_fixture/bin/tht" INSTALLATION="$update_fixture/installation.yaml" \
|
||||
/bin/bash "$update_script"
|
||||
) >"$output" 2>&1
|
||||
status=$?
|
||||
@@ -978,7 +978,7 @@ NODE
|
||||
return 1
|
||||
fi
|
||||
grep -Fq 'bash scripts/build-local.sh' "$calls" || return 1
|
||||
grep -Fq 'thothctl --installation ' "$calls" || return 1
|
||||
grep -Fq 'tht --installation ' "$calls" || return 1
|
||||
else
|
||||
[[ $status -ne 0 ]] || { echo "$fixture_step source failure fixture was accepted" >&2; return 1; }
|
||||
if grep -Fq 'Built source revision:' "$output"; then
|
||||
@@ -1131,13 +1131,13 @@ NODE
|
||||
|
||||
verify_pi_management_guide() {
|
||||
local guide="$root/docs/install/pi-management.md"
|
||||
local lifecycle_contract="$root/docs/contracts/thothctl-pi.md"
|
||||
local lifecycle_contract="$root/docs/contracts/tht-pi.md"
|
||||
[[ -f "$guide" ]] || {
|
||||
echo "missing Pi management guide: docs/install/pi-management.md" >&2
|
||||
return 1
|
||||
}
|
||||
[[ -f "$lifecycle_contract" ]] || {
|
||||
echo "missing Pi lifecycle contract: docs/contracts/thothctl-pi.md" >&2
|
||||
echo "missing Pi lifecycle contract: docs/contracts/tht-pi.md" >&2
|
||||
return 1
|
||||
}
|
||||
require_text "$lifecycle_contract" "Pi lifecycle contract" \
|
||||
@@ -1192,7 +1192,7 @@ const marker = "## Direct support access";
|
||||
const start = source.indexOf(marker);
|
||||
const support = start < 0 ? "" : source.slice(start, source.indexOf("\n## ", start + marker.length) < 0
|
||||
? source.length : source.indexOf("\n## ", start + marker.length));
|
||||
for (const token of ["unsupported", "thothctl", "pi status", "pi doctor", "pi test", "pi logs"]) {
|
||||
for (const token of ["unsupported", "tht", "pi status", "pi doctor", "pi test", "pi logs"]) {
|
||||
if (!support.toLowerCase().includes(token.toLowerCase())) {
|
||||
throw new Error(`direct support section lacks installation-aware diagnostic: ${token}`);
|
||||
}
|
||||
@@ -1214,7 +1214,7 @@ verify_server_guide() {
|
||||
"Address co-resident external services" \
|
||||
"Prepare operator files and secrets" \
|
||||
"Build locally or select pinned images" \
|
||||
"Install thothctl" \
|
||||
"Install tht" \
|
||||
"Start and verify readiness" \
|
||||
"Configure TLS and upstream authentication" \
|
||||
"Operate Pi, drain, and roll back" \
|
||||
@@ -1228,7 +1228,7 @@ verify_server_guide() {
|
||||
"thothii-ops" \
|
||||
"-m 2770 /srv/thothii/operator" \
|
||||
"chmod 0660 /srv/thothii/operator/server.env" \
|
||||
"THT_THOTHCTL_OUTPUT_DIRECTORY=/srv/thothii/operator/build-output" \
|
||||
"THT_THT_OUTPUT_DIRECTORY=/srv/thothii/operator/build-output" \
|
||||
"/srv/thothii" \
|
||||
"example operator root" \
|
||||
"/run/secrets" \
|
||||
@@ -1243,8 +1243,8 @@ verify_server_guide() {
|
||||
"embedding" \
|
||||
"bash scripts/build-local.sh" \
|
||||
"@sha256:" \
|
||||
"bash scripts/build-thothctl.sh" \
|
||||
"thothctl --installation" \
|
||||
"bash scripts/build-tht.sh" \
|
||||
"tht --installation" \
|
||||
"sessions migrate --yes" \
|
||||
'"pending":[]' \
|
||||
'"drifted":[]' \
|
||||
@@ -1325,7 +1325,7 @@ if (/session-migrate:[\s\S]{0,180}image:\s*thothii-core:local/.test(source) &&
|
||||
throw new Error("server pinned migration image must equal the pinned core image");
|
||||
}
|
||||
if (/```(?:sh|bash)\n[\s\S]*?\bdocker compose\s+(?:up|stop|down|restart|pull|build)\b[\s\S]*?```/i.test(source)) {
|
||||
throw new Error("server lifecycle must use thothctl, not raw Docker Compose");
|
||||
throw new Error("server lifecycle must use tht, not raw Docker Compose");
|
||||
}
|
||||
NODE
|
||||
echo "server installation guide contract passed"
|
||||
@@ -1735,7 +1735,7 @@ verify_manual() {
|
||||
)
|
||||
else
|
||||
expected_steps=(
|
||||
'THTCTL=/srv/thothii/operator/thothctl'
|
||||
'THTCTL=/srv/thothii/operator/tht'
|
||||
'INSTALLATION=/srv/thothii/operator/thothii-installation.yaml'
|
||||
'"$THTCTL" --installation "$INSTALLATION" start'
|
||||
'"$THTCTL" --installation "$INSTALLATION" doctor'
|
||||
|
||||
Reference in New Issue
Block a user