-
Notifications
You must be signed in to change notification settings - Fork 41
/
entrypoint.sh
executable file
·172 lines (143 loc) · 4.85 KB
/
entrypoint.sh
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
#!/usr/bin/env bash
# Inspired by concourse/docker-image-resource:
# https://github.com/concourse/docker-image-resource/blob/master/assets/common.sh
set -o errexit -o pipefail -o nounset
# Waits DOCKERD_TIMEOUT seconds for startup (default: 60)
DOCKERD_TIMEOUT="${DOCKERD_TIMEOUT:-60}"
# Accepts optional DOCKER_OPTS (default: --data-root /scratch/docker)
DOCKER_OPTS="${DOCKER_OPTS:-}"
# Constants
DOCKERD_PID_FILE="/tmp/docker.pid"
DOCKERD_LOG_FILE="/tmp/docker.log"
sanitize_cgroups() {
local cgroup="/sys/fs/cgroup"
mkdir -p "${cgroup}"
if ! mountpoint -q "${cgroup}"; then
if ! mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup "${cgroup}"; then
echo >&2 "Could not make a tmpfs mount. Did you use --privileged?"
exit 1
fi
fi
mount -o remount,rw "${cgroup}"
# Skip AppArmor
# See: https://github.com/moby/moby/commit/de191e86321f7d3136ff42ff75826b8107399497
export container=docker
# Mount /sys/kernel/security
if [[ -d /sys/kernel/security ]] && ! mountpoint -q /sys/kernel/security; then
if ! mount -t securityfs none /sys/kernel/security; then
echo >&2 "Could not mount /sys/kernel/security."
echo >&2 "AppArmor detection and --privileged mode might break."
fi
fi
sed -e 1d /proc/cgroups | while read sys hierarchy num enabled; do
if [[ "${enabled}" != "1" ]]; then
# subsystem disabled; skip
continue
fi
grouping="$(cat /proc/self/cgroup | cut -d: -f2 | grep "\\<${sys}\\>")"
if [[ -z "${grouping}" ]]; then
# subsystem not mounted anywhere; mount it on its own
grouping="${sys}"
fi
mountpoint="${cgroup}/${grouping}"
mkdir -p "${mountpoint}"
# clear out existing mount to make sure new one is read-write
if mountpoint -q "${mountpoint}"; then
umount "${mountpoint}"
fi
mount -n -t cgroup -o "${grouping}" cgroup "${mountpoint}"
if [[ "${grouping}" != "${sys}" ]]; then
if [[ -L "${cgroup}/${sys}" ]]; then
rm "${cgroup}/${sys}"
fi
ln -s "${mountpoint}" "${cgroup}/${sys}"
fi
done
# Initialize systemd cgroup if host isn't using systemd.
# Workaround for https://github.com/docker/for-linux/issues/219
if ! [[ -d /sys/fs/cgroup/systemd ]]; then
mkdir "${cgroup}/systemd"
mount -t cgroup -o none,name=systemd cgroup "${cgroup}/systemd"
fi
}
# Setup container environment and start docker daemon in the background.
start_docker() {
echo >&2 "Setting up Docker environment..."
mkdir -p /var/log
mkdir -p /var/run
sanitize_cgroups
# check for /proc/sys being mounted readonly, as systemd does
if grep '/proc/sys\s\+\w\+\s\+ro,' /proc/mounts >/dev/null; then
mount -o remount,rw /proc/sys
fi
local docker_opts="${DOCKER_OPTS:-}"
# Pass through `--garden-mtu` from gardian container
if [[ "${docker_opts}" != *'--mtu'* ]]; then
local mtu="$(cat /sys/class/net/$(ip route get 8.8.8.8|awk '{ print $5 }')/mtu)"
docker_opts+=" --mtu ${mtu}"
fi
# Use Concourse's scratch volume to bypass the graph filesystem by default
if [[ "${docker_opts}" != *'--data-root'* ]] && [[ "${docker_opts}" != *'--graph'* ]]; then
docker_opts+=' --data-root /scratch/docker'
fi
rm -f "${DOCKERD_PID_FILE}"
touch "${DOCKERD_LOG_FILE}"
echo >&2 "Starting Docker..."
dockerd ${docker_opts} &>"${DOCKERD_LOG_FILE}" &
echo "$!" > "${DOCKERD_PID_FILE}"
}
# Wait for docker daemon to be healthy
# Timeout after DOCKERD_TIMEOUT seconds
await_docker() {
local timeout="${DOCKERD_TIMEOUT}"
echo >&2 "Waiting ${timeout} seconds for Docker to be available..."
local start=${SECONDS}
timeout=$(( timeout + start ))
until docker info &>/dev/null; do
if (( SECONDS >= timeout )); then
echo >&2 'Timed out trying to connect to docker daemon.'
if [[ -f "${DOCKERD_LOG_FILE}" ]]; then
echo >&2 '---DOCKERD LOGS---'
cat >&2 "${DOCKERD_LOG_FILE}"
fi
exit 1
fi
if [[ -f "${DOCKERD_PID_FILE}" ]] && ! kill -0 $(cat "${DOCKERD_PID_FILE}"); then
echo >&2 'Docker daemon failed to start.'
if [[ -f "${DOCKERD_LOG_FILE}" ]]; then
echo >&2 '---DOCKERD LOGS---'
cat >&2 "${DOCKERD_LOG_FILE}"
fi
exit 1
fi
sleep 1
done
local duration=$(( SECONDS - start ))
echo >&2 "Docker available after ${duration} seconds."
}
# Gracefully stop Docker daemon.
stop_docker() {
if ! [[ -f "${DOCKERD_PID_FILE}" ]]; then
return 0
fi
local docker_pid="$(cat ${DOCKERD_PID_FILE})"
if [[ -z "${docker_pid}" ]]; then
return 0
fi
echo >&2 "Terminating Docker daemon."
kill -TERM ${docker_pid}
local start=${SECONDS}
echo >&2 "Waiting for Docker daemon to exit..."
wait ${docker_pid}
local duration=$(( SECONDS - start ))
echo >&2 "Docker exited after ${duration} seconds."
}
start_docker
trap stop_docker EXIT
await_docker
# do not exec, because exec disables traps
if [[ "$#" != "0" ]]; then
"$@"
else
bash --login
fi