From 5535808cf6b1fc4a61af0d977462b4ed1f750077 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 13 Dec 2013 15:31:27 -0800 Subject: [PATCH] portage: Add a Portage-volume-exporting image This builds the Portage snapshot into a stand-alone volume, which can be mounted using -volumes-from. There's currently no Dockerfile-supported way to mount this for builds, so gentoo-portage still goes the emerge-webrsync route. We need something to fill the role of /bin/sh in the Portage-snapshot container, so I'm using the /bin/busybox from the 'gentoo' image. As of 2013-12-12, it's: sys-apps/busybox-1.21.0 USE="ipv6 pam static -livecd -make-symlinks -math -mdev -savedconfig (-selinux) -sep-usr -syslog -systemd" --- build.sh | 37 ++++++++++++++++++++++++---- portage/.gitignore | 1 + portage/Dockerfile.template | 37 ++++++++++++++++++++++++++++ portage/README.md | 48 +++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 portage/.gitignore create mode 100644 portage/Dockerfile.template create mode 100644 portage/README.md diff --git a/build.sh b/build.sh index e527ec6..9c72780 100755 --- a/build.sh +++ b/build.sh @@ -26,15 +26,18 @@ AUTHOR="${AUTHOR:-W. Trevor King }" 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 @@ -43,7 +46,7 @@ REPOS=" elasticsearch postgresql redis - " + }" die() { @@ -58,7 +61,7 @@ if [ -z "${STAGE3_MATCHES}" ]; then 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 @@ -75,6 +78,30 @@ fi 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}") diff --git a/portage/.gitignore b/portage/.gitignore new file mode 100644 index 0000000..a1a4c36 --- /dev/null +++ b/portage/.gitignore @@ -0,0 +1 @@ +busybox diff --git a/portage/Dockerfile.template b/portage/Dockerfile.template new file mode 100644 index 0000000..65d1520 --- /dev/null +++ b/portage/Dockerfile.template @@ -0,0 +1,37 @@ +# Copyright (C) 2013 W. Trevor King +# +# 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 + +# -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"] diff --git a/portage/README.md b/portage/README.md new file mode 100644 index 0000000..534124a --- /dev/null +++ b/portage/README.md @@ -0,0 +1,48 @@ +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 -- 2.26.2