Skip to content
This repository has been archived by the owner on May 3, 2018. It is now read-only.

RFC: Added isolated Docker builder and runner #14

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
1 change: 1 addition & 0 deletions contrib/flocker-builder/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
61 changes: 61 additions & 0 deletions contrib/flocker-builder/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
FROM ubuntu:16.04

MAINTAINER Srdjan Grubor <[email protected]>

# You can't have aufs on aufs so this is mandatory to have bind-mounted
# on some systems
# VOLUME /var/lib/docker

# Add Docker repo key
# XXX: Done early to reuse cache as much as possible
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

RUN apt-get update && \
apt-get -y dist-upgrade && \
apt-get install -y apt-transport-https

RUN echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" > /etc/apt/sources.list.d/docker.list

RUN apt-get update && \
apt-get install -y docker-engine \
libffi-dev \
libssl-dev \
lsb-release \
python \
python-pip \
sudo \
virtualenv && \
apt-get clean

# Get tini to handle reaping and signal processing
ENV TINI_VERSION v0.14.0

ADD https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini /usr/local/bin/tini
ADD https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini.asc /usr/local/bin/tini.asc

RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 6380DC428747F6C393FEACA59A84159D7001A4E5 && \
gpg --verify /usr/local/bin/tini.asc && \
rm -r /usr/local/bin/tini.asc

RUN chmod +x /usr/local/bin/tini

# We want a limited user even though we technically are using a privileged container
RUN groupadd -r -g 910 builder
RUN useradd -m -r -u 910 -g 910 builder

# Builder needs to be in docker group to avoid requirements for sudo
RUN usermod -a -G docker builder

RUN mkdir -p /opt/flocker && \
chown builder:builder /opt/flocker

# Added last to avoid cache busting
COPY build_flocker.sh build.sh dind_wrapper.sh \
/usr/local/bin/

RUN chmod +x /usr/local/bin/build_flocker.sh \
/usr/local/bin/build.sh \
/usr/local/bin/dind_wrapper.sh

ENTRYPOINT ["/usr/local/bin/tini", "-g", "--"]
CMD ["/usr/local/bin/build.sh"]
22 changes: 22 additions & 0 deletions contrib/flocker-builder/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash -e

OUTPUT_DIR=/opt/flocker/output
FLOCKER_SRC_DIR=/opt/flocker/flocker

echo "Starting DinD..."
/usr/local/bin/dind_wrapper.sh &

echo "Invoking build script..."
sudo -i -u builder /usr/local/bin/build_flocker.sh

echo "Exporting the packages..."
if [ ! -d "${OUTPUT_DIR}" ]; then
mkdir -p "${OUTPUT_DIR}"
fi

mv ${FLOCKER_SRC_DIR}/clusterhq-*.deb "${OUTPUT_DIR}"
chmod 666 ${OUTPUT_DIR}/clusterhq-*.deb

echo
echo "Output files:"
ls "${OUTPUT_DIR}"
30 changes: 30 additions & 0 deletions contrib/flocker-builder/build_flocker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash -e

echo "Building as UID/EUID $UID/$EUID"

BUILD_DIR=/opt/flocker
FLOCKER_SRC_DIR=${BUILD_DIR}/flocker

pushd "${BUILD_DIR}" >/dev/null
echo "Cloning..."
git clone https://github.com/scatterhq/flocker

pushd "${FLOCKER_SRC_DIR}" >/dev/null
echo "Installing prerequisites"
# XXX: Not strictly needed but can help if used locally to build
virtualenv venv
. venv/bin/activate

# XXX: netifaces throws an error if it's not installed but adding it to
# admin.txt throws an error in Docker build due to duplication
pip install --requirement requirements/admin.txt && \
pip install netifaces

release_id=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
release_name=$(lsb_release -rs)

echo "Starting Flocker build in ${FLOCKER_SRC_DIR}..."
./admin/build-package --distribution=${release_id}-${release_name} $(pwd)
echo "Finished Flocker build!"
popd >/dev/null
popd >/dev/null
116 changes: 116 additions & 0 deletions contrib/flocker-builder/dind_wrapper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/bin/bash -e
#
# The MIT License (MIT)
#
# Copyright (c) 2014 Dan Tehranian
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Original from:
# https://github.com/tehranian/dind-jenkins-slave/commit/bdaea009f2ec982f07c89408906a64ce24ab7637

# First, make sure that cgroups are mounted correctly.
CGROUP=/sys/fs/cgroup
: {LOG:=stdio}

[ -d $CGROUP ] ||
mkdir $CGROUP

mountpoint -q $CGROUP ||
mount -n -t tmpfs -o uid=0,gid=0,mode=0755 cgroup $CGROUP || {
echo "Could not make a tmpfs mount. Did you use --privileged?"
exit 1
}

if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security
then
mount -t securityfs none /sys/kernel/security || {
echo "Could not mount /sys/kernel/security."
echo "AppArmor detection and --privileged mode might break."
}
fi

# Mount the cgroup hierarchies exactly as they are in the parent system.
for SUBSYS in $(cut -d: -f2 /proc/1/cgroup)
do
[ -d $CGROUP/$SUBSYS ] || mkdir $CGROUP/$SUBSYS
mountpoint -q $CGROUP/$SUBSYS ||
mount -n -t cgroup -o $SUBSYS cgroup $CGROUP/$SUBSYS

# The two following sections address a bug which manifests itself
# by a cryptic "lxc-start: no ns_cgroup option specified" when
# trying to start containers withina container.
# The bug seems to appear when the cgroup hierarchies are not
# mounted on the exact same directories in the host, and in the
# container.

# Named, control-less cgroups are mounted with "-o name=foo"
# (and appear as such under /proc/<pid>/cgroup) but are usually
# mounted on a directory named "foo" (without the "name=" prefix).
# Systemd and OpenRC (and possibly others) both create such a
# cgroup. To avoid the aforementioned bug, we symlink "foo" to
# "name=foo". This shouldn't have any adverse effect.
echo $SUBSYS | grep -q ^name= && {
NAME=$(echo $SUBSYS | sed s/^name=//)
ln -s $SUBSYS $CGROUP/$NAME || true
}

# Likewise, on at least one system, it has been reported that
# systemd would mount the CPU and CPU accounting controllers
# (respectively "cpu" and "cpuacct") with "-o cpuacct,cpu"
# but on a directory called "cpu,cpuacct" (note the inversion
# in the order of the groups). This tries to work around it.
[ $SUBSYS = cpuacct,cpu ] && ln -s $SUBSYS $CGROUP/cpu,cpuacct
done

# Note: as I write those lines, the LXC userland tools cannot setup
# a "sub-container" properly if the "devices" cgroup is not in its
# own hierarchy. Let's detect this and issue a warning.
grep -q :devices: /proc/1/cgroup ||
echo "WARNING: the 'devices' cgroup should be in its own hierarchy."
grep -qw devices /proc/1/cgroup ||
echo "WARNING: it looks like the 'devices' cgroup is not mounted."

# Now, close extraneous file descriptors.
pushd /proc/self/fd >/dev/null
for FD in *
do
case "$FD" in
# Keep stdin/stdout/stderr
[012])
;;
# Nuke everything else
*)
eval exec "$FD>&-"
;;
esac
done
popd >/dev/null


# If a pidfile is still around (for example after a container restart),
# delete it so that docker can start.
rm -rf /var/run/docker.pid

# Force overlayfs for DinD or it won't work on Debian image (like this one)
# XXX: Disabled for now since this will be run on local machines w/ overlay
# as the default FS so we leave the default in
# DOCKER_DAEMON_ARGS="$DOCKER_DAEMON_ARGS -s overlay"

exec dockerd $DOCKER_DAEMON_ARGS >/var/log/docker.log
15 changes: 15 additions & 0 deletions contrib/flocker-builder/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash -e

CURRENT_DIR=$(readlink -f $(dirname $0))
OUTPUT_DIR="${CURRENT_DIR}/dist"

if [ ! -d "${OUTPUT_DIR}" ]; then
mkdir -p "${OUTPUT_DIR}"
fi

pushd "${CURRENT_DIR}" >/dev/null
docker build --tag flocker_builder .
docker run -v ${OUTPUT_DIR}:/opt/flocker/output --rm --privileged flocker_builder
popd >/dev/null

echo "Built files are in ${OUTPUT_DIR}"