diff --git a/docker-compose/executors/README.md b/docker-compose/executors/README.md index b0ae6d20d..a19b405a2 100644 --- a/docker-compose/executors/README.md +++ b/docker-compose/executors/README.md @@ -1,6 +1,6 @@ # Executors -Executors are Sourcegraph’s solution for running untrusted code in a secure and controllable way. For more information on executors and how they are used see the Executors [documentation](https://docs.sourcegraph.com/admin/executors) +Executors are Sourcegraph's solution for running untrusted code in a secure and controllable way. For more information on executors and how they are used see the Executors [documentation](https://sourcegraph.com/docs/self-hosted/executors). ## Deploying @@ -8,16 +8,16 @@ This directory contains a compose file to deploy a Sourcegraph Executor. NOTE: Executors require privileged access in order to run correctly on docker-compose based deployments. -To learn more visit TODO +To learn more visit the [Docker Compose executor deployment docs](https://sourcegraph.com/docs/self-hosted/executors/deploy-executors-docker). -To run this as part of a Sourcegraph deployment on the machine machine, execute the following command from the `docker-compose` directory: +To run this as part of a Sourcegraph deployment on the same machine, execute the following command from the `docker-compose` directory: ```bash -docker-compose -f docker-compose.yaml -f executors/executor.docker-compose.yaml up -d +docker compose -f docker-compose.yaml -f executors/executor.docker-compose.yaml up -d ``` -To run this on a standalone machine, execute the following from the `executors` directory +To run this on a standalone machine, execute the following from the `executors` directory: ```bash -docker-compose up -d executor.docker-compose.yaml -``` \ No newline at end of file +docker compose -f executor.docker-compose.yaml up -d +``` diff --git a/docker-compose/executors/executor.docker-compose.yaml b/docker-compose/executors/executor.docker-compose.yaml index c7fc82486..10b4296c8 100644 --- a/docker-compose/executors/executor.docker-compose.yaml +++ b/docker-compose/executors/executor.docker-compose.yaml @@ -10,7 +10,7 @@ services: # Run with privileged capabilities (required for docker daemon control) privileged: true environment: - # Refer to https://docs.sourcegraph.com/admin/executors/deploy_executors_binary#step-2-setup-environment-variables on how to populate these variables + # Refer to https://sourcegraph.com/docs/self-hosted/executors/executors-config on how to populate these variables - EXECUTOR_FRONTEND_URL=http://sourcegraph-frontend-0:3080 # Note: Must match `executors.accessToken` in site config - EXECUTOR_FRONTEND_PASSWORD= diff --git a/test/executor-smoke-test.sh b/test/executor-smoke-test.sh new file mode 100755 index 000000000..f92e1b474 --- /dev/null +++ b/test/executor-smoke-test.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Executor smoke test for deploy-sourcegraph-docker +# +# Requires: a running Sourcegraph docker-compose stack (from smoke-test.sh or manual start). +# This script creates a site admin account, configures executor access, starts an executor +# container, and verifies it registers with the Sourcegraph instance. +# +# Dependencies: curl, jq, docker compose + +FRONTEND_URL="${FRONTEND_URL:-http://localhost:80}" +EXECUTOR_TOKEN="executor-smoke-test-token" +ADMIN_EMAIL="smoke-test@sourcegraph.com" +ADMIN_USERNAME="smoke-admin" +ADMIN_PASSWORD="smoke-test-password-123!" +COMPOSE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../docker-compose" && pwd)" + +echo "=== Executor Smoke Test ===" + +# Step 1: Create initial site admin account +echo "Step 1: Creating site admin account..." +INIT_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST "${FRONTEND_URL}/-/site-init" \ + -H 'Content-Type: application/json' \ + -d "{\"email\":\"${ADMIN_EMAIL}\",\"username\":\"${ADMIN_USERNAME}\",\"password\":\"${ADMIN_PASSWORD}\"}") +if [ "$INIT_STATUS" = "200" ] || [ "$INIT_STATUS" = "201" ]; then + echo " Site admin created" +elif [ "$INIT_STATUS" = "409" ]; then + echo " Site admin already exists, continuing" +else + echo " Warning: site-init returned HTTP $INIT_STATUS, attempting to continue" +fi + +# Step 2: Sign in and extract session cookie +echo "Step 2: Signing in..." +SESSION_COOKIE=$(curl -s -D - -o /dev/null -X POST "${FRONTEND_URL}/-/sign-in" \ + -H 'Content-Type: application/json' \ + -d "{\"email\":\"${ADMIN_EMAIL}\",\"password\":\"${ADMIN_PASSWORD}\"}" \ + | tr -d '\r' | grep -i '^Set-Cookie: sgs=' | sed 's/^Set-Cookie: \([^;]*\).*/\1/') + +if [ -z "$SESSION_COOKIE" ]; then + echo " FAILED: Could not obtain session cookie" + exit 1 +fi +echo " Signed in" + +# Step 3: Create access token +echo "Step 3: Creating access token..." +TOKEN=$(curl -s --cookie "$SESSION_COOKIE" -X POST "${FRONTEND_URL}/.api/graphql" \ + -H 'Content-Type: application/json' \ + -d '{"query":"mutation { createAccessToken(user: \"VXNlcjox\", scopes: [\"user:all\"], note: \"executor-smoke-test\") { token } }"}' \ + | jq -r '.data.createAccessToken.token') + +if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then + echo " FAILED: Could not create access token" + exit 1 +fi +echo " Access token created" + +# Step 4: Update site config with executor access token +echo "Step 4: Configuring executor access token in site config..." +LAST_ID=$(curl -s -X POST "${FRONTEND_URL}/.api/graphql" \ + -H "Authorization: token $TOKEN" \ + -H 'Content-Type: application/json' \ + -d '{"query":"{ site { configuration { id } } }"}' \ + | jq -r '.data.site.configuration.id') + +NEW_CONFIG=$(jq -n --arg token "$EXECUTOR_TOKEN" \ + '{"auth.providers": [{"type": "builtin"}], "executors.accessToken": $token} | tojson') + +curl -s -o /dev/null -X POST "${FRONTEND_URL}/.api/graphql" \ + -H "Authorization: token $TOKEN" \ + -H 'Content-Type: application/json' \ + --data-raw "{\"query\":\"mutation UpdateSiteConfig(\$input: String!) { updateSiteConfiguration(lastID: $LAST_ID, input: \$input) }\", \"variables\":{\"input\":$NEW_CONFIG}}" +echo " Site config updated" + +# Step 5: Start executor container +echo "Step 5: Starting executor container..." +EXECUTOR_CONTAINER=$(docker compose \ + -f "${COMPOSE_DIR}/docker-compose.yaml" \ + -f "${COMPOSE_DIR}/executors/executor.docker-compose.yaml" \ + run -d \ + -e "EXECUTOR_FRONTEND_PASSWORD=${EXECUTOR_TOKEN}" \ + -e EXECUTOR_QUEUE_NAME=batches \ + executor 2>&1 | tail -1) +echo " Executor container started: ${EXECUTOR_CONTAINER:0:12}" + +# Step 6: Wait for executor to register +echo "Step 6: Waiting for executor to register..." +MAX_ATTEMPTS=24 +for i in $(seq 1 $MAX_ATTEMPTS); do + COUNT=$(curl -s -X POST "${FRONTEND_URL}/.api/graphql" \ + -H "Authorization: token $TOKEN" \ + -H 'Content-Type: application/json' \ + -d '{"query":"{ executors(query: \"\", active: false) { totalCount } }"}' \ + | jq -r '.data.executors.totalCount // 0') + + if [ "$COUNT" -ge 1 ] 2>/dev/null; then + echo " Executor registered after $((i * 5))s" + echo "" + echo "=== EXECUTOR SMOKE TEST PASSED ===" + exit 0 + fi + echo " Attempt $i/$MAX_ATTEMPTS - waiting 5s..." + sleep 5 +done + +echo "" +echo "=== EXECUTOR SMOKE TEST FAILED ===" +echo "Executor did not register within $((MAX_ATTEMPTS * 5))s" +echo "" +echo "Container status:" +docker inspect "$EXECUTOR_CONTAINER" --format '{{.State.Status}} (exit code: {{.State.ExitCode}})' 2>/dev/null || echo " Container not found" +echo "" +echo "Container logs:" +docker logs "$EXECUTOR_CONTAINER" 2>&1 | tail -20 || echo " No logs available" +exit 1