#!/bin/sh # container-tools - Manage systemd-nspawn containers # Copyright (C) 2014-2016 Daniel Baumann # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set -e SCRIPT="${0}" MACHINES="/var/lib/machines" CACHE="/var/cache/container-tools/images" Parameters () { LONG_OPTIONS="bind:,script:,name:,clean,image:,server:,password:" OPTIONS="b:,s:,n:,p:" PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${SCRIPT} --options ${OPTIONS} --shell sh -- ${@})" if [ "${?}" != "0" ] then echo "'${SCRIPT}': getopt exit" >&2 exit 1 fi eval set -- "${PARAMETERS}" while true do case "${1}" in -b|--bind) # ignore shift 2 ;; --cnt.auto) # ignore shift 2 ;; -s|--script) # ignore shift 2 ;; -n|--name) NAME="${2}" shift 2 ;; --clean) CLEAN="true" shift 1 ;; --image) IMAGE="${2}" shift 2 ;; --server) SERVER="${2}" shift 2 ;; -p|--password) PASSWORD="${2}" shift 2 ;; --) shift 1 break ;; *) echo "'${SCRIPT}': getopt error" >&2 exit 1 ;; esac done } Usage () { echo "Usage: container create -n|--name NAME -s|--script ${SCRIPT} -- [--clean] [--image IMAGE] [--server SERVER] [-p|--password PASSWORD}" >&2 exit 1 } Debconf () { # Configure local debconf mkdir -p /tmp/container-tools DEBCONF_TMPDIR="$(mktemp -d -p /tmp/container-tools -t $(basename ${0}).XXXX)" export DEBCONF_TMPDIR mkdir -p "${DEBCONF_TMPDIR}/debconf" cat > "${DEBCONF_TMPDIR}/debconf.systemrc" << EOF Config: configdb Templates: templatedb Name: config Driver: File Mode: 644 Reject-Type: password Filename: ${DEBCONF_TMPDIR}/debconf/config.dat Name: passwords Driver: File Mode: 600 Backup: false Required: false Accept-Type: password Filename: ${DEBCONF_TMPDIR}/debconf/passwords.dat Name: configdb Driver: Stack Stack: config, passwords Name: templatedb Driver: File Mode: 644 Filename: ${DEBCONF_TMPDIR}/debconf/templates.dat EOF DEBCONF_SYSTEMRC="${DEBCONF_TMPDIR}/debconf.systemrc" export DEBCONF_SYSTEMRC } Parameters "${@}" if [ -z "${NAME}" ] then Usage fi if [ -e "${MACHINES}/${NAME}" ] then echo "'${NAME}': container already exists" >&2 exit 1 fi if [ ! -x /usr/bin/curl ] then echo "'${NAME}': /usr/bin/curl - no such file." >&2 exit 1 fi if [ "$(id -u)" -ne 0 ] then echo "'${NAME}': need root privileges" >&2 exit 1 fi ARCHITECTURE="${ARCHITECTURE:-$(dpkg --print-architecture)}" SERVER="${SERVER:-https://files.open-infrastructure.net/images/container-tools/current}" PASSWORD="${PASSWORD:-$(dd if=/dev/urandom bs=12 count=1 2> /dev/null | base64)}" VERSION="$(container version)" # Run if [ -z "${IMAGE}" ] then Debconf # Run debconf parts for SCRIPT in /usr/share/container-tools/scripts/curl.d/* do if [ -x "${SCRIPT}" ] then # FIXME # debconf -ocontainer-tools "${SCRIPT}" "${SCRIPT}" fi done # Read-in configuration from debconf . "${DEBCONF_TMPDIR}/debconf.default" fi if [ -z "${IMAGE}" ] then echo "no image selected, doing nothing." >&2 exit 1 fi # FIXME: Show available image directories on server # FIXME: Fetch debconf-choices.txt to show debconf select # FIXME: gpg verification against debian-keyring or local keyring # FIXME: default server via configuration file echo "Downloading ${IMAGE}" mkdir -p "${CACHE}" if [ -e "${CACHE}/${IMAGE}" ] then CURL_OPTIONS="--time-cond ${CACHE}/${IMAGE}" fi if curl -V | grep -qs http2 then CURL_OPTIONS="${CURL_OPTIONS} --https" fi curl --location --progress-bar --user-agent container-tools/${VERSION} ${CURL_OPTIONS} \ "${SERVER}/${IMAGE}" -o "${CACHE}/${IMAGE}" echo "Unpacking ${IMAGE}" mkdir -p "${MACHINES}/${NAME}" case "${IMAGE}" in *.gz) TAR_OPTIONS="--gzip" ;; *.lz) TAR_OPTIONS="--lzip" ;; *.xz) TAR_OPTIONS="--xz" ;; *) TAR_OPTIONS="" ;; esac if [ -e /usr/bin/pv ] then pv --format '%p' --width 77 "${CACHE}/${IMAGE}" | tar xf - ${TAR_OPTIONS} -C "${MACHINES}/${NAME}" --strip 1 else tar xf "${CACHE}/${IMAGE}" ${TAR_OPTIONS} -C "${MACHINES}/${NAME}" --strip 1 fi # Creating machine-id chroot "${MACHINES}/${NAME}" systemd-machine-id-setup > /dev/null 2>&1 # Setting hostname echo "${NAME}" > "${MACHINES}/${NAME}/etc/hostname" # Copying resolv.conf cp -L /etc/resolv.conf "${MACHINES}/${NAME}/etc/resolv.conf" # Setting root password echo root:${PASSWORD} | chroot "${MACHINES}/${NAME}" chpasswd echo "${NAME}: root password set to '${PASSWORD}'." # Reove cache case "${CLEAN}" in true) rm -f "${CACHE}/${IMAGE}" ;; esac # remove debconf temporary files rm --preserve-root --one-file-system -rf "${DEBCONF_TMPDIR}" rmdir --ignore-fail-on-non-empty /tmp/container-tools 2>&1 || true