lxc-download.in revision 7d540a266389ab981c87a64050b0ba050e147e15
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber#!/bin/sh
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Client script for LXC container images.
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber#
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Copyright © 2014 Stéphane Graber <stgraber@ubuntu.com>
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber#
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# This library is free software; you can redistribute it and/or
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# modify it under the terms of the GNU Lesser General Public
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# License as published by the Free Software Foundation; either
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# version 2.1 of the License, or (at your option) any later version.
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# This library is distributed in the hope that it will be useful,
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# but WITHOUT ANY WARRANTY; without even the implied warranty of
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Lesser General Public License for more details.
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# You should have received a copy of the GNU Lesser General Public
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# License along with this library; if not, write to the Free Software
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# USA
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberset -eu
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberLOCALSTATEDIR="@LOCALSTATEDIR@"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberLXC_HOOK_DIR="@LXCHOOKDIR@"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberLXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Defaults
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberDOWNLOAD_ARCH=
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_BUILD=
ce7aee4d913e4c181502e3c2e6373c30a3db55b9Stéphane GraberDOWNLOAD_COMPAT_LEVEL=2
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_DIST=
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberDOWNLOAD_FLUSH_CACHE="false"
41670b35b0d7a11c7fa7d04e2535495dc90b76a9Stéphane GraberDOWNLOAD_FORCE_CACHE="false"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_INTERACTIVE="false"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_KEYID="0xBAEFF88C22F6E216"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_KEYSERVER="hkp://pool.sks-keyservers.net"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_LIST_IMAGES="false"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberDOWNLOAD_MODE="system"
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane GraberDOWNLOAD_READY_GPG="false"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_RELEASE=
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_SERVER="images.linuxcontainers.org"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_SHOW_GPG_WARNING="true"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_SHOW_HTTP_WARNING="true"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_TARGET="system"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_URL=
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_USE_CACHE="false"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_VALIDATE="true"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberDOWNLOAD_VARIANT="default"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberLXC_MAPPED_GID=
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberLXC_MAPPED_UID=
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberLXC_NAME=
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberLXC_PATH=
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberLXC_ROOTFS=
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
4eb706b3ce9891f86ff3f9b5b5d063922df9f6b6Stéphane Graber# Deal with GPG over http proxy
4eb706b3ce9891f86ff3f9b5b5d063922df9f6b6Stéphane Graberif [ -n "${http_proxy:-}" ]; then
ef9512b491f12ffd64030b15300dcfc448f516e0Stéphane Graber DOWNLOAD_KEYSERVER="hkp://p80.pool.sks-keyservers.net:80"
4eb706b3ce9891f86ff3f9b5b5d063922df9f6b6Stéphane Graberfi
4eb706b3ce9891f86ff3f9b5b5d063922df9f6b6Stéphane Graber
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graber# Make sure the usual locations are in PATH
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graberexport PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Some useful functions
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Grabercleanup() {
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ -d "$DOWNLOAD_TEMP" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber rm -Rf $DOWNLOAD_TEMP
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber}
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graberwget_wrapper() {
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber for i in $(seq 3); do
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber if wget $@; then
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber return 0
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber fi
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber done
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber return 1
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber}
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberdownload_file() {
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber if ! wget_wrapper -T 30 -q https://${DOWNLOAD_SERVER}/$1 -O $2 >/dev/null 2>&1; then
acabe1faee82d44db391345a8a51b9dec3dc0229Stéphane Graber if ! wget_wrapper -T 30 -q http://${DOWNLOAD_SERVER}/$1 -O $2 >/dev/null 2>&1; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ "$3" = "noexit" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber return 1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber else
fad967669817061cda3aafc40be04dcb712a4767Dwight Engen echo "ERROR: Failed to download http://${DOWNLOAD_SERVER}/$1" 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber exit 1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber elif [ "$DOWNLOAD_SHOW_HTTP_WARNING" = "true" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber DOWNLOAD_SHOW_HTTP_WARNING="false"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "WARNING: Failed to download the file over HTTPs." 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo -n " The file was instead download over HTTP. " 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "A server replay attack may be possible!" 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber}
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
fad967669817061cda3aafc40be04dcb712a4767Dwight Engendownload_sig() {
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber if ! download_file $1 $2 noexit; then
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber if [ "$DOWNLOAD_VALIDATE" = "true" ]; then
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber if [ "$3" = "normal" ]; then
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber echo "ERROR: Failed to download http://${DOWNLOAD_SERVER}/$1" 1>&2
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber exit 1
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber else
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber return 1
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber fi
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber else
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber return 0
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber fi
fad967669817061cda3aafc40be04dcb712a4767Dwight Engen fi
fad967669817061cda3aafc40be04dcb712a4767Dwight Engen}
fad967669817061cda3aafc40be04dcb712a4767Dwight Engen
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Grabergpg_setup() {
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ "$DOWNLOAD_VALIDATE" = "false" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber return
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber if [ "$DOWNLOAD_READY_GPG" = "true" ]; then
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber return
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber fi
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "Setting up the GPG keyring"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber mkdir -p "$DOWNLOAD_TEMP/gpg"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber chmod 700 "$DOWNLOAD_TEMP/gpg"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber export GNUPGHOME="$DOWNLOAD_TEMP/gpg"
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber success=
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber for i in $(seq 3); do
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber if gpg --keyserver $DOWNLOAD_KEYSERVER \
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --recv-keys ${DOWNLOAD_KEYID} >/dev/null 2>&1; then
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber success=1
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber break
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber fi
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber done
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber
809a1539a3d83d0ea6f277519e6d43e75ccf1013Stéphane Graber if [ -z "$success" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "ERROR: Unable to fetch GPG key from keyserver."
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber exit 1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber DOWNLOAD_READY_GPG="true"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber}
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Grabergpg_validate() {
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ "$DOWNLOAD_VALIDATE" = "false" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ "$DOWNLOAD_SHOW_GPG_WARNING" = "true" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "WARNING: Running without gpg validation!" 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber DOWNLOAD_SHOW_GPG_WARNING="false"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber return 0
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if ! gpg --verify $1 >/dev/zero 2>&1; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "ERROR: Invalid signature for $1" 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber exit 1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber}
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberin_userns() {
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber [ -e /proc/self/uid_map ] || { echo no; return; }
9f15e86afa60f9f29658a3e7f60104a5bc23e86bStéphane Graber while read line; do
9f15e86afa60f9f29658a3e7f60104a5bc23e86bStéphane Graber fields=$(echo $line | awk '{ print $1 " " $2 " " $3 }')
9f15e86afa60f9f29658a3e7f60104a5bc23e86bStéphane Graber [ "$fields" = "0 0 4294967295" ] && { echo no; return; } || true
9f15e86afa60f9f29658a3e7f60104a5bc23e86bStéphane Graber echo $fields | grep -q " 0 1$" && { echo userns-root; return; } || true
9f15e86afa60f9f29658a3e7f60104a5bc23e86bStéphane Graber done < /proc/self/uid_map
a1b6244eb510affcd448a9ddf25603e532f4dec6Stéphane Graber
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber [ "$(cat /proc/self/uid_map)" = "$(cat /proc/1/uid_map)" ] && \
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber { echo userns-root; return; }
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo yes
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber}
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberrelevant_file() {
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber FILE_PATH="${LXC_CACHE_PATH}/$1"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ -e "${FILE_PATH}-${DOWNLOAD_MODE}" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber FILE_PATH="${FILE_PATH}-${DOWNLOAD_MODE}"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ -e "$FILE_PATH.${DOWNLOAD_COMPAT_LEVEL}" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber FILE_PATH="${FILE_PATH}.${DOWNLOAD_COMPAT_LEVEL}"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo $FILE_PATH
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber}
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberusage() {
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber cat <<EOF
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberLXC container image downloader
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
7d540a266389ab981c87a64050b0ba050e147e15Michael AdamSpecial arguments:
7d540a266389ab981c87a64050b0ba050e147e15Michael Adam[ -h | --help ]: Print this help message and exit.
7d540a266389ab981c87a64050b0ba050e147e15Michael Adam[ -l | --list ]: List all available images and exit.
7d540a266389ab981c87a64050b0ba050e147e15Michael Adam
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberRequired arguments:
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ -d | --dist <distribution> ]: The name of the distribution
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ -r | --release <release> ]: Release name/version
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ -a | --arch <architecture> ]: Architecture of the container
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberOptional arguments:
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ --variant <variant> ]: Variant of the image (default: "default")
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ --server <server> ]: Image server (default: "images.linuxcontainers.org")
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ --keyid <keyid> ]: GPG keyid (default: 0x...)
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ --keyserver <keyserver> ]: GPG keyserver to use
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ --no-validate ]: Disable GPG validation (not recommended)
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ --flush-cache ]: Flush the local copy (if present)
e145b7bb6d62fe3ba279ec0730117edea9c2d538Michael Adam[ --force-cache ]: Force the use of the local copy even if expired
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberLXC internal arguments (do not pass manually!):
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ --name <name> ]: The container name
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ --path <path> ]: The path to the container
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber[ --rootfs <rootfs> ]: The path to the container's rootfs
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn[ --mapped-uid <map> ]: A uid map (user namespaces)
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn[ --mapped-gid <map> ]: A gid map (user namespaces)
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberEOF
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber return 0
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber}
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graberoptions=$(getopt -o d:r:a:hl -l dist:,release:,arch:,help,list,variant:,\
3cd988ccdbbb5b5794b19ad1165e48168c2dd1d9Stéphane Graberserver:,keyid:,keyserver:,no-validate,flush-cache,force-cache,name:,path:,\
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallynrootfs:,mapped-uid:,mapped-gid: -- "$@")
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ $? -ne 0 ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber usage
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber exit 1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Grabereval set -- "$options"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberwhile :; do
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber case "$1" in
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber -h|--help) usage && exit 1;;
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber -l|--list) DOWNLOAD_LIST_IMAGES="true"; shift 1;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber -d|--dist) DOWNLOAD_DIST=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber -r|--release) DOWNLOAD_RELEASE=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber -a|--arch) DOWNLOAD_ARCH=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --variant) DOWNLOAD_VARIANT=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --server) DOWNLOAD_SERVER=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --keyid) DOWNLOAD_KEYID=$2; shift 2;;
3cd988ccdbbb5b5794b19ad1165e48168c2dd1d9Stéphane Graber --keyserver) DOWNLOAD_KEYSERVER=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --no-validate) DOWNLOAD_VALIDATE="false"; shift 1;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --flush-cache) DOWNLOAD_FLUSH_CACHE="true"; shift 1;;
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber --force-cache) DOWNLOAD_FORCE_CACHE="true"; shift 1;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --name) LXC_NAME=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --path) LXC_PATH=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --rootfs) LXC_ROOTFS=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber --mapped-uid) LXC_MAPPED_UID=$2; shift 2;;
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn --mapped-gid) LXC_MAPPED_GID=$2; shift 2;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber *) break;;
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber esac
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberdone
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Check for required binaries
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfor bin in tar xz wget; do
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if ! type $bin >/dev/null 2>&1; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "ERROR: Missing required tool: $bin" 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber exit 1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberdone
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Check for GPG
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ "$DOWNLOAD_VALIDATE" = "true" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if ! type gpg >/dev/null 2>&1; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "ERROR: Missing recommended tool: gpg" 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "You can workaround this by using --no-validate." 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber exit 1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Check that we have all variables we need
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ -z "$LXC_NAME" ] || [ -z "$LXC_PATH" ] || [ -z "$LXC_ROOTFS" ]; then
308f4f391a0a0f2bd29a44a7b2be1e43abc61912Michael Adam if [ "$DOWNLOAD_LIST_IMAGES" != "true" ]; then
308f4f391a0a0f2bd29a44a7b2be1e43abc61912Michael Adam echo "ERROR: Not running through LXC." 1>&2
308f4f391a0a0f2bd29a44a7b2be1e43abc61912Michael Adam exit 1
308f4f391a0a0f2bd29a44a7b2be1e43abc61912Michael Adam fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane GraberUSERNS=$(in_userns)
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graberif [ "$USERNS" != "no" ]; then
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber if [ "$USERNS" = "yes" ]; then
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber if [ -z "$LXC_MAPPED_UID" ] || [ "$LXC_MAPPED_UID" = "-1" ]; then
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber echo "ERROR: In a user namespace without a map." 1>&2
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber exit 1
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber fi
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber DOWNLOAD_MODE="user"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber DOWNLOAD_TARGET="user"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber else
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber DOWNLOAD_MODE="user"
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graber DOWNLOAD_TARGET="system"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graberif [ -z "$DOWNLOAD_DIST" ] || [ -z "$DOWNLOAD_RELEASE" ] || \
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber [ -z "$DOWNLOAD_ARCH" ]; then
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber DOWNLOAD_INTERACTIVE="true"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Trap all exit signals
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Grabertrap cleanup EXIT HUP INT TERM
843a58743e6ba9e8efa61aede4cdf32be43af114Stéphane Graber
843a58743e6ba9e8efa61aede4cdf32be43af114Stéphane Graberif ! type mktemp >/dev/null 2>&1; then
843a58743e6ba9e8efa61aede4cdf32be43af114Stéphane Graber DOWNLOAD_TEMP=/tmp/lxc-download.$$
843a58743e6ba9e8efa61aede4cdf32be43af114Stéphane Graber mkdir -p $DOWNLOAD_TEMP
843a58743e6ba9e8efa61aede4cdf32be43af114Stéphane Graberelse
843a58743e6ba9e8efa61aede4cdf32be43af114Stéphane Graber DOWNLOAD_TEMP=$(mktemp -d)
843a58743e6ba9e8efa61aede4cdf32be43af114Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber# Simply list images
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graberif [ "$DOWNLOAD_LIST_IMAGES" = "true" ] || \
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber [ "$DOWNLOAD_INTERACTIVE" = "true" ]; then
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber # Initialize GPG
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber gpg_setup
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber # Grab the index
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber DOWNLOAD_INDEX_PATH=/meta/1.0/index-${DOWNLOAD_MODE}
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber echo "Downloading the image index"
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber if ! download_file ${DOWNLOAD_INDEX_PATH}.${DOWNLOAD_COMPAT_LEVEL} \
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber ${DOWNLOAD_TEMP}/index noexit ||
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber ! download_sig ${DOWNLOAD_INDEX_PATH}.${DOWNLOAD_COMPAT_LEVEL}.asc \
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber ${DOWNLOAD_TEMP}/index.asc noexit; then
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber download_file ${DOWNLOAD_INDEX_PATH} ${DOWNLOAD_TEMP}/index normal
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber download_sig ${DOWNLOAD_INDEX_PATH}.asc \
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber ${DOWNLOAD_TEMP}/index.asc normal
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber fi
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber gpg_validate ${DOWNLOAD_TEMP}/index.asc
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber # Parse it
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber echo ""
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber echo "---"
96283b546081e7ff709968378fca25cb44f1ab6cStéphane Graber printf "DIST\tRELEASE\tARCH\tVARIANT\tBUILD\n"
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber echo "---"
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber while read line; do
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber # Basic CSV parser
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber OLD_IFS=$IFS
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber IFS=";"
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber set -- $line
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber IFS=$OLD_IFS
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber [ -n "$DOWNLOAD_DIST" ] && [ "$1" != "$DOWNLOAD_DIST" ] && continue
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber [ -n "$DOWNLOAD_RELEASE" ] && [ "$2" != "$DOWNLOAD_RELEASE" ] && continue
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber [ -n "$DOWNLOAD_ARCH" ] && [ "$3" != "$DOWNLOAD_ARCH" ] && continue
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber [ -n "$DOWNLOAD_VARIANT" ] && [ "$4" != "$DOWNLOAD_VARIANT" ] && continue
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber [ -z "$5" ] || [ -z "$6" ] && continue
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber
96283b546081e7ff709968378fca25cb44f1ab6cStéphane Graber printf "$1\t$2\t$3\t$4\t$5\n"
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber done < ${DOWNLOAD_TEMP}/index
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber echo "---"
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber if [ "$DOWNLOAD_LIST_IMAGES" = "true" ]; then
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber exit 1
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber fi
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber # Interactive mode
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber echo ""
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber if [ -z "$DOWNLOAD_DIST" ]; then
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber echo -n "Distribution: "
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber read DOWNLOAD_DIST
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber fi
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber if [ -z "$DOWNLOAD_RELEASE" ]; then
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber echo -n "Release: "
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber read DOWNLOAD_RELEASE
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber fi
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber if [ -z "$DOWNLOAD_ARCH" ]; then
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber echo -n "Architecture: "
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber read DOWNLOAD_ARCH
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber fi
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber
b0f0932a944abf6425e9f185dea9c6d9ba6e8436Stéphane Graber echo ""
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graberfi
10a5fab6f3ad5cab234b198da31633e41c8ee364Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Setup the cache
f74e080cf75f958b3e52dff9e858fd722f66301eStéphane Graberif [ "$DOWNLOAD_TARGET" = "system" ]; then
b56661fead638d40eaee54d9134063098e4fa51cStéphane Graber LXC_CACHE_BASE="$LOCALSTATEDIR/cache/lxc/"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberelse
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber LXC_CACHE_BASE="$HOME/.cache/lxc/"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
b56661fead638d40eaee54d9134063098e4fa51cStéphane GraberLXC_CACHE_PATH="$LXC_CACHE_BASE/download/$DOWNLOAD_DIST"
b56661fead638d40eaee54d9134063098e4fa51cStéphane GraberLXC_CACHE_PATH="$LXC_CACHE_PATH/$DOWNLOAD_RELEASE/$DOWNLOAD_ARCH/"
b56661fead638d40eaee54d9134063098e4fa51cStéphane GraberLXC_CACHE_PATH="$LXC_CACHE_PATH/$DOWNLOAD_VARIANT"
b56661fead638d40eaee54d9134063098e4fa51cStéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ -d "$LXC_CACHE_PATH" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ "$DOWNLOAD_FLUSH_CACHE" = "true" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "Flushing the cache..."
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber rm -Rf $LXC_CACHE_PATH
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber elif [ "$DOWNLOAD_FORCE_CACHE" = "true" ]; then
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber DOWNLOAD_USE_CACHE="true"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber else
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber DOWNLOAD_USE_CACHE="true"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ -e "$(relevant_file expiry)" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ "$(cat $(relevant_file expiry))" -lt $(date +%s) ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "The cached copy has expired, re-downloading..."
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber DOWNLOAD_USE_CACHE="false"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Download what's needed
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ "$DOWNLOAD_USE_CACHE" = "false" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber # Initialize GPG
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber gpg_setup
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber # Grab the index
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber DOWNLOAD_INDEX_PATH=/meta/1.0/index-${DOWNLOAD_MODE}
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "Downloading the image index"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if ! download_file ${DOWNLOAD_INDEX_PATH}.${DOWNLOAD_COMPAT_LEVEL} \
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber ${DOWNLOAD_TEMP}/index noexit ||
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber ! download_sig ${DOWNLOAD_INDEX_PATH}.${DOWNLOAD_COMPAT_LEVEL}.asc \
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber ${DOWNLOAD_TEMP}/index.asc noexit; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber download_file ${DOWNLOAD_INDEX_PATH} ${DOWNLOAD_TEMP}/index normal
fad967669817061cda3aafc40be04dcb712a4767Dwight Engen download_sig ${DOWNLOAD_INDEX_PATH}.asc \
33aa351ac13936fb2549403f18a44fed32b2edfbStéphane Graber ${DOWNLOAD_TEMP}/index.asc normal
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber gpg_validate ${DOWNLOAD_TEMP}/index.asc
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber # Parse it
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber while read line; do
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber # Basic CSV parser
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber OLD_IFS=$IFS
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber IFS=";"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber set -- $line
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber IFS=$OLD_IFS
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ "$1" != "$DOWNLOAD_DIST" ] || \
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber [ "$2" != "$DOWNLOAD_RELEASE" ] || \
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber [ "$3" != "$DOWNLOAD_ARCH" ] || \
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber [ "$4" != "$DOWNLOAD_VARIANT" ] || \
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber [ -z "$6" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber continue
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber DOWNLOAD_BUILD=$5
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber DOWNLOAD_URL=$6
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber break
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber done < ${DOWNLOAD_TEMP}/index
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber if [ -z "$DOWNLOAD_URL" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "ERROR: Couldn't find a matching image." 1>&1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber exit 1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber if [ -d "$LXC_CACHE_PATH" ] && [ -f "$LXC_CACHE_PATH/build_id" ] && \
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber [ "$(cat $LXC_CACHE_PATH/build_id)" = "$DOWNLOAD_BUILD" ]; then
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber echo "The cache is already up to date."
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber echo "Using image from local cache"
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber else
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber # Download the actual files
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber echo "Downloading the rootfs"
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber download_file $DOWNLOAD_URL/rootfs.tar.xz \
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber ${DOWNLOAD_TEMP}/rootfs.tar.xz normal
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber download_sig $DOWNLOAD_URL/rootfs.tar.xz.asc \
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber ${DOWNLOAD_TEMP}/rootfs.tar.xz.asc normal
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber gpg_validate ${DOWNLOAD_TEMP}/rootfs.tar.xz.asc
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber echo "Downloading the metadata"
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber download_file $DOWNLOAD_URL/meta.tar.xz \
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber ${DOWNLOAD_TEMP}/meta.tar.xz normal
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber download_sig $DOWNLOAD_URL/meta.tar.xz.asc \
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber ${DOWNLOAD_TEMP}/meta.tar.xz.asc normal
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber gpg_validate ${DOWNLOAD_TEMP}/meta.tar.xz.asc
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber if [ -d $LXC_CACHE_PATH ]; then
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber rm -Rf $LXC_CACHE_PATH
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber fi
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber mkdir -p $LXC_CACHE_PATH
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber mv ${DOWNLOAD_TEMP}/rootfs.tar.xz $LXC_CACHE_PATH
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber if ! tar Jxf ${DOWNLOAD_TEMP}/meta.tar.xz -C $LXC_CACHE_PATH; then
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber echo "ERROR: Invalid rootfs tarball." 2>&1
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber exit 1
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber echo $DOWNLOAD_BUILD > $LXC_CACHE_PATH/build_id
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then
0d656b0549e67635ad9c24474b82dfa26e1f4512Stéphane Graber chown -R $LXC_MAPPED_UID $LXC_CACHE_BASE >/dev/null 2>&1 || true
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber fi
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn if [ -n "$LXC_MAPPED_GID" ] && [ "$LXC_MAPPED_GID" != "-1" ]; then
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn chgrp -R $LXC_MAPPED_GID $LXC_CACHE_BASE >/dev/null 2>&1 || true
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn fi
9accc2efea59a685942501c13e8eb7a21f74a5f6Stéphane Graber echo "The image cache is now ready"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberelse
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "Using image from local cache"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Unpack the rootfs
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberecho "Unpacking the rootfs"
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Graber
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane GraberEXCLUDES=""
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Graberexcludelist=$(relevant_file excludes)
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Graberif [ -f "${excludelist}" ]; then
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Graber while read line; do
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Graber EXCLUDES="$EXCLUDES --exclude=$line"
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Graber done < $excludelist
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Grabertar --anchored ${EXCLUDES} --numeric-owner -xpJf \
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Graber ${LXC_CACHE_PATH}/rootfs.tar.xz -C ${LXC_ROOTFS}
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Graber
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Grabermkdir -p ${LXC_ROOTFS}/dev/pts/
fecf101cc4352e9bf60ed3477196146a65b5c4f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Setup the configuration
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberconfigfile=$(relevant_file config)
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfstab=$(relevant_file fstab)
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ ! -e $configfile ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "ERROR: meta tarball is missing the configuration file" 1>&2
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber exit 1
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber## Extract all the network config entries
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Grabersed -i -e "/lxc.network/{w ${LXC_PATH}/config-network" -e "d}" \
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber## Extract any other config entry
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Grabersed -i -e "/lxc./{w ${LXC_PATH}/config-auto" -e "d}" ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber## Append the defaults
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberecho "" >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberecho "# Distribution configuration" >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Grabercat $configfile >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber## Add the container-specific config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberecho "" >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberecho "# Container specific configuration" >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ -e "${LXC_PATH}/config-auto" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber cat ${LXC_PATH}/config-auto >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber rm ${LXC_PATH}/config-auto
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ -e "$fstab" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "lxc.mount = ${LXC_PATH}/fstab" >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberecho "lxc.utsname = ${LXC_NAME}" >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber## Re-add the previously removed network config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ -e "${LXC_PATH}/config-network" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "" >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "# Network configuration" >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber cat ${LXC_PATH}/config-network >> ${LXC_PATH}/config
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber rm ${LXC_PATH}/config-network
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane GraberTEMPLATE_FILES="${LXC_PATH}/config"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Setup the fstab
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ -e $fstab ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber cp ${fstab} ${LXC_PATH}/fstab
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber TEMPLATE_FILES="$TEMPLATE_FILES ${LXC_PATH}/fstab"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Look for extra templates
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ -e "$(relevant_file templates)" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber while read line; do
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber fullpath=${LXC_ROOTFS}/$line
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber [ ! -e "$fullpath" ] && continue
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber TEMPLATE_FILES="$TEMPLATE_FILES $fullpath"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber done < $(relevant_file templates)
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber# Replace variables in all templates
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfor file in $TEMPLATE_FILES; do
fad967669817061cda3aafc40be04dcb712a4767Dwight Engen [ ! -f "$file" ] && continue
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber sed -i "s#LXC_NAME#$LXC_NAME#g" $file
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber sed -i "s#LXC_PATH#$LXC_PATH#g" $file
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber sed -i "s#LXC_ROOTFS#$LXC_ROOTFS#g" $file
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber sed -i "s#LXC_TEMPLATE_CONFIG#$LXC_TEMPLATE_CONFIG#g" $file
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber sed -i "s#LXC_HOOK_DIR#$LXC_HOOK_DIR#g" $file
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberdone
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then
0d656b0549e67635ad9c24474b82dfa26e1f4512Stéphane Graber chown $LXC_MAPPED_UID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallynif [ -n "$LXC_MAPPED_GID" ] && [ "$LXC_MAPPED_GID" != "-1" ]; then
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn chgrp $LXC_MAPPED_GID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallynfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberif [ -e "$(relevant_file create-message)" ]; then
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo ""
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber echo "---"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber cat "$(relevant_file create-message)"
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberfi
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graber
71d3a6590fe665421d7a0026d699b0654ddfc7f6Stéphane Graberexit 0