simplified runner script

This commit is contained in:
Morten Olsen
2026-01-01 23:39:24 +01:00
parent c50095a0b6
commit 8f3f96a685
3 changed files with 107 additions and 61 deletions

View File

@@ -0,0 +1,25 @@
{{- if .Values.actions.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ .Release.Name }}-runner-config"
data:
config.yml: |
log:
level: warn
format: text
runner:
file: .runner
container:
network: host
options: -v /certs/client:/certs/client -e DOCKER_HOST=tcp://localhost:2376 -e DOCKER_TLS_VERIFY=1 -e DOCKER_CERT_PATH=/certs/client
valid_volumes:
- /certs/client
envs:
DOCKER_HOST: tcp://localhost:2376
DOCKER_TLS_VERIFY: "1"
DOCKER_CERT_PATH: /certs/client
{{- end }}

View File

@@ -16,6 +16,21 @@ spec:
app: "{{ .Release.Name }}-runner"
spec:
hostname: docker
initContainers:
- name: install-jq
image: curlimages/curl:latest
command:
- sh
- -c
- |
# Download static jq binary for Linux amd64
curl -L -o /shared/jq https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64
chmod +x /shared/jq
# Verify it works
/shared/jq --version || echo "Warning: jq download may have failed"
volumeMounts:
- name: shared-tools
mountPath: /shared
containers:
- name: docker-in-docker
image: "{{ .Values.actions.runner.dind.image.repository }}:{{ .Values.actions.runner.dind.image.tag }}"
@@ -42,12 +57,21 @@ spec:
- -c
- |
cd /data
# Use jq from shared volume (installed by initContainer)
export PATH="/shared:${PATH}"
export LD_LIBRARY_PATH="/shared/lib:${LD_LIBRARY_PATH}"
if ! /shared/jq --version >/dev/null 2>&1; then
echo "Error: jq is not working (checking dependencies...)"
ldd /shared/jq 2>&1 || true
exit 1
fi
echo "jq is available at /shared/jq"
# Wait for shared secret to be available
while [ -z "${FORGEJO_RUNNER_SHARED_SECRET}" ]; do
echo "Waiting for shared secret..."
sleep 1
done
# Create runner file if it doesn't exist
# Always ensure runner file exists and is up to date
if [ ! -f .runner ]; then
echo "Creating runner file..."
forgejo-runner create-runner-file \
@@ -59,59 +83,44 @@ spec:
sleep 5
exit 1
}
# Set labels in runner file (matching docker-compose example)
{{- if .Values.actions.runner.labels }}
echo "Setting runner labels..."
LABELS_JSON='[{{- range $index, $label := .Values.actions.runner.labels }}{{- if $index }},{{- end }}"{{ $label }}"{{- end }}]'
sed -i "s|\"labels\": null|\"labels\": ${LABELS_JSON}|" .runner || \
sed -i "s|\"labels\": \[\]|\"labels\": ${LABELS_JSON}|" .runner || true
{{- end }}
else
fi
# Always update labels to match configuration
{{- if .Values.actions.runner.labels }}
# Verify jq is available
if ! command -v jq >/dev/null 2>&1; then
echo "Error: jq is not available"
exit 1
fi
LABELS_JSON='[{{- range $index, $label := .Values.actions.runner.labels }}{{- if $index }},{{- end }}"{{ $label }}"{{- end }}]'
echo "Updating runner labels to match configuration..."
# Use awk to replace the labels array (handles both single-line and multi-line JSON)
awk -v new_labels="${LABELS_JSON}" '
BEGIN { in_labels = 0 }
/"labels":/ {
in_labels = 1
print " \"labels\": " new_labels
next
}
in_labels && /^ \]/ {
in_labels = 0
next
}
in_labels && /^ / {
next
}
{ print }
' .runner > .runner.tmp && mv .runner.tmp .runner || {
# Fallback to sed for single-line labels if awk fails
echo "Awk failed, trying sed fallback..."
sed -i "s|\"labels\": null|\"labels\": ${LABELS_JSON}|" .runner 2>/dev/null || true
sed -i "s|\"labels\": \[\]|\"labels\": ${LABELS_JSON}|" .runner 2>/dev/null || true
sed -i "s|\"labels\": \[[^]]*\]|\"labels\": ${LABELS_JSON}|" .runner 2>/dev/null || true
}
echo "New labels: ${LABELS_JSON}"
# Ensure .runner file exists and is readable
if [ ! -f .runner ]; then
echo "Error: .runner file does not exist"
exit 1
fi
# Show current labels before update
CURRENT_LABELS_BEFORE=$(jq -r '.labels // "null"' .runner 2>/dev/null || echo "error reading file")
echo "Current labels before update: ${CURRENT_LABELS_BEFORE}"
# Update labels
if jq --argjson labels "${LABELS_JSON}" '.labels = $labels' .runner > .runner.tmp; then
mv .runner.tmp .runner
echo "Labels updated successfully"
# Verify the update
CURRENT_LABELS_AFTER=$(jq -r '.labels // "null"' .runner)
echo "Current labels after update: ${CURRENT_LABELS_AFTER}"
else
echo "Error: Failed to update labels with jq"
exit 1
fi
{{- end }}
fi
# Generate config if it doesn't exist
if [ ! -f config.yml ]; then
echo "Generating config file..."
# Always copy config from ConfigMap to ensure it's up to date
echo "Copying config from ConfigMap..."
cp /config/config.yml config.yml || {
echo "Warning: Failed to copy config from ConfigMap, generating default..."
forgejo-runner generate-config > config.yml
# Update config for docker-in-docker
sed -i 's|network: .*|network: host|' config.yml || true
if ! grep -q "DOCKER_HOST" config.yml; then
awk '/^ envs:$/ { print; print " DOCKER_HOST: tcp://localhost:2376"; print " DOCKER_TLS_VERIFY: 1"; print " DOCKER_CERT_PATH: /certs/client"; next }1' config.yml > config.yml.tmp && mv config.yml.tmp config.yml || true
fi
sed -i 's|^ options:.*| options: -v /certs/client:/certs/client|' config.yml || true
if grep -q "valid_volumes: \[\]" config.yml; then
awk '/^ valid_volumes: \[\]$/ { print " valid_volumes:"; print " - /certs/client"; next }1' config.yml > config.yml.tmp && mv config.yml.tmp config.yml || true
fi
fi
# Wait for docker-in-docker to be ready
}
# Wait for docker-in-docker TCP to be ready
echo "Waiting for docker-in-docker to be ready..."
while ! nc -z localhost 2376 2>/dev/null; do
echo "Docker daemon not ready, waiting..."
@@ -123,18 +132,18 @@ spec:
sleep 1
done
echo "Docker daemon and certificates ready"
# Verify runner file exists before starting daemon
if [ ! -f .runner ] || [ ! -w .runner ]; then
echo "Error: .runner file is missing or not writable"
exit 1
fi
# Run daemon
echo "Starting runner daemon..."
while : ; do
if [ -f .runner ] && [ -w .runner ]; then
forgejo-runner --config config.yml daemon || {
echo "Daemon exited, restarting in 5 seconds..."
sleep 5
}
else
echo "Waiting for runner file..."
sleep 1
fi
done
env:
- name: FORGEJO_INSTANCE_URL
@@ -160,10 +169,20 @@ spec:
mountPath: /data
- name: docker-certs
mountPath: /certs
- name: runner-config
mountPath: /config
readOnly: true
- name: shared-tools
mountPath: /shared
volumes:
- name: runner-data
persistentVolumeClaim:
claimName: "{{ .Release.Name }}-runner-data"
- name: docker-certs
emptyDir: {}
- name: shared-tools
emptyDir: {}
- name: runner-config
configMap:
name: "{{ .Release.Name }}-runner-config"
{{- end }}

View File

@@ -141,6 +141,8 @@ actions:
storage:
size: 10Gi
labels:
- "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest-full"
- "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest-slim"
- "ubuntu-slim-latest:docker://gitea/runner-images:ubuntu-latest-slim"
- "ubuntu-full-latest:docker://gitea/runner-images:ubuntu-latest-full"
- "docker-cli:docker://code.forgejo.org/oci/docker:cli"
- "node-bookworm:docker://code.forgejo.org/oci/node:20-bookworm"