#!/bin/bash export BUILD_DIR=${BUILD_DIR:-/usr/lib/build} CONTAINERD_PID=0 DOCKERD_PID=0 WEBSERVER_PID=0 cleanup_and_exit() { test -z "$1" && set 0 if test -n "$2" ; then if test "$1" -ne 0 ; then echo "$2" >&2 else echo "$2" fi fi if test "$1" != 0 ; then test -n "$WEBSERVER_PID" -a "$WEBSERVER_PID" != 0 && kill "$WEBSERVER_PID" test -n "$DOCKERD_PID" -a "$DOCKERD_PID" != 0 && kill "$DOCKERD_PID" test -n "$CONTAINERD_PID" -a "$CONTAINERD_PID" != 0 && kill "$CONTAINERD_PID" fi exit $1 } BUILD_ROOT= IS_UNSHARED= KILL= WEBSERVER= WEBSERVER_ONLY= while test -n "$1" ; do case "$1" in --root) BUILD_ROOT="$2" shift 2 ;; --webserver) WEBSERVER="$2" shift 2 ;; --webserver-only) WEBSERVER_ONLY="1" WEBSERVER="$2" shift 2 ;; --isunshared) IS_UNSHARED=true shift ;; --kill) KILL=true shift ;; *) break ;; esac done if test -n "$1" -o -z "$BUILD_ROOT" ; then cleanup_and_exit 1 "Usage: startdockerd --root " echo "Usage: startdockerd --root " fi if test -n "$KILL" ; then if test -e "$BUILD_ROOT/.startdockerd.pids" ; then read CONTAINERD_PID DOCKERD_PID WEBSERVER_PID < $BUILD_ROOT/.startdockerd.pids if test -n "$WEBSERVER_PID" -a "$WEBSERVER_PID" != 0 ; then echo "Stopping local repository server" kill "$WEBSERVER_PID" fi if test -n "$DOCKERD_PID" -a "$DOCKERD_PID" != 0 ; then echo "Stopping docker daemon" kill "$DOCKERD_PID" fi if test -n "$CONTAINERD_PID" -a "$CONTAINERD_PID" != 0 ; then echo "Stopping container daemon" kill "$CONTAINERD_PID" fi rm -f "$BUILD_ROOT/.startdockerd.pids" fi exit 0 fi rm -f $BUILD_ROOT/.startdockerd.pids if test -z "$IS_UNSHARED" -a -z "$WEBSERVER_ONLY" ; then echo "Unsharing environment" # unshare mounts and network exec unshare -m -n $BUILD_DIR/startdockerd --isunshared --root "$BUILD_ROOT" --webserver "$WEBSERVER" "$@" cleanup_and_exit 1 "exec unshare returned" fi # load needed kernel modules modprobe bridge br_netfilter modprobe nf_nat modprobe xt_conntrack modprobe ip_tables if test -n "$IS_UNSHARED" ; then # make mounts private mount --make-rprivate / # create loopback interface if test -x /sbin/ip ; then ip addr add 127.0.0.1/8 dev lo ip addr add ::1/128 dev lo ip link set lo up else ifconfig lo 127.0.0.1 up ifconfig lo add ::1/128 fi fi # setup cgroups if test "$BUILD_ROOT" != '/' ; then test -d /sys/fs/cgroup || cleanup_and_exit 1 "/sys/fs/cgroup does not exist" # make build root a mount point mount --rbind --make-private "$BUILD_ROOT" "$BUILD_ROOT" mount --make-rprivate "$BUILD_ROOT" # mount /sys if ! test -e $BUILD_ROOT/sys/block; then mkdir -p $BUILD_ROOT/sys mount -n -tsysfs sys $BUILD_ROOT/sys fi # bind mount cgroups mount --rbind /sys/fs/cgroup "$BUILD_ROOT/sys/fs/cgroup" mount --make-rslave "$BUILD_ROOT/sys/fs/cgroup" export DOCKER_RAMDISK=true fi # setup mounts test -e "$BUILD_ROOT/proc/self" || mount -n -tproc none $BUILD_ROOT/proc if test -n "$WEBSERVER" ; then echo "Starting local repository server" $BUILD_DIR/dummyhttpserver "$BUILD_ROOT" "$WEBSERVER" & WEBSERVER_PID=$! echo "$CONTAINERD_PID $DOCKERD_PID $WEBSERVER_PID" > $BUILD_ROOT/.startdockerd.pids fi if test -n "$WEBSERVER_ONLY" ; then echo "SKIPPING DOCKERD" exit 0 fi echo "Starting container daemon" CONTAINERD_BIN=/usr/sbin/containerd test -x $BUILD_ROOT/usr/bin/containerd && CONTAINERD_BIN=/usr/bin/containerd chroot $BUILD_ROOT $CONTAINERD_BIN --listen unix:///run/containerd/containerd.sock & CONTAINERD_PID=$! echo "$CONTAINERD_PID $DOCKERD_PID $WEBSERVER_PID" > $BUILD_ROOT/.startdockerd.pids echo "Starting docker daemon" chroot $BUILD_ROOT /usr/bin/dockerd --containerd /run/containerd/containerd.sock --bridge=none --add-runtime oci=/usr/bin/docker-runc & DOCKERD_PID=$! echo "$CONTAINERD_PID $DOCKERD_PID $WEBSERVER_PID" > $BUILD_ROOT/.startdockerd.pids echo "Waiting for docker daemon to complete startup" for i in 1 2 3 4 5 6 7 8 9 10 ; do chroot $BUILD_ROOT docker version >/dev/null 2>&1 && break sleep 1 done if ! chroot $BUILD_ROOT docker version >/dev/null 2>&1 ; then cleanup_and_exit 1 "Docker is dead" fi echo "Docker is running" exit 0