Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -334,20 +334,22 @@ jobs:
digest="$(printf '%s' "$OAC_CORE_KEY" | sha256sum | cut -d' ' -f1)"
printf '%s' "$OAC_DATABASE_PASSWORD" > "$work/database.password"
printf '%s' "$OAC_CREDENTIAL_KEY" > "$work/credential.key"
printf '%s' "$OAC_INSTALLATION_ID" > "$work/installation.id"
printf '["%s"]\n' "$digest" > "$work/core-key-digests.json"
printf '%s' "$OAC_CORE_KEY" > "$work/core.key"

kubectl create secret generic oac-core-secrets -n "$NS" \
--from-file="database.password=$work/database.password" \
--from-file="credential.key=$work/credential.key" \
--from-file="installation.id=$work/installation.id" \
--from-file="core-key-digests.json=$work/core-key-digests.json" \
--dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic oac-web-core-key -n "$NS" \
--from-file="core.key=$work/core.key" \
--dry-run=client -o yaml | kubectl apply -f -

# shellcheck disable=SC2016 # envsubst takes the variable list literally
envsubst '$OAC_PUBLIC_URL $OAC_INSTALLATION_ID $OAC_DATABASE_URL' \
envsubst '$OAC_PUBLIC_URL $OAC_DATABASE_URL' \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve identity substitution for older deployment templates

When source_branch/ref selects an earlier release, the checkout at .github/workflows/deploy.yml:187-190 replaces the working tree with that revision, so this command renders its older core-env.yaml.tpl, which still contains ${OAC_INSTALLATION_ID}. GNU envsubst --help confirms that with a SHELL-FORMAT, only the listed variables are substituted; therefore the ConfigMap retains the literal placeholder. Older Core versions reject it as a non-UUID, while the immediately preceding file-only Core starts without an installation identity and encounters the deployment conflict. This breaks the documented rollback flow in deploy/kubernetes/README.md:35; keep OAC_INSTALLATION_ID in the substitution whitelist even though the current template no longer uses it.

Useful? React with 👍 / 👎.

< deploy/kubernetes/prod/core-env.yaml.tpl > "$work/core-env.yaml"
for name in OAC_HARNESSES OAC_DEFAULT_HARNESS OAC_EXECUTION_CONCURRENCY \
OAC_WRITE_AUDIT_RETENTION OAC_LOG_LEVEL; do
Expand All @@ -359,7 +361,7 @@ jobs:
# Core and Web read their environment and secret files once at startup.
# This digest enters both Pod templates, so a settings or secret change
# replaces the Pods even when the images are unchanged.
digest_input="$(cat "$work/core-env.yaml"; printf '%s' "$digest$OAC_DATABASE_PASSWORD$OAC_CREDENTIAL_KEY")"
digest_input="$(cat "$work/core-env.yaml"; printf '%s' "$digest$OAC_DATABASE_PASSWORD$OAC_CREDENTIAL_KEY$OAC_INSTALLATION_ID")"
printf 'digest=%s\n' "$(printf '%s' "$digest_input" | sha256sum | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"

- name: Roll out Core
Expand Down
2 changes: 1 addition & 1 deletion deploy/kubernetes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Restrict the repository’s `production` GitHub Environment to deployments from
| `OAC_REGISTRY_HOST` | Registry host for `docker login` and the pull Secret. Optional; the host of `OAC_REGISTRY` by default |
| `OAC_PUBLIC_URL` | The canonical HTTPS origin, such as `https://core.example`, with no path, query or fragment. Core derives the daemon WebSocket address, the sandbox `core_url` and the self-hosted `remote_url` from it, and Web serves only this origin. Without it Core executes no Session |
| `OAC_DATABASE_URL` | `postgres://USER@HOST:PORT/DATABASE`, with `sslmode` and any `pool_*` parameter in the query and no password |
| `OAC_INSTALLATION_ID` | A canonical lowercase UUID, generated once with `uuidgen \| tr 'A-Z' 'a-z'`. Core refuses an ID other than the one its database recorded, so it belongs to the database: keep the two together and restore them together |
| `OAC_INSTALLATION_ID` | A canonical lowercase UUID, generated once with `uuidgen \| tr 'A-Z' 'a-z'`. The workflow writes it to `installation.id` in the Core Secret; Core reads `/run/oac/installation.id` through `OAC_INSTALLATION_ID_FILE`. Core refuses an ID other than the one its database recorded, so it belongs to the database: keep the two together and restore them together |
| `OAC_NAMESPACE` | Existing namespace; `openagentcore` by default |
| `OAC_STORAGE_CLASS`, `OAC_STATE_SIZE` | StorageClass and size of the required Core state volume. See [the state volume](#the-state-volume). `10Gi` by default |
| `OAC_CLUSTER_UID` | UID of the target cluster’s `kube-system` namespace. The workflow verifies it before applying resources |
Expand Down
2 changes: 1 addition & 1 deletion deploy/kubernetes/prod/core-env.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ metadata:
data:
OAC_ADDR: ":8091"
OAC_PUBLIC_URL: "${OAC_PUBLIC_URL}"
OAC_INSTALLATION_ID: "${OAC_INSTALLATION_ID}"
OAC_INSTALLATION_ID_FILE: "/run/oac/installation.id"

OAC_DATABASE_URL: "${OAC_DATABASE_URL}"
OAC_DATABASE_PASSWORD_FILE: "/run/oac/database.password"
Expand Down
2 changes: 1 addition & 1 deletion deploy/kubernetes/prod/core.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ spec:
chmod 700 /state/e2b
chown 65532:65532 /run/oac
chmod 700 /run/oac
for name in database.password credential.key core-key-digests.json; do
for name in database.password credential.key core-key-digests.json installation.id; do
install -o 65532 -g 65532 -m 0400 "/run/oac-source/$name" "/run/oac/$name"
done
securityContext:
Expand Down
Loading