gentoo-openrc/Dockerfile.template: Fix FROM gentoo-portage -> gentoo-en-us
[dockerfile.git] / build.sh
1 #!/bin/sh
2 #
3 # Copyright (C) 2013-2014 W. Trevor King <wking@tremily.us>
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are met:
7 #
8 # * Redistributions of source code must retain the above copyright notice, this
9 # list of conditions and the following disclaimer.
10 #
11 # * Redistributions in binary form must reproduce the above copyright notice,
12 # this list of conditions and the following disclaimer in the documentation
13 # and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 # POSSIBILITY OF SUCH DAMAGE.
26
27 AUTHOR="${AUTHOR:-W. Trevor King <wking@tremily.us>}"
28 NAMESPACE="${NAMESPACE:-wking}"
29 DATE="${DATE:-20140724}"
30 MIRROR="${MIRROR:-http://distfiles.gentoo.org/}"
31 ARCH_URL="${ARCH_URL:-${MIRROR}releases/amd64/autobuilds/${DATE}/}"
32 STAGE3="${STAGE3:-stage3-amd64-${DATE}.tar.bz2}"
33 STAGE3_CONTENTS="${STAGE3_CONTENTS:-${STAGE3}.CONTENTS}"
34 STAGE3_DIGESTS="${STAGE3_DIGESTS:-${STAGE3}.DIGESTS.asc}"
35 PORTAGE_URL="${PORTAGE_URL:-${MIRROR}snapshots/}"
36 PORTAGE="${PORTAGE:-portage-${DATE}.tar.xz}"
37 PORTAGE_SIG="${PORTAGE_SIG:-${PORTAGE}.gpgsig}"
38
39 DOCKER_IO=$(command -v docker.io)
40 DOCKER="${DOCKER:-${DOCKER_IO:-docker}}"
41 BUILD_OPTS="${BUILD_OPTS:-}"
42
43 REPOS="${REPOS:-
44         portage
45         gentoo-portage
46         gentoo-utc
47         gentoo-en-us
48         gentoo-openrc
49         gentoo-syslog
50         gentoo-java
51         gentoo-layman
52         gentoo-node
53         buildbot
54         docker-registry
55         elasticsearch
56         hubot
57         irker
58         memcached
59         nginx
60         nginx-proxy
61         kibana
62         kibana-azure
63         ngircd
64         package-cache
65         postgresql
66         redis
67         salt-minion
68         stunnel
69         }"
70
71 die()
72 {
73         echo "$1"
74         exit 1
75 }
76
77 msg()
78 {
79         echo "$@"
80 }
81
82 REALPATH="${REALPATH:-$(command -v realpath)}"
83 if [ -z "${REALPATH}" ]; then
84         READLINK="${READLINK:-$(command -v readlink)}"
85         if [ -n "${READLINK}" ]; then
86                 REALPATH="${READLINK} -f"
87         else
88                 die "need realpath or readlink to canonicalize paths"
89         fi
90 fi
91
92 # Does "${NAMESPACE}/${REPO}:${DATE}" exist?
93 # Returns 0 (exists) or 1 (missing).
94 #
95 # Arguments:
96 #
97 # 1: REPO
98 repo_exists()
99 {
100         REPO="${1}"
101         IMAGES=$("${DOCKER}" images "${NAMESPACE}/${REPO}")
102         MATCHES=$(echo "${IMAGES}" | grep "${DATE}")
103         if [ -z "${MATCHES}" ]; then
104                 return 1
105         fi
106         return 0
107 }
108
109 # If they don't already exist:
110 #
111 # * download the stage3 and
112 # * create "${NAMESPACE}/gentoo:${DATE}"
113 #
114 # Forcibly tag "${NAMESPACE}/gentoo:${DATE}" with "latest"
115 import_stage3()
116 {
117         msg "import stage3"
118         if ! repo_exists gentoo; then
119                 # import stage3 image from Gentoo mirrors
120
121                 for FILE in "${STAGE3}" "${STAGE3_CONTENTS}" "${STAGE3_DIGESTS}"; do
122                         if [ ! -f "downloads/${FILE}" ]; then
123                                 wget -O "downloads/${FILE}" "${ARCH_URL}${FILE}" ||
124                                         die "failed to download ${ARCH_URL}${FILE}"
125                         fi
126                 done
127
128                 gpg --verify "downloads/${STAGE3_DIGESTS}" || die "insecure digests"
129                 SHA512_HASHES=$(grep -A1 SHA512 "downloads/${STAGE3_DIGESTS}" | grep -v '^--')
130                 SHA512_CHECK=$(cd downloads/ && (echo "${SHA512_HASHES}" | sha512sum -c))
131                 SHA512_FAILED=$(echo "${SHA512_CHECK}" | grep FAILED)
132                 if [ -n "${SHA512_FAILED}" ]; then
133                         die "${SHA512_FAILED}"
134                 fi
135
136                 msg "import ${NAMESPACE}/gentoo:${DATE}"
137                 "${DOCKER}" import - "${NAMESPACE}/gentoo:${DATE}" < "downloads/${STAGE3}" || die "failed to import"
138         fi
139
140         msg "tag ${NAMESPACE}/gentoo:latest"
141         "${DOCKER}" tag -f "${NAMESPACE}/gentoo:${DATE}" "${NAMESPACE}/gentoo:latest" || die "failed to tag"
142 }
143
144 # If they don't already exist:
145 #
146 # * download a portage snapshot and
147 # * create "${NAMESPACE}/portage-import:${DATE}"
148 #
149 # Forcibly tag "${NAMESPACE}/portage-import:${DATE}" with "latest"
150 import_portage()
151 {
152         msg "import portage"
153         if ! repo_exists portage-import; then
154                 # import portage image from Gentoo mirrors
155
156                 for FILE in "${PORTAGE}" "${PORTAGE_SIG}"; do
157                         if [ ! -f "downloads/${FILE}" ]; then
158                                 wget -O "downloads/${FILE}" "${PORTAGE_URL}${FILE}" ||
159                                         die "failed to download ${PORTAGE_URL}${FILE}"
160                         fi
161                 done
162
163                 gpg --verify "downloads/${PORTAGE_SIG}" "downloads/${PORTAGE}" || die "insecure digests"
164
165                 msg "import ${NAMESPACE}/portage-import:${DATE}"
166                 "${DOCKER}" import - "${NAMESPACE}/portage-import:${DATE}" < "downloads/${PORTAGE}" || die "failed to import"
167         fi
168
169         msg "tag ${NAMESPACE}/portage-import:latest"
170         "${DOCKER}" tag -f "${NAMESPACE}/portage-import:${DATE}" "${NAMESPACE}/portage-import:latest" || die "failed to tag"
171 }
172
173 # extract Busybox for the portage image
174 #
175 # Arguments:
176 #
177 # 1: SUBDIR target subdirectory for the busybox binary
178 extract_busybox()
179 {
180         SUBDIR="${1}"
181         msg "extract Busybox binary to ${SUBDIR}"
182         THIS_DIR=$(dirname $($REALPATH $0))
183         CONTAINER="${NAMESPACE}-gentoo-${DATE}-extract-busybox"
184         "${DOCKER}" run --name "${CONTAINER}" -v "${THIS_DIR}/${SUBDIR}/":/tmp "${NAMESPACE}/gentoo:${DATE}" cp /bin/busybox /tmp/
185         "${DOCKER}" rm "${CONTAINER}"
186 }
187
188 # If it doesn't already exist:
189 #
190 # * create "${NAMESPACE}/${REPO}:${DATE}" from
191 #   "${REPO}/Dockerfile.template"
192 #
193 # Forcibly tag "${NAMESPACE}/${REPO}:${DATE}" with "latest"
194 #
195 # Arguments:
196 #
197 # 1: REPO
198 build_repo()
199 {
200         REPO="${1}"
201         msg "build repo ${REPO}"
202         if ! repo_exists "${REPO}"; then
203                 if [ "${REPO}" = portage ]; then
204                         extract_busybox "${REPO}"
205                 fi
206
207                 env -i \
208                         NAMESPACE="${NAMESPACE}" \
209                         TAG="${DATE}" \
210                         MAINTAINER="${AUTHOR}" \
211                         envsubst '
212                                 ${NAMESPACE}
213                                 ${TAG}
214                                 ${MAINTAINER}
215                                 ' \
216                                 < "${REPO}/Dockerfile.template" > "${REPO}/Dockerfile"
217
218                 msg "build ${NAMESPACE}/${REPO}:${DATE}"
219                 "${DOCKER}" build ${BUILD_OPTS} -t "${NAMESPACE}/${REPO}:${DATE}" "${REPO}" || die "failed to build"
220         fi
221         msg "tag ${NAMESPACE}/${REPO}:latest"
222         "${DOCKER}" tag -f "${NAMESPACE}/${REPO}:${DATE}" "${NAMESPACE}/${REPO}:latest" || die "failed to tag"
223 }
224
225 build()
226 {
227         import_stage3
228         import_portage
229
230         for REPO in ${REPOS}; do
231                 build_repo "${REPO}"
232         done
233 }
234
235 missing()
236 {
237         for REPO in gentoo portage-import ${REPOS}; do
238                 if ! repo_exists "${REPO}"; then
239                         msg "${REPO}"
240                 fi
241         done
242 }
243
244 ACTION="${1:-build}"
245
246 case "${ACTION}" in
247 build) build ;;
248 missing) missing ;;
249 --help) msg "usage: ${0} [--help] {build|missing}" ;;
250 *) die "invalid action '${ACTION}'" ;;
251 esac