Commit 7cb27aab authored by Steve Azzopardi's avatar Steve Azzopardi

Add LXD Custom executor example

This example creates LXD containers for a specific job and runs the
script inside of that container. After the job is done the container is
removed. This tries to follow the same life cycle of the Docker executor

reference #4257
parent c687a923
......@@ -405,3 +405,8 @@ We strongly suggest using `SYSTEM_FAILURE_EXIT_CODE` to exit
instead of a hard coded value since it can change in any release, making
your binary/script future proof.
## Examples
A set of example executors using the Custom executor can be found in
the [examples page](custom_examples/index.md).
# Custom executor examples
The following are examples of using the [Custom executor](../custom.md)
for environments not supported natively by GitLab Runner:
- [LXD](lxd.md)
# Using LXD with the Custom executor
In this example, we use LXD to create a container per build and clean it
up afterwards.
Here, we are using a bash script for each stage. Users
[can't yet specify which image to use](https://gitlab.com/gitlab-org/gitlab-runner/issues/4357),
so we are going to use an Ubuntu 18.04 image to run the jobs.
These scripts have the following prerequisites:
- [LXD](https://linuxcontainers.org/lxd/introduction/)
- [GitLab Runner](https://docs.gitlab.com/runner/install/linux-manually.html)
## Configuration
```toml
[[runners]]
name = "lxd-executor"
url = "https://www.gitlab.com"
token = "xxxxxxxxxxx"
executor = "custom"
builds_dir = "/builds"
cache_dir = "/cache"
[runners.custom]
prepare_exec = "/opt/lxd-executor/prepare.sh" # Path to a bash script to create lxd container and download dependencies.
run_exec = "/opt/lxd-executor/run.sh" # Path to a bash script to run script inside the container.
cleanup_exec = "/opt/lxd-executor/cleanup.sh" # Path to bash script to delete container.
```
## Base
Each stage [prepare](#prepare), [run](#run), and [cleanup](#cleanup)
will use this script to generate variables that are used throughout the
scripts.
It's important that this script is located in the same directory as the
other scripts, in this case `/opt/lxd-executor/`.
```sh
#!/usr/bin/env bash
# /opt/lxd-executor/base.sh
CONTAINER_ID="runner-$CUSTOM_ENV_CI_RUNNER_ID-project-$CUSTOM_ENV_CI_PROJECT_ID-concurrent-$CUSTOM_ENV_CI_CONCURRENT_PROJECT_ID-$CUSTOM_ENV_CI_JOB_ID"
```
## Prepare
The prepare script will do the following:
- Destroy a container with the same name if there is one running.
- Start a container and wait for it to start.
- Install [prerequisite
dependencies](../custom.md#prerequisite-software-for-running-a-job).
```sh
#!/usr/bin/env bash
# /opt/lxd-executor/prepare.sh
currentDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
source ${currentDir}/base.sh # Get variables from base.
set -eo pipefail
# trap any error, and mark it as a system failure.
trap "exit $SYSTEM_FAILURE_EXIT_CODE" ERR
CONTAINER_ID="runner-$CUSTOM_ENV_CI_RUNNER_ID-project-$CUSTOM_ENV_CI_PROJECT_ID-concurrent-$CUSTOM_ENV_CI_CONCURRENT_PROJECT_ID"
start_container () {
if lxc info "$CONTAINER_ID" >/dev/null 2>/dev/null ; then
echo 'Found old container, deleting'
lxc delete -f "$CONTAINER_ID"
fi
# Container image is harcoded at the moment, since Custom executor
# does not provide the value of `image`. See
# https://gitlab.com/gitlab-org/gitlab-runner/issues/4357 for
# details.
lxc launch ubuntu:18.04 "$CONTAINER_ID"
# Wait for container to start, we are using systemd to check this,
# for the sake of brevity.
for i in $(seq 1 10); do
if lxc exec "$CONTAINER_ID" -- sh -c "systemctl isolate multi-user.target" >/dev/null 2>/dev/null; then
break
fi
if [ "$i" == "10" ]; then
echo 'Waited for 10 seconds to start container, exiting..'
# Inform GitLab Runner that this is a system failure, so it
# should be retried.
exit "$SYSTEM_FAILURE_EXIT_CODE"
fi
sleep 1s
done
}
install_dependencies () {
# Install Git LFS, git comes pre installed with ubuntu image.
lxc exec "$CONTAINER_ID" -- sh -c "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash"
lxc exec "$CONTAINER_ID" -- sh -c "apt-get install git-lfs"
# Install gitlab-runner binary since we need for cache/artifacts.
lxc exec "$CONTAINER_ID" -- sh -c "curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64"
lxc exec "$CONTAINER_ID" -- sh -c "chmod +x /usr/local/bin/gitlab-runner"
}
echo "Running in $CONTAINER_ID"
start_container
install_dependencies
```
## Run
This will run the script generated by GitLab Runner by sending
the content of the script to the container via `STDIN`.
```sh
#!/usr/bin/env bash
# /opt/lxd-executor/run.sh
currentDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
source ${currentDir}/base.sh # Get variables from base.
lxc exec "$CONTAINER_ID" /bin/bash < "${1}"
if [ $? -ne 0 ]; then
# Exit using the variable, to make the build as failure in GitLab
# CI.
exit $BUILD_FAILURE_EXIT_CODE
fi
```
## Cleanup
Destroy the container since the build has finished.
```sh
#!/usr/bin/env bash
# /opt/lxd-executor/cleanup.sh
currentDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
source ${currentDir}/base.sh # Get variables from base.
echo "Deleting container $CONTAINER_ID"
lxc delete -f "$CONTAINER_ID"
```
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment