Skip to content
Open
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
14 changes: 7 additions & 7 deletions docker-compose/executors/README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# Executors

Executors are Sourcegraphs 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

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
```
docker compose -f executor.docker-compose.yaml up -d
```
2 changes: 1 addition & 1 deletion docker-compose/executors/executor.docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
117 changes: 117 additions & 0 deletions test/executor-smoke-test.sh
Original file line number Diff line number Diff line change
@@ -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