We have setup a CentOS 7
repository in OpenAFS
that we access from our images to install some applications.
This process is entirely manual and we're trying to automate the generation with GitLab-CI
.
I've set up a runner following the instructions for setting Docker-in-Docker runner.
Then, I've modified the /etc/gitlab-runner/config.toml
file to specify an OpenAFS
host volume (volumes entry):
concurrent = 1
check_interval = 0
[[runners]]
name = "DinD builder"
url = "https://gitlab.ch/ci"
token = "7cf33172d567dd2504e988a78f64c3"
executor = "docker"
[runners.docker]
tls_verify = false
image = "docker:latest"
privileged = true
disable_cache = false
volumes = ["/afs:/afs:ro", "/cache"]
[runners.cache]
In the Dockerfile
, we have a RUN
command that copies the repo file from AFS
to the currently-being-built-image, so we can install the software with yum install
:
FROM gitlab-registry.ch/cc7-base
MAINTAINER Somebody
RUN echo "set completion-ignore-case On" >> /etc/inputrc
RUN yum update -y && \
yum install -y \
gcc \
git \
mc \
python-devel \
python-pip \
svn \
unzip \
vim
RUN cp /afs/<hugePathHere>/Linux/RPM/cc7/custom-repo.repo /etc/yum.repos.d && \
yum install --enablerepo=custom-repo -y CustomApp
CMD /bin/bash
The .gitlab-ci.yml
file is:
services:
- docker:dind
build:
stage: build
tags:
- rtf-builder
before_script:
- docker info
- docker login -u $DOCKER_LOGIN_USERNAME -p $DOCKER_LOGIN_PASSWORD gitlab-registry.ch
script:
- docker build --pull -t $TO .
- docker push $TO
after_script:
- docker logout gitlab-registry.ch
variables:
TO: gitlab-registry.ch/<myUser>/testdockergitlabbuild:$CI_BUILD_REF_NAME
But this always fails, with GitLab-CI
telling me that
cp: cannot stat '/afs/hugePathHere/Linux/RPM/cc7/custom-repo.repo': No such file or directory
In the host machine, AFS
is accesible and I can manually copy the
repo file.
A container created with docker run --rm --privileged -ti -v /afs:/afs cc7-base
has AFS
accesible.
Am I missing something to make AFS
accesible from the Dockerfile
?
NOTE:
$DOCKER_LOGIN_USERNAME
and $DOCKER_LOGIN_PASSWORD
are GitLab secure variables.
I found a way to have AFS
and Docker
together, but not with a Docker-in-Docker
runner.
The trick is to use instead a shell
runner.
So when registering the runner, we should do it like:
sudo gitlab-ci-multi-runner register -n \
--url <GITLAB_CI_SERVER_URL> \
--registration-token <PROJECT_TOKEN> \
--executor shell \
--tag-list "shell-builder" \
--description "Shell builder for Docker images"
Afterwards, we just need to install Docker and make it available for the gitlab-runner
user (for example, adding the user to the docker
group).
As stated here, we can't access the files inside AFS
from the Dockerfile
.
Instead, we can use a 2-step build:
Dockerfile
everything that doesn't need to access AFS
.AFS
mounted and install all the AFS
related stuff.Then, we just have to commit the container and push it to the registry as the final image.
As an example, the files involved in this process could be something like this:
stages:
- build
variables:
TO: <GitLab Registry URL>/<project>:$CI_BUILD_REF_NAME
build:
stage: build
tags:
- shell-builder
before_script:
- docker login -u $DOCKER_LOGIN_USERNAME -p $DOCKER_LOGIN_PASSWORD <GitLab Registry URL>
script:
- docker build --pull -t $TO .
after_script:
- sh ./postBuild.sh $TO $GITLAB_USER_EMAIL
- docker push $TO
- docker logout <GitLab Registry URL>
FROM <Some base image>
MAINTAINER <Somebody>
<Do everything not related to AFS>
CMD /bin/bash
#!/bin/bash
readonly imageName="$1"
readonly maintainer="$2"
readonly imageNameAsLatest="$imageName-latest"
readonly containerName="afs_mounted"
docker create -ti --privileged -v /afs:/afs --name="$containerName" "$imageName"
docker start "$containerName"
docker exec "$containerName" /bin/bash -c "cp /afs/LONG_AFS_PATH/Linux/CentOS7/custom-repo.repo /etc/yum.repos.d"
docker exec "$containerName" /bin/bash -c "yum install --enablerepo=custom-repo -y CustomApplication"
docker commit -a "$maintainer" -m "Mounted AFS in a container and installed CustomApplication." "$containerName" "$imageName"
docker tag "$imageName" "$imageNameAsLatest"
docker stop "$containerName"
docker rm "$containerName"