AUTHOR="${AUTHOR:-W. Trevor King <wking@tremily.us>}"
NAMESPACE="${NAMESPACE:-wking}"
-#PORTAGE="${PORTAGE:-/usr/portage}"
DATE="${DATE:-20131212}"
MIRROR="${MIRROR:-http://mirror.mcs.anl.gov/pub/gentoo/}"
-ARCH_URL="${ARCH_URL:-${MIRROR}/releases/amd64/current-stage3/}"
+ARCH_URL="${ARCH_URL:-${MIRROR}releases/amd64/current-stage3/}"
STAGE3="${STAGE3:-stage3-amd64-${DATE}.tar.bz2}"
STAGE3_CONTENTS="${STAGE3_CONTENTS:-${STAGE3}.CONTENTS}"
STAGE3_DIGESTS="${STAGE3_DIGESTS:-${STAGE3}.DIGESTS.asc}"
+PORTAGE_URL="${PORTAGE_URL:-${MIRROR}snapshots/}"
+PORTAGE="${PORTAGE:-portage-${DATE}.tar.xz}"
+PORTAGE_SIG="${PORTAGE_SIG:-${PORTAGE}.gpgsig}"
-REPOS="
+REPOS="${REPOS:-
+ portage
gentoo-portage
gentoo-en-us
gentoo-syslog
elasticsearch
postgresql
redis
- "
+ }"
die()
{
for FILE in "${STAGE3}" "${STAGE3_CONTENTS}" "${STAGE3_DIGESTS}"; do
if [ ! -f "downloads/${FILE}" ]; then
- wget -O "downloads/${FILE}" "${ARCH_URL}/${FILE}"
+ wget -O "downloads/${FILE}" "${ARCH_URL}${FILE}"
fi
done
docker tag -f "${NAMESPACE}/gentoo:${DATE}" "${NAMESPACE}/gentoo:latest" || die "failed to tag"
+PORTAGE_IMAGES=$(docker images "${NAMESPACE}/portage-import")
+PORTAGE_MATCHES=$(echo "${PORTAGE_IMAGES}" | grep "${DATE}")
+if [ -z "${PORTAGE_MATCHES}" ]; then
+ # import portage image from Gentoo mirrors
+
+ for FILE in "${PORTAGE}" "${PORTAGE_SIG}"; do
+ if [ ! -f "downloads/${FILE}" ]; then
+ wget -O "downloads/${FILE}" "${PORTAGE_URL}${FILE}"
+ fi
+ done
+
+ gpg --verify "downloads/${PORTAGE_SIG}" "downloads/${PORTAGE}" || die "insecure digests"
+
+ docker import - "${NAMESPACE}/portage-import:${DATE}" < "downloads/${PORTAGE}" || die "failed to import"
+fi
+
+docker tag -f "${NAMESPACE}/portage-import:${DATE}" "${NAMESPACE}/portage-import:latest" || die "failed to tag"
+
+# extract Busybox for the portage image
+THIS_DIR=$(dirname $(realpath $0))
+CONTAINER="${NAMESPACE}-gentoo-${DATE}-extract-busybox"
+docker run -name "${CONTAINER}" -v "${THIS_DIR}/portage/":/tmp "${NAMESPACE}/gentoo:${DATE}" cp /bin/busybox /tmp/
+docker rm "${CONTAINER}"
+
for REPO in ${REPOS}; do
REPO_IMAGES=$(docker images "${NAMESPACE}/${REPO}")
REPO_MATCHES=$(echo "${REPO_IMAGES}" | grep "${DATE}")
--- /dev/null
+# Copyright (C) 2013 W. Trevor King <wking@tremily.us>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+FROM NAMESPACE/portage-import:TAG
+MAINTAINER A. U. Thor <author@example.com>
+
+# -volumes-from doesn't map names, so we need to shift /portage to
+# /usr/portage. Add a statically-linked BusyBox for RUN commands.
+ADD busybox /bin/sh
+ENTRYPOINT ["/bin/sh"]
+RUN mkdir /usr/
+RUN mv /portage /usr/portage
+VOLUME ["/usr/portage"]
+
+# We need a dummy process for this container
+CMD ["tail", "-f", "/portage/profiles/repo_name"]
--- /dev/null
+Use volume mounts to avoid including the Portage tree in your images:
+
+ $ docker run -d -name portage wking/portage
+
+This exports a [VOLUME][] which you can [mount][volumes-from] from
+another container:
+
+ $ docker run -volumes-from portage -i -t wking/gentoo /bin/bash
+ d1a49abc4b3c / # ls /usr/portage/
+ app-accessibility dev-python mail-mta sci-mathematics
+ …
+
+Changes (e.g. distfiles downloads) are preserved between mounts by the
+continuously-running `portage` container. Let's install something in
+the first container:
+
+ d1a49abc4b3c / # emerge -av netcat
+ …
+ These are the packages that would be fetched, in order:
+
+ Calculating dependencies... done!
+ [ebuild N ] dev-libs/libmix-2.05-r6 USE="-static-libs" 78 kB
+ [ebuild N ] net-analyzer/netcat-110-r9 USE="crypt ipv6 -static" 108 kB
+
+ Total: 2 packages (2 new), Size of downloads: 186 kB
+
+Now kill that container and spin up another one:
+
+ $ docker run -volumes-from portage -i -t wking/gentoo /bin/bash
+ 187adaf8babd / # emerge -pv netcat
+ …
+ These are the packages that would be merged, in order:
+
+ Calculating dependencies... done!
+ [ebuild N ] dev-libs/libmix-2.05-r6 USE="-static-libs" 0 kB
+ [ebuild N ] net-analyzer/netcat-110-r9 USE="crypt ipv6 -static" 0 kB
+
+ Total: 2 packages (2 new), Size of downloads: 0 kB
+ …
+
+The local Portage cache, read news items, etc. stored outside of
+`/usr/portage` (e.g. in `/var/cache/edb`, `/var/lib/gentoo/news`, …)
+will still be local to your client containers, so you'll get
+promptings for reading the news on both `d1a49abc4b3c` and
+`187adaf8babd`.
+
+[VOLUME]: http://docs.docker.io/en/latest/use/builder/#volume
+[volumes-from]: http://docs.docker.io/en/latest/use/working_with_volumes/#mount-volumes-from-an-existing-container