Executors
Executors are Sourcegraph's solution for running untrusted code in a secure and controllable way.
Installation
To deploy executors to target your Sourcegraph instance, follow our deployment guide.
The supported deployment options are,
- Binary.
- Terraform on AWS or GCP.
- Beta Native Kubernetes.
- Beta Docker-in-Docker on Kubernetes.
- Beta Docker-Compose.
Why use executors?
Running untrusted code is a core requirement of features such as precise code navigation auto-indexing, and running batch changes server-side.
Auto-indexing jobs, in particular, require the invocation of arbitrary and untrusted code to support the resolution of project dependencies. Invocation of post-install hooks, use of insecure package management tools, and package manager proxy attacks can create opportunities in which an adversary can gain unlimited use of compute or exfiltrate data. The latter outcome is particularly dangerous for on-premise installations of Sourcegraph, which is the chosen option for companies wanting to maintain strict privacy of their code property.
Instead of performing this work within the Sourcegraph instance, where code is available on disk and unprotected internal services are available over the local network, we move untrusted compute into a sandboxed environment, the executor, that has access only to the clone of a single repository on disk (its workspace) and to the public internet.
How it works
Executor instances are capable of being deployed in a variety of ways. Each runtime vary in how jobs are executed.
Locally with src-cli
- User run the
src
(e.g.src batch
) command from the command line. src
calls the Sourcegraph API to clone a repository.- The repositories are written to a directory.
- A Docker Container is created for each "step."
- The directory containing the repository is mounted to the container.
- "Steps" are ran in sequential order.
- The container run a defined command against the repository.
- Logs from the container are sent back to
src
. - At the end of processing all repositories, the result is sent to a Sourcegraph API.
- e.g. Batch Changes sends a
git diff
to a Sourcegraph API (and invokes other APIs).
- e.g. Batch Changes sends a
Binary
- The executor binary is installed to a machine.
- Additional executables (e.g. Docker,
src
) are installed as well
- Additional executables (e.g. Docker,
- The executor instances pulls for available Jobs from a Sourcegraph API
- A user initiates a process that creates executor Jobs.
- The executor instance "dequeues" a Job.
- Executor calls the Sourcegraph API to clone a repository.
- The repositories are written to a directory.
- A Docker Container is created for each "step."
- If the Job is
batches
(non-native execution),src
is invoked - Docker is invoked directly for other Jobs (
codeintel
and native executionbatches
) - The directory containing the repository is mounted to the container.
- "Steps" are ran in sequential order.
- If the Job is
- The container run a defined command against the repository.
- Logs from the container are sent back to the executor.
- Logs are streamed from the executor to a Sourcegraph API
- The executor calls a Sourcegraph API to that "complete" the Job.
Firecracker
- The executor binary is installed to a machine.
- Additional executables (e.g. Docker,
src
) are installed as well
- Additional executables (e.g. Docker,
- The executor instances pulls for available Jobs from a Sourcegraph API
- A user initiates a process that creates executor Jobs.
- The executor instance "dequeues" a Job.
- Executor calls the Sourcegraph API to clone a repository.
- The repositories are written to a directory.
ignite
starts up a Docker container that spawns a single Firecracker VM within the Docker container.- The directory containing the repository is mounted to the VM.
- Docker Container is created in the Firecracker VM for each "step."
- If the Job is
batches
(non-native execution),src
is invoked - Docker is invoked directly for other Jobs (
codeintel
and native executionbatches
) - "Steps" are ran in sequential order.
- If the Job is
- Within each Firecracker VM a single Docker container is created
- The container run a defined command against the repository.
- Logs from the container are sent back to the executor.
- Logs are streamed from the executor to a Sourcegraph API
- The executor calls a Sourcegraph API to that "complete" the Job.
Docker
- The executor image is started as a Docker container on a machine
- The executor pulls for available Jobs from a Sourcegraph API
- A user initiates a process that creates executor Jobs.
- The executor instance "dequeues" a Job.
- Executor calls the Sourcegraph API to clone a repository.
- The repositories are written to a directory.
- A Docker Container is created for each "step."
- If the Job is
batches
(non-native execution),src
is invoked - Docker is invoked directly for other Jobs (
codeintel
and native executionbatches
) - The directory containing the repository is mounted to the container.
- "Steps" are ran in sequential order.
- If the Job is
- The container run a defined command against the repository.
- Logs from the container are sent back to the executor.
- Logs are streamed from the executor to a Sourcegraph API
- The executor calls a Sourcegraph API to that "complete" the Job.
Native Kubernetes
Experimental
- The executor image is started as a pod in a Kubernetes node
- The executor pulls for available Jobs from a Sourcegraph API
- A user initiates a process that creates executor Jobs.
- The executor instance "dequeues" a Job.
- Executor calls the Sourcegraph API to clone a repository.
- The repositories are written to a directory.
- A Kubernetes Job is created for each "step."
- The directory containing the repository is mounted to the container.
- "Steps" are ran in sequential order.
- The container run a defined command against the repository.
- Logs from the container are sent back to the executor.
- Logs are streamed from the executor to a Sourcegraph API
- The executor calls a Sourcegraph API to that "complete" the Job.
Native execution
Read more in Native execution.
Docker-in-Docker Kubernetes
Experimental
- The executor image is started as a container in Kubernetes Pod
- The dind image is started as a sidecar container in the same Kubernetes Pod
- The executor pulls for available Jobs from a Sourcegraph API
- A user initiates a process that creates executor Jobs.
- The executor instance "dequeues" a Job.
- Executor calls the Sourcegraph API to clone a repository.
- The repositories are written to a directory.
- A Docker Container is created for each "step."
- If the Job is
batches
(non-native execution),src
is invoked - Docker is invoked directly for other Jobs (
codeintel
and native executionbatches
) - The directory containing the repository is mounted to the container.
- "Steps" are ran in sequential order.
- If the Job is
- The container run a defined command against the repository.
- Logs from the container are sent back to the executor.
- Logs are streamed from the executor to a Sourcegraph API
- The executor calls a Sourcegraph API to that "complete" the Job.
Deciding which deployment to use
Deciding how to deploy the executor depends on your use case. The following flowchart can help you decide which deployment is best for you.
Troubleshooting
Refer to the Troubleshooting Executors document for common debugging operations.