1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
---
stage: Verify
group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Using LXD with the Custom executor **(FREE)**
In this example, we use LXD to create a container per build and clean it
up afterwards.
This example uses a bash script for each stage. You can specify your
own image, which is exposed as
[CI_JOB_IMAGE](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html).
This example uses the `ubuntu:18.04` image for simplicity. If you
want to support multiple images, you would have to modify the executor.
These scripts have the following prerequisites:
- [LXD](https://linuxcontainers.org/lxd/introduction/)
- [GitLab Runner](../../install/linux-manually.md)
## Configuration
```toml
[[runners]]
name = "lxd-driver"
url = "https://www.gitlab.com"
token = "xxxxxxxxxxx"
executor = "custom"
builds_dir = "/builds"
cache_dir = "/cache"
[runners.custom]
prepare_exec = "/opt/lxd-driver/prepare.sh" # Path to a bash script to create lxd container and download dependencies.
run_exec = "/opt/lxd-driver/run.sh" # Path to a bash script to run script inside the container.
cleanup_exec = "/opt/lxd-driver/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-driver/`.
```shell
#!/usr/bin/env bash
# /opt/lxd-driver/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).
```shell
#!/usr/bin/env bash
# /opt/lxd-driver/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
start_container () {
if lxc info "$CONTAINER_ID" >/dev/null 2>/dev/null ; then
echo 'Found old container, deleting'
lxc delete -f "$CONTAINER_ID"
fi
# The container image is hardcoded, but you can use
# the `CI_JOB_IMAGE` predefined variable
# https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
# which is available under `CUSTOM_ENV_CI_JOB_IMAGE` to allow the
# user to specify the image. The rest of the script assumes that
# you are running on an ubuntu image so modifications might be
# required.
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`.
```shell
#!/usr/bin/env bash
# /opt/lxd-driver/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.
```shell
#!/usr/bin/env bash
# /opt/lxd-driver/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"
```
|