diff --git a/.dockerignore b/.dockerignore index ab6a1f8..05ec59a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,3 +2,4 @@ !Dockerfile !docker/entrypoint.sh !target/release/omnigraph-server +!target/release/omnigraph diff --git a/Dockerfile b/Dockerfile index e49a6c7..ca22a93 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,9 +11,13 @@ RUN groupadd --system omnigraph \ && useradd --system --gid omnigraph --create-home --home-dir /var/lib/omnigraph omnigraph COPY target/release/omnigraph-server /usr/local/bin/omnigraph-server +# The CLI ships in the image so the cluster day-2 loop (cluster +# apply/approve/status, data loads by explicit URI) runs in-container via +# `docker exec` / ECS exec / `railway shell` — no omnigraph.yaml required. +COPY target/release/omnigraph /usr/local/bin/omnigraph COPY docker/entrypoint.sh /usr/local/bin/omnigraph-entrypoint -RUN chmod 0755 /usr/local/bin/omnigraph-server /usr/local/bin/omnigraph-entrypoint +RUN chmod 0755 /usr/local/bin/omnigraph-server /usr/local/bin/omnigraph /usr/local/bin/omnigraph-entrypoint ENV OMNIGRAPH_BIND=0.0.0.0:8080 diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index a5fb275..98587aa 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -9,6 +9,17 @@ fi bind="${OMNIGRAPH_BIND:-0.0.0.0:8080}" +# Cluster mode first, and exclusive (the server's mode-inference rule 0): +# a deployment serves from cluster state XOR omnigraph.yaml, never a merge. +# Fail fast here with the same contract the server enforces. +if [ -n "${OMNIGRAPH_CLUSTER:-}" ]; then + if [ -n "${OMNIGRAPH_TARGET_URI:-}" ] || [ -n "${OMNIGRAPH_CONFIG:-}" ] || [ -n "${OMNIGRAPH_TARGET:-}" ]; then + echo "OMNIGRAPH_CLUSTER is an exclusive boot source; unset OMNIGRAPH_TARGET_URI/OMNIGRAPH_CONFIG/OMNIGRAPH_TARGET" >&2 + exit 64 + fi + exec "$SERVER_BIN" --cluster "${OMNIGRAPH_CLUSTER}" --bind "${bind}" +fi + # URI comes from the env var (the positional arg wins over any config # `graphs` block in resolve_target_uri). OMNIGRAPH_CONFIG, when also set, # is forwarded as --config purely to supply a policy file — the two @@ -28,6 +39,8 @@ fi cat >&2 <<'EOF' omnigraph-server container startup requires one of: + - OMNIGRAPH_CLUSTER (serve a cluster directory's applied revision; + exclusive — cannot combine with the others) - OMNIGRAPH_TARGET_URI - OMNIGRAPH_CONFIG diff --git a/docker/entrypoint_test.sh b/docker/entrypoint_test.sh index 01fbee2..3ee668f 100755 --- a/docker/entrypoint_test.sh +++ b/docker/entrypoint_test.sh @@ -58,6 +58,26 @@ got=$(sh "$ep" some-uri --bind 1.2.3.4:9 --extra) check "explicit args passthrough" \ "ARGS: some-uri --bind 1.2.3.4:9 --extra" "$got" +got=$(OMNIGRAPH_CLUSTER="/var/lib/omnigraph/company-brain" OMNIGRAPH_BIND="0.0.0.0:8080" sh "$ep") +check "CLUSTER only (Phase 5 mode switch)" \ + "ARGS: --cluster /var/lib/omnigraph/company-brain --bind 0.0.0.0:8080" "$got" + +# Exclusivity: OMNIGRAPH_CLUSTER refuses every combination, exit 64. +for combo in "OMNIGRAPH_TARGET_URI=s3://b/g" "OMNIGRAPH_CONFIG=/etc/o.yaml" "OMNIGRAPH_TARGET=active"; do + if out=$(env "$combo" OMNIGRAPH_CLUSTER="/data/cluster" sh "$ep" 2>&1); then + echo "FAIL: CLUSTER + ${combo%%=*} unexpectedly succeeded: $out" + fail=1 + else + status=$? + if [ "$status" -ne 64 ]; then + echo "FAIL: CLUSTER + ${combo%%=*} exited $status, want 64" + fail=1 + else + echo "ok: CLUSTER + ${combo%%=*} refused (64)" + fi + fi +done + if [ "$fail" -ne 0 ]; then echo "entrypoint_test: FAILED" exit 1