feat: profile-gated workspace-maintenance service and connector override generator (P2)
This commit is contained in:
@@ -55,6 +55,60 @@ services:
|
||||
networks:
|
||||
- thothii
|
||||
|
||||
workspace-maintenance:
|
||||
image: thothii-core:local
|
||||
profiles: [workspace-maintenance]
|
||||
pull_policy: never
|
||||
entrypoint: ["/usr/bin/tini", "--", "/app/docker/workspace-maintenance-entrypoint.sh"]
|
||||
environment:
|
||||
THT_HARNESS_DIR: /app/harness
|
||||
THT_BIN: /opt/venv/bin/tht
|
||||
THT_DATA_ROOT: /data
|
||||
THT_WORKSPACE_REGISTRY_ROOT: /data/workspace-registry
|
||||
THT_WORKSPACE_GIT_REMOTE: ${THT_WORKSPACE_GIT_REMOTE:?set THT_WORKSPACE_GIT_REMOTE}
|
||||
THT_WORKSPACE_GIT_BRANCH: ${THT_WORKSPACE_GIT_BRANCH:-main}
|
||||
THT_WORKSPACE_INSTALLATION_ID: ${THT_WORKSPACE_INSTALLATION_ID:-local}
|
||||
THT_WORKSPACE_SECRET_ROOTS: /run/secrets
|
||||
THT_SECRETS_FILE: /run/secrets/thothii.secrets
|
||||
THT_DB_NAME: ${THT_DB_NAME:-}
|
||||
THT_DWH_REST_URL: ${THT_DWH_REST_URL:-}
|
||||
THT_LLM_URL: ${THT_LLM_URL:-}
|
||||
THT_INTERNAL_QDRANT_URL: http://qdrant:6333
|
||||
THT_INTERNAL_EMBEDDING_URL: http://embedding:11434
|
||||
THT_INTERNAL_EMBEDDING_MODEL: qwen3-embedding:0.6b
|
||||
THT_INTERNAL_EMBEDDING_DIMENSIONS: "1024"
|
||||
HOME: /tmp/thoth
|
||||
AWS_ACCESS_KEY_ID: ""
|
||||
AWS_SECRET_ACCESS_KEY: ""
|
||||
AWS_SESSION_TOKEN: ""
|
||||
AWS_PROFILE: ""
|
||||
AWS_DEFAULT_PROFILE: ""
|
||||
AWS_CONFIG_FILE: /dev/null
|
||||
AWS_SHARED_CREDENTIALS_FILE: /dev/null
|
||||
volumes:
|
||||
- type: volume
|
||||
source: workspace-registry
|
||||
target: /data/workspace-registry
|
||||
read_only: true
|
||||
- type: volume
|
||||
source: sessions
|
||||
target: /data/sessions
|
||||
secrets:
|
||||
- source: thothii_secrets
|
||||
target: thothii.secrets
|
||||
user: "10001:10001"
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp:rw,noexec,nosuid,nodev,size=64m,mode=1777
|
||||
- /var/tmp:rw,noexec,nosuid,nodev,size=32m,mode=1777
|
||||
cap_drop:
|
||||
- ALL
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
restart: "no"
|
||||
networks:
|
||||
- thothii
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: .
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Select this override only for an HTTPS Git remote. The separate CA mount keeps TLS validation
|
||||
# explicit; neither host-only source file nor its contents belongs in the base Compose contract.
|
||||
# Active-snapshot workspace-maintenance operations intentionally receive no Git credential mounts.
|
||||
x-thoth-git-transport: https
|
||||
|
||||
services:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Select this override only for an SSH Git remote. The host-only source files must be absolute,
|
||||
# normalized paths; strict host-key checking is mandatory for registry pull and publish.
|
||||
# Active-snapshot workspace-maintenance operations intentionally receive no Git credential mounts.
|
||||
x-thoth-git-transport: ssh
|
||||
|
||||
services:
|
||||
|
||||
@@ -11,3 +11,8 @@ services:
|
||||
ports:
|
||||
- "127.0.0.1:${THOTH_HTTP_PORT:-8080}:8080"
|
||||
restart: "no"
|
||||
|
||||
workspace-maintenance:
|
||||
environment:
|
||||
THT_WORKSPACE_INSTALLATION_ID: local
|
||||
restart: "no"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Retired for operator use: this profile remains only as a non-public engine-fixture path.
|
||||
# It exercises the legacy preprocessing fixtures and must not become a second operator interface.
|
||||
services:
|
||||
preprocess-evidence:
|
||||
image: thothii-core:local
|
||||
|
||||
@@ -35,3 +35,18 @@ services:
|
||||
ports:
|
||||
- "${THOTH_SERVER_BIND:-127.0.0.1}:${THOTH_HTTP_PORT:-8080}:8080"
|
||||
restart: unless-stopped
|
||||
|
||||
|
||||
workspace-maintenance:
|
||||
environment:
|
||||
THT_DATA_ROOT: /data
|
||||
THT_WORKSPACE_INSTALLATION_ID: server
|
||||
volumes: !override
|
||||
- type: bind
|
||||
source: ${THT_DATA_ROOT:?set THT_DATA_ROOT}/sessions
|
||||
target: /data/sessions
|
||||
- type: bind
|
||||
source: ${THT_WORKSPACE_REGISTRY_ROOT:?set THT_WORKSPACE_REGISTRY_ROOT}
|
||||
target: /data/workspace-registry
|
||||
read_only: true
|
||||
restart: "no"
|
||||
|
||||
+12
-6
@@ -33,10 +33,16 @@ LABEL org.opencontainers.image.title="thothii-core" \
|
||||
io.thothii.pi.version="${PI_VERSION}"
|
||||
|
||||
# Runtime tools
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl ca-certificates ripgrep fd-find tini git openssh-client \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& ln -s /usr/bin/fdfind /usr/local/bin/fd
|
||||
RUN set -eux; \
|
||||
runtime_packages="curl ca-certificates ripgrep fd-find tini git openssh-client"; \
|
||||
if ! command -v flock >/dev/null 2>&1; then \
|
||||
runtime_packages="$runtime_packages util-linux"; \
|
||||
fi; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends $runtime_packages; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
command -v flock >/dev/null 2>&1; \
|
||||
ln -s /usr/bin/fdfind /usr/local/bin/fd
|
||||
|
||||
# Node 22 + npm copiati dall'immagine ufficiale (stesso Debian bookworm → binario compatibile)
|
||||
COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node
|
||||
@@ -91,10 +97,10 @@ ENV PATH="/opt/venv/bin:/usr/local/bin:$PATH" \
|
||||
HOME=/home/thoth
|
||||
|
||||
COPY scripts/verify-line-endings.sh /usr/local/bin/verify-line-endings
|
||||
COPY docker/core-entrypoint.sh docker/session-migrate.sh docker/ensure-pi-trust.mjs docker/embedding-model-init.sh /app/docker/
|
||||
COPY docker/core-entrypoint.sh docker/workspace-maintenance-entrypoint.sh docker/session-migrate.sh docker/ensure-pi-trust.mjs docker/embedding-model-init.sh /app/docker/
|
||||
COPY docker/smoke/core-smoke.sh /app/docker/smoke/core-smoke.sh
|
||||
RUN /usr/local/bin/verify-line-endings /app/docker \
|
||||
&& chmod +x /app/docker/core-entrypoint.sh /app/docker/session-migrate.sh /app/docker/embedding-model-init.sh /app/docker/smoke/core-smoke.sh
|
||||
&& chmod +x /app/docker/core-entrypoint.sh /app/docker/workspace-maintenance-entrypoint.sh /app/docker/session-migrate.sh /app/docker/embedding-model-init.sh /app/docker/smoke/core-smoke.sh
|
||||
|
||||
WORKDIR /app/backend
|
||||
USER thoth
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
exec node /app/backend/dist/workspace-maintenance.js "$@"
|
||||
@@ -3,7 +3,10 @@
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 --bindings-env <workspace-bindings.env> --operator-env <operator.env> --output <override.yaml>" >&2
|
||||
cat >&2 <<'EOF'
|
||||
usage: $0 --bindings-env <workspace-bindings.env> --operator-env <operator.env> --output <override.yaml> \
|
||||
[--service <core|workspace-maintenance>]... [--role <all|dwh|evidence>]...
|
||||
EOF
|
||||
exit 2
|
||||
}
|
||||
|
||||
@@ -40,20 +43,59 @@ read_env_value() {
|
||||
printf '%s' "$result"
|
||||
}
|
||||
|
||||
binding_matches_roles() {
|
||||
local name="$1" role
|
||||
for role in "${roles[@]}"; do
|
||||
case "$role" in
|
||||
all) return 0 ;;
|
||||
dwh)
|
||||
[[ "$name" == *"_DWH_"* ]] && return 0
|
||||
;;
|
||||
evidence)
|
||||
[[ "$name" == *"_EVIDENCE_"* ]] && return 0
|
||||
;;
|
||||
*)
|
||||
echo "unsupported role filter: $role" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
bindings_env=""
|
||||
operator_env=""
|
||||
output=""
|
||||
services=()
|
||||
roles=()
|
||||
while (($#)); do
|
||||
case "$1" in
|
||||
--bindings-env) bindings_env="${2:-}"; shift 2 ;;
|
||||
--operator-env) operator_env="${2:-}"; shift 2 ;;
|
||||
--output) output="${2:-}"; shift 2 ;;
|
||||
--service) services+=("${2:-}"); shift 2 ;;
|
||||
--role)
|
||||
roles+=("$(printf '%s' "${2:-}" | tr '[:upper:]' '[:lower:]')")
|
||||
shift 2
|
||||
;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -f "$bindings_env" && -f "$operator_env" && -n "$output" ]] || usage
|
||||
[[ ! -e "$output" ]] || { echo "refusing to overwrite connector override: $output" >&2; exit 2; }
|
||||
((${#services[@]})) || services=(core)
|
||||
((${#roles[@]})) || roles=(all)
|
||||
|
||||
for service in "${services[@]}"; do
|
||||
case "$service" in
|
||||
core|workspace-maintenance) ;;
|
||||
*)
|
||||
echo "unsupported service target: $service" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
names=()
|
||||
targets=()
|
||||
@@ -64,6 +106,7 @@ while IFS=$'\t' read -r name target; do
|
||||
echo "retired semantic secret binding is not supported: ${name%_FILE}_SOURCE" >&2
|
||||
exit 2
|
||||
fi
|
||||
binding_matches_roles "$name" || continue
|
||||
[[ "$target" =~ ^/run/secrets/[A-Za-z0-9][A-Za-z0-9_.-]*$ && "$target" != *..* ]] || {
|
||||
echo "invalid connector secret target for $name: $target" >&2
|
||||
exit 2
|
||||
@@ -101,20 +144,25 @@ done < <(
|
||||
' "$bindings_env"
|
||||
)
|
||||
|
||||
((${#names[@]})) || { echo "no THT_WS_*_FILE connector bindings found in $bindings_env" >&2; exit 2; }
|
||||
((${#names[@]})) || {
|
||||
echo "no THT_WS_*_FILE connector bindings matched the selected roles in $bindings_env" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
{
|
||||
printf '%s\n' '# Generated by scripts/generate-connector-secrets-override.sh; keep this file untracked.'
|
||||
printf '%s\n' \
|
||||
'services:' \
|
||||
' core:' \
|
||||
' env_file:' \
|
||||
' - path: ${THT_WORKSPACE_BINDINGS_ENV_FILE:?set THT_WORKSPACE_BINDINGS_ENV_FILE}' \
|
||||
' required: true' \
|
||||
' secrets:'
|
||||
for ((index = 0; index < ${#names[@]}; index += 1)); do
|
||||
printf ' - source: connector_secret_%d\n' "$((index + 1))"
|
||||
printf ' target: %s\n' "${targets[index]}"
|
||||
printf '%s\n' 'services:'
|
||||
for service in "${services[@]}"; do
|
||||
printf ' %s:\n' "$service"
|
||||
printf '%s\n' \
|
||||
' env_file:' \
|
||||
' - path: ${THT_WORKSPACE_BINDINGS_ENV_FILE:?set THT_WORKSPACE_BINDINGS_ENV_FILE}' \
|
||||
' required: true' \
|
||||
' secrets:'
|
||||
for ((index = 0; index < ${#names[@]}; index += 1)); do
|
||||
printf ' - source: connector_secret_%d\n' "$((index + 1))"
|
||||
printf ' target: %s\n' "${targets[index]}"
|
||||
done
|
||||
done
|
||||
printf '%s\n' '' 'secrets:'
|
||||
for ((index = 0; index < ${#names[@]}; index += 1)); do
|
||||
@@ -123,4 +171,5 @@ done < <(
|
||||
done
|
||||
} >"$output"
|
||||
|
||||
printf 'generated %s connector secret mount(s) at %s\n' "${#names[@]}" "$output"
|
||||
printf 'generated %s connector secret mount(s) for %s at %s\n' \
|
||||
"${#names[@]}" "$(IFS=,; printf '%s' "${services[*]}")" "$output"
|
||||
|
||||
Reference in New Issue
Block a user