summaryrefslogtreecommitdiff
path: root/startdockerd
blob: a321643b5ca0726a6209a6864f9ceaf3031cdf53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/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 <buildroot>"
    echo "Usage: startdockerd --root <buildroot>"
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