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

Commit

Permalink
Added isolated Docker builder and runner
Browse files Browse the repository at this point in the history
Current build setup requires root and installation of a ton of packages
from pip on the local machine. With this PR, this can be done in a
single-command with a DinD config and isolated builder. Currently only
supports Ubuntu 16.04 but can be easily extended to others.
  • Loading branch information
sgnn7 committed Apr 28, 2017
1 parent 9dd5214 commit 51675af
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 0 deletions.
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}"

0 comments on commit 51675af

Please sign in to comment.