ci: switch runner git clones from HTTPS+CF Access to SSH deploy key
This commit is contained in:
@@ -96,17 +96,9 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
|
|||||||
# build containers with its own entrypoint to keep them alive between
|
# build containers with its own entrypoint to keep them alive between
|
||||||
# steps, and overriding it breaks job execution.
|
# steps, and overriding it breaks job execution.
|
||||||
|
|
||||||
# In-cluster git redirect — GKE runners resolve the internal Gitea service
|
# SSH-based git clone init script.
|
||||||
# directly, bypassing Cloudflare Access. This insteadOf rule rewrites any
|
# Sourced before every CI step via BASH_ENV (set in deployment.yaml).
|
||||||
# clone/fetch of the public URL to the in-cluster service URL so CI jobs work
|
# Writes GITEA_SSH_PRIVATE_KEY to ~/.ssh/gitea_key and rewrites HTTPS
|
||||||
# without CF Access headers inside the GKE cluster.
|
# Gitea URLs to SSH so actions/checkout and git clone both use SSH auth.
|
||||||
#
|
COPY git-ssh-init.sh /usr/local/bin/git-ssh-init.sh
|
||||||
# On Legion runners this is overridden at runtime by git-cf-access-init.sh
|
RUN chmod +x /usr/local/bin/git-ssh-init.sh
|
||||||
# (which sets the reverse redirect + CF Access headers). The system-level rule
|
|
||||||
# here is a safe baseline; the init script wins because it runs after.
|
|
||||||
RUN git config --system \
|
|
||||||
url."http://gitea.gitea.svc.cluster.local:3000/".insteadOf \
|
|
||||||
"https://git.neuralplatform.ai/"
|
|
||||||
|
|
||||||
COPY git-cf-access-init.sh /usr/local/bin/git-cf-access-init.sh
|
|
||||||
RUN chmod +x /usr/local/bin/git-cf-access-init.sh
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
labels:
|
labels:
|
||||||
app: gitea-runner
|
app: gitea-runner
|
||||||
annotations:
|
annotations:
|
||||||
config-version: "2026-05-05-gke-gitea-url"
|
config-version: "2026-05-05-ssh-clone"
|
||||||
spec:
|
spec:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
selector:
|
selector:
|
||||||
@@ -19,7 +19,7 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app: gitea-runner
|
app: gitea-runner
|
||||||
annotations:
|
annotations:
|
||||||
config-version: "2026-05-05-gke-gitea-url"
|
config-version: "2026-05-05-ssh-clone"
|
||||||
spec:
|
spec:
|
||||||
securityContext:
|
securityContext:
|
||||||
runAsNonRoot: false
|
runAsNonRoot: false
|
||||||
@@ -52,9 +52,8 @@ spec:
|
|||||||
# /usr/local/bin/git-cf-access-init.sh before every step,
|
# /usr/local/bin/git-cf-access-init.sh before every step,
|
||||||
# which sets up the redirect + headers.
|
# which sets up the redirect + headers.
|
||||||
env:
|
env:
|
||||||
CF_ACCESS_CLIENT_ID: "${CF_ACCESS_CLIENT_ID}"
|
GITEA_SSH_PRIVATE_KEY: "${GITEA_SSH_PRIVATE_KEY}"
|
||||||
CF_ACCESS_CLIENT_SECRET: "${CF_ACCESS_CLIENT_SECRET}"
|
BASH_ENV: "/usr/local/bin/git-ssh-init.sh"
|
||||||
BASH_ENV: "/usr/local/bin/git-cf-access-init.sh"
|
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
EOF
|
EOF
|
||||||
envFrom:
|
envFrom:
|
||||||
@@ -101,7 +100,7 @@ metadata:
|
|||||||
labels:
|
labels:
|
||||||
app: neuron-technologies-runner
|
app: neuron-technologies-runner
|
||||||
annotations:
|
annotations:
|
||||||
config-version: "2026-05-05-gke-gitea-url"
|
config-version: "2026-05-05-ssh-clone"
|
||||||
spec:
|
spec:
|
||||||
replicas: 2
|
replicas: 2
|
||||||
selector:
|
selector:
|
||||||
@@ -112,7 +111,7 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app: neuron-technologies-runner
|
app: neuron-technologies-runner
|
||||||
annotations:
|
annotations:
|
||||||
config-version: "2026-05-05-gke-gitea-url"
|
config-version: "2026-05-05-ssh-clone"
|
||||||
spec:
|
spec:
|
||||||
securityContext:
|
securityContext:
|
||||||
runAsNonRoot: false
|
runAsNonRoot: false
|
||||||
@@ -145,9 +144,8 @@ spec:
|
|||||||
# /usr/local/bin/git-cf-access-init.sh before every step,
|
# /usr/local/bin/git-cf-access-init.sh before every step,
|
||||||
# which sets up the redirect + headers.
|
# which sets up the redirect + headers.
|
||||||
env:
|
env:
|
||||||
CF_ACCESS_CLIENT_ID: "${CF_ACCESS_CLIENT_ID}"
|
GITEA_SSH_PRIVATE_KEY: "${GITEA_SSH_PRIVATE_KEY}"
|
||||||
CF_ACCESS_CLIENT_SECRET: "${CF_ACCESS_CLIENT_SECRET}"
|
BASH_ENV: "/usr/local/bin/git-ssh-init.sh"
|
||||||
BASH_ENV: "/usr/local/bin/git-cf-access-init.sh"
|
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
EOF
|
EOF
|
||||||
envFrom:
|
envFrom:
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
---
|
---
|
||||||
# gitea-runner-secret — neural-platform org runner token
|
# gitea-runner-secret — neural-platform org runner token
|
||||||
#
|
#
|
||||||
# GITEA_INSTANCE_URL stays as the in-cluster URL — the act_runner daemon
|
# GITEA_INSTANCE_URL: act_runner daemon polls git.neuralplatform.ai via HTTPS.
|
||||||
# polls it constantly and we don't want every poll to hit Cloudflare Access.
|
# GITEA_SSH_PRIVATE_KEY: ED25519 deploy key for SSH-based git clones inside
|
||||||
# Build containers, however, need the public URL because they run with
|
# build containers. git-ssh-init.sh (sourced via BASH_ENV) writes this key
|
||||||
# network: host and can't resolve gitea.git.svc.cluster.local. The
|
# to ~/.ssh/gitea_key and rewrites HTTPS Gitea URLs to SSH so that
|
||||||
# git-cf-access-init.sh entrypoint in the ci-base image rewrites the
|
# actions/checkout and plain `git clone` both use SSH auth without any
|
||||||
# in-cluster URL to https://git.neuralplatform.ai with the CF Access
|
# HTTPS credential or CF Access token.
|
||||||
# headers from CF_ACCESS_CLIENT_ID / CF_ACCESS_CLIENT_SECRET below.
|
|
||||||
apiVersion: external-secrets.io/v1beta1
|
apiVersion: external-secrets.io/v1beta1
|
||||||
kind: ExternalSecret
|
kind: ExternalSecret
|
||||||
metadata:
|
metadata:
|
||||||
name: gitea-runner-secret
|
name: gitea-runner-secret
|
||||||
namespace: ci
|
namespace: ci
|
||||||
annotations:
|
annotations:
|
||||||
force-sync: "2026-05-05-gke-gitea-url"
|
force-sync: "2026-05-05-ssh-clone"
|
||||||
spec:
|
spec:
|
||||||
refreshInterval: 1h
|
refreshInterval: 1h
|
||||||
secretStoreRef:
|
secretStoreRef:
|
||||||
@@ -27,21 +26,16 @@ spec:
|
|||||||
data:
|
data:
|
||||||
GITEA_INSTANCE_URL: "https://git.neuralplatform.ai"
|
GITEA_INSTANCE_URL: "https://git.neuralplatform.ai"
|
||||||
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ .runner_token }}"
|
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ .runner_token }}"
|
||||||
CF_ACCESS_CLIENT_ID: "{{ .cf_access_client_id }}"
|
GITEA_SSH_PRIVATE_KEY: "{{ .ci_ssh_private_key }}"
|
||||||
CF_ACCESS_CLIENT_SECRET: "{{ .cf_access_client_secret }}"
|
|
||||||
data:
|
data:
|
||||||
- secretKey: runner_token
|
- secretKey: runner_token
|
||||||
remoteRef:
|
remoteRef:
|
||||||
key: secret/data/gitea
|
key: secret/data/gitea
|
||||||
property: runner_token
|
property: runner_token
|
||||||
- secretKey: cf_access_client_id
|
- secretKey: ci_ssh_private_key
|
||||||
remoteRef:
|
remoteRef:
|
||||||
key: secret/data/gitea-runner-cf-access
|
key: secret/data/gitea
|
||||||
property: client_id
|
property: ci_ssh_private_key
|
||||||
- secretKey: cf_access_client_secret
|
|
||||||
remoteRef:
|
|
||||||
key: secret/data/gitea-runner-cf-access
|
|
||||||
property: client_secret
|
|
||||||
---
|
---
|
||||||
# neuron-technologies-runner-secret — neuron-technologies org runner token
|
# neuron-technologies-runner-secret — neuron-technologies org runner token
|
||||||
apiVersion: external-secrets.io/v1beta1
|
apiVersion: external-secrets.io/v1beta1
|
||||||
@@ -50,7 +44,7 @@ metadata:
|
|||||||
name: neuron-technologies-runner-secret
|
name: neuron-technologies-runner-secret
|
||||||
namespace: ci
|
namespace: ci
|
||||||
annotations:
|
annotations:
|
||||||
force-sync: "2026-05-05-gke-gitea-url"
|
force-sync: "2026-05-05-ssh-clone"
|
||||||
spec:
|
spec:
|
||||||
refreshInterval: 1h
|
refreshInterval: 1h
|
||||||
secretStoreRef:
|
secretStoreRef:
|
||||||
@@ -63,18 +57,13 @@ spec:
|
|||||||
data:
|
data:
|
||||||
GITEA_INSTANCE_URL: "https://git.neuralplatform.ai"
|
GITEA_INSTANCE_URL: "https://git.neuralplatform.ai"
|
||||||
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ .runner_token }}"
|
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ .runner_token }}"
|
||||||
CF_ACCESS_CLIENT_ID: "{{ .cf_access_client_id }}"
|
GITEA_SSH_PRIVATE_KEY: "{{ .ci_ssh_private_key }}"
|
||||||
CF_ACCESS_CLIENT_SECRET: "{{ .cf_access_client_secret }}"
|
|
||||||
data:
|
data:
|
||||||
- secretKey: runner_token
|
- secretKey: runner_token
|
||||||
remoteRef:
|
remoteRef:
|
||||||
key: secret/data/gitea
|
key: secret/data/gitea
|
||||||
property: neuron_technologies_runner_token
|
property: neuron_technologies_runner_token
|
||||||
- secretKey: cf_access_client_id
|
- secretKey: ci_ssh_private_key
|
||||||
remoteRef:
|
remoteRef:
|
||||||
key: secret/data/gitea-runner-cf-access
|
key: secret/data/gitea
|
||||||
property: client_id
|
property: ci_ssh_private_key
|
||||||
- secretKey: cf_access_client_secret
|
|
||||||
remoteRef:
|
|
||||||
key: secret/data/gitea-runner-cf-access
|
|
||||||
property: client_secret
|
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# git-ssh-init.sh
|
||||||
|
#
|
||||||
|
# Sets up SSH authentication for git operations inside CI build containers.
|
||||||
|
#
|
||||||
|
# How this gets invoked:
|
||||||
|
# act_runner runs each step via a non-interactive bash invocation.
|
||||||
|
# Setting BASH_ENV=/usr/local/bin/git-ssh-init.sh in act_runner's
|
||||||
|
# container.env causes bash to source this before any step's commands.
|
||||||
|
# (See servers/legion/k8s/gitea-runner/deployment.yaml.)
|
||||||
|
#
|
||||||
|
# What it does:
|
||||||
|
# 1. Writes GITEA_SSH_PRIVATE_KEY (from the runner secret) to ~/.ssh/gitea_key
|
||||||
|
# 2. Creates an ~/.ssh/config entry so git uses that key for git.neuralplatform.ai
|
||||||
|
# 3. Sets a git insteadOf rule to rewrite HTTPS Gitea URLs to SSH,
|
||||||
|
# so `actions/checkout` and any direct `git clone https://...` also use SSH
|
||||||
|
#
|
||||||
|
# Idempotent — safe to re-run on every step.
|
||||||
|
|
||||||
|
if [ -n "${GITEA_SSH_PRIVATE_KEY:-}" ]; then
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
chmod 700 ~/.ssh
|
||||||
|
|
||||||
|
# Write the private key
|
||||||
|
printf '%s\n' "${GITEA_SSH_PRIVATE_KEY}" > ~/.ssh/gitea_key
|
||||||
|
chmod 600 ~/.ssh/gitea_key
|
||||||
|
|
||||||
|
# SSH config — use this key for git.neuralplatform.ai, skip host key checking
|
||||||
|
# (build containers are ephemeral; we don't persist a known_hosts file)
|
||||||
|
cat > ~/.ssh/gitea_config << 'EOF'
|
||||||
|
Host git.neuralplatform.ai
|
||||||
|
HostName git.neuralplatform.ai
|
||||||
|
User git
|
||||||
|
IdentityFile ~/.ssh/gitea_key
|
||||||
|
StrictHostKeyChecking no
|
||||||
|
UserKnownHostsFile /dev/null
|
||||||
|
EOF
|
||||||
|
chmod 600 ~/.ssh/gitea_config
|
||||||
|
|
||||||
|
# Point SSH at our per-job config (merge with any existing config if present)
|
||||||
|
export GIT_SSH_COMMAND="ssh -F ~/.ssh/gitea_config"
|
||||||
|
|
||||||
|
# Rewrite HTTPS Gitea URLs → SSH so `actions/checkout` and plain `git clone`
|
||||||
|
# both go through SSH without any HTTPS credential or CF Access token needed
|
||||||
|
git config --global \
|
||||||
|
url."git@git.neuralplatform.ai:".insteadOf \
|
||||||
|
"https://git.neuralplatform.ai/" 2>/dev/null || true
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user