From d1ab7c24aa257679e3b5855c6bfad8d1ff0c69a2 Mon Sep 17 00:00:00 2001 From: Allan Lin Date: Mon, 31 Aug 2026 10:35:18 -0700 Subject: [PATCH 1/2] Install Codex CLI and wire up file-based auth Install the Codex CLI in the devcontainer image (Layer 6, alongside the Claude install), and provision its credentials the same way as the gcloud/Vertex ones: - create_dev_user.sh prompts for a codex auth.json path and uploads it as the -codex-config secret. - Both deployments mount that secret read-only at ~/.codex/auth.json via subPath, so Codex uses file-based auth while the rest of ~/.codex stays writable. Intended for a static OpenAI API key in auth.json (no token refresh), so the read-only mount is sufficient. --- .devcontainer/Dockerfile | 1 + create_dev_user.sh | 12 ++++++++++++ deployment/deployment-rdma.yml | 8 ++++++++ deployment/deployment.yml | 8 ++++++++ 4 files changed, 29 insertions(+) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index b30a831..6c7143e 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -166,6 +166,7 @@ RUN mkdir -p /build_ray \ # Layer 6: setuptools, uv, Claude, gcc symlinks, git config, sudoers, permissions RUN /home/devuser/miniconda/bin/pip install --no-cache-dir setuptools uv scikit-build \ && curl -fsSL https://claude.ai/install.sh | HOME=/home/devuser bash \ + && curl -fsSL https://chatgpt.com/codex/install.sh | HOME=/home/devuser bash \ && if [ -n "${GCC_SUFFIX}" ]; then \ rm -f /usr/bin/gcc /usr/bin/g++ \ && ln -s "/usr/bin/gcc${GCC_SUFFIX}" /usr/bin/gcc \ diff --git a/create_dev_user.sh b/create_dev_user.sh index 2e976ec..ca74aff 100755 --- a/create_dev_user.sh +++ b/create_dev_user.sh @@ -13,6 +13,7 @@ while true; do read -p "Enter openshift username: " USERNAME read -e -p "Enter ssh private key path for github: " SSH_KEY_PATH read -e -p "Enter gcloud application default credentials path: " GCLOUD_CREDENTIALS + read -e -p "Enter codex auth.json path: " CODEX_AUTH read -e -i "${ANTHROPIC_VERTEX_PROJECT_ID:-}" -p "Enter vertex project ID: " PROJECT_ID NAMESPACE=$(echo "$USERNAME" | tr '[:upper:]' '[:lower:]') @@ -22,6 +23,7 @@ while true; do echo " Username (namespace): $NAMESPACE" echo " SSH private key path: $SSH_KEY_PATH" echo " gcloud credentials: $GCLOUD_CREDENTIALS" + echo " codex auth.json: $CODEX_AUTH" echo " Vertex Project ID: $PROJECT_ID" echo "" read -p "Is this correct? (y/n): " CONFIRM @@ -56,6 +58,16 @@ oc create secret generic $NAMESPACE-gcloud-config \ --namespace=$NAMESPACE \ --from-file=$GCLOUD_CREDENTIALS +# create codex authentication secret (file auth: mounted at ~/.codex/auth.json in +# the pod); if one already exists, delete it first so we upload the latest credentials +if oc get secret $NAMESPACE-codex-config --namespace=$NAMESPACE >/dev/null 2>&1; then + echo "Secret $NAMESPACE-codex-config already exists, deleting it to upload the latest credentials." + oc delete secret $NAMESPACE-codex-config --namespace=$NAMESPACE +fi +oc create secret generic $NAMESPACE-codex-config \ + --namespace=$NAMESPACE \ + --from-file=auth.json=$CODEX_AUTH + # apply the DRA resource templates oc apply -f <(sed "s//$NAMESPACE/g" resourceClaimTemplates/rct_gpu.yml) # inject the vertex project ID env var into the container (reads YAML on stdin, diff --git a/deployment/deployment-rdma.yml b/deployment/deployment-rdma.yml index 693e03c..986cf67 100644 --- a/deployment/deployment-rdma.yml +++ b/deployment/deployment-rdma.yml @@ -33,6 +33,10 @@ spec: secret: secretName: -gcloud-config defaultMode: 0640 + - name: codex-config + secret: + secretName: -codex-config + defaultMode: 0640 - name: pytorch-eco-data persistentVolumeClaim: claimName: pytorch-py3-10- @@ -121,6 +125,10 @@ spec: - name: gcloud-config readOnly: true mountPath: /home/devuser/.config/gcloud + - name: codex-config + readOnly: true + mountPath: /home/devuser/.codex/auth.json + subPath: auth.json - name: bazelrc mountPath: /home/devuser/.bazelrc subPath: .bazelrc diff --git a/deployment/deployment.yml b/deployment/deployment.yml index 81af9af..66905f4 100644 --- a/deployment/deployment.yml +++ b/deployment/deployment.yml @@ -32,6 +32,10 @@ spec: secret: secretName: -gcloud-config defaultMode: 0640 + - name: codex-config + secret: + secretName: -codex-config + defaultMode: 0640 - name: pytorch-eco-data persistentVolumeClaim: claimName: pytorch-- @@ -103,6 +107,10 @@ spec: - name: gcloud-config readOnly: true mountPath: /home/devuser/.config/gcloud + - name: codex-config + readOnly: true + mountPath: /home/devuser/.codex/auth.json + subPath: auth.json - name: bazelrc mountPath: /home/devuser/.bazelrc subPath: .bazelrc From 2140b7972dfc397d97622e08b24de8b5f29eb8fc Mon Sep 17 00:00:00 2001 From: Allan Lin Date: Mon, 31 Aug 2026 10:40:03 -0700 Subject: [PATCH 2/2] Install Codex CLI in the agent and nvshmem devcontainer images too Both images install the Claude CLI in Layer 6; add the Codex install next to it, matching the main Dockerfile. runtime.Dockerfile is left alone since it inherits its tooling from the shared build rather than installing Claude itself. --- .devcontainer/agent.Dockerfile | 1 + .devcontainer/nvshmem.Dockerfile | 1 + 2 files changed, 2 insertions(+) diff --git a/.devcontainer/agent.Dockerfile b/.devcontainer/agent.Dockerfile index 2b186ef..cb91a15 100644 --- a/.devcontainer/agent.Dockerfile +++ b/.devcontainer/agent.Dockerfile @@ -91,6 +91,7 @@ ENV PATH=/home/devuser/miniconda/bin:${PATH} # Layer 6: setuptools, uv, Claude, gcc symlinks, git config, sudoers, permissions RUN /home/devuser/miniconda/bin/pip install --no-cache-dir setuptools uv scikit-build \ && curl -fsSL https://claude.ai/install.sh | HOME=/home/devuser bash \ + && curl -fsSL https://chatgpt.com/codex/install.sh | HOME=/home/devuser bash \ && if [ -n "${GCC_SUFFIX}" ]; then \ rm -f /usr/bin/gcc /usr/bin/g++ \ && ln -s "/usr/bin/gcc${GCC_SUFFIX}" /usr/bin/gcc \ diff --git a/.devcontainer/nvshmem.Dockerfile b/.devcontainer/nvshmem.Dockerfile index 0daa6a1..2fd3150 100644 --- a/.devcontainer/nvshmem.Dockerfile +++ b/.devcontainer/nvshmem.Dockerfile @@ -163,6 +163,7 @@ RUN mkdir -p /build_ray \ # Layer 6: setuptools, uv, Claude, gcc symlinks, git config, sudoers, permissions RUN /home/devuser/miniconda/bin/pip install --no-cache-dir setuptools uv scikit-build \ && curl -fsSL https://claude.ai/install.sh | HOME=/home/devuser bash \ + && curl -fsSL https://chatgpt.com/codex/install.sh | HOME=/home/devuser bash \ && if [ -n "${GCC_SUFFIX}" ]; then \ rm -f /usr/bin/gcc /usr/bin/g++ \ && ln -s "/usr/bin/gcc${GCC_SUFFIX}" /usr/bin/gcc \