diff --git a/contrib/flocker-builder/.gitignore b/contrib/flocker-builder/.gitignore new file mode 100644 index 0000000000..849ddff3b7 --- /dev/null +++ b/contrib/flocker-builder/.gitignore @@ -0,0 +1 @@ +dist/ diff --git a/contrib/flocker-builder/Dockerfile b/contrib/flocker-builder/Dockerfile new file mode 100644 index 0000000000..07032aef7d --- /dev/null +++ b/contrib/flocker-builder/Dockerfile @@ -0,0 +1,61 @@ +FROM ubuntu:16.04 + +MAINTAINER Srdjan Grubor + +# 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"] diff --git a/contrib/flocker-builder/build.sh b/contrib/flocker-builder/build.sh new file mode 100644 index 0000000000..fecff097c9 --- /dev/null +++ b/contrib/flocker-builder/build.sh @@ -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}" diff --git a/contrib/flocker-builder/build_flocker.sh b/contrib/flocker-builder/build_flocker.sh new file mode 100644 index 0000000000..99e25998e1 --- /dev/null +++ b/contrib/flocker-builder/build_flocker.sh @@ -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 diff --git a/contrib/flocker-builder/dind_wrapper.sh b/contrib/flocker-builder/dind_wrapper.sh new file mode 100644 index 0000000000..c56bd720e9 --- /dev/null +++ b/contrib/flocker-builder/dind_wrapper.sh @@ -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//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 diff --git a/contrib/flocker-builder/run.sh b/contrib/flocker-builder/run.sh new file mode 100755 index 0000000000..0b6ee6c29c --- /dev/null +++ b/contrib/flocker-builder/run.sh @@ -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}"