#!/usr/bin/bash # TODO: Support other flavours. readonly IMAGE_URL='https://cloud.debian.org/images/cloud/sid/daily/latest/debian-sid-generic-amd64-daily.tar.xz' readonly IMAGE_SHA512SUMS='https://cloud.debian.org/images/cloud/sid/daily/latest/SHA512SUMS' if [ -x /usr/bin/importctl ]; then readonly IMPORTCTL='importctl' readonly IMPORTCTL_IMPORT_RAW_ARGS='-m' else readonly IMPORTCTL='machinectl' fi CONTAINER_NAME= NO_INTERNET= log() { printf "I: ${@}\n" } error() { printf "E: ${@}\n" > /dev/stderr exit 1 } import_image() { local name="${1}" local tmpdir=$(mktemp -d) local filename=$(basename "${IMAGE_URL}") local sha512sum_filename=$(basename "${IMAGE_SHA512SUMS}") trap 'rm -f $tmpdir' RETURN EXIT SIGINT SIGTERM log "Dowloading image '${IMAGE_URL}' into '${tmpdir}'" cd "${tmpdir}" wget "${IMAGE_URL}" tar xf "${tmpdir}/${filename}" log "Verifying hash for '${filename}'" wget "${IMAGE_SHA512SUMS}" if ! sha512sum --ignore-missing -c "${sha512sum_filename}"; then error "Aborting; please check the hash!" fi log "Importing image '${filename}' as '${name}'" $IMPORTCTL import-raw ${IMPORTCTL_IMPORT_RAW_ARGS} "${filename}" "${name}" } setup_container() { local name="${1}" local etcpath='/etc/systemd/nspawn' mkdir -p "${etcpath}" cat > "${etcpath}/${name}.nspawn" << _EOF_ [Network] Private=yes VirtualEthernet=yes Zone=${name} _EOF_ if [ -z "${NO_INTERNET}" ]; then iptables -A FORWARD -i "vz-${name}" -o enp5s0 -j ACCEPT iptables-save log "Don't forget to enable port-forwarding on sysctl" fi } create_container() { local name="${1}" log "Starting container '${name}'" machinectl start "${name}" } usage() { cat << EOF ${0} -- Create a container using machinectl Arguments: -n|--name NAME: The container name. Mandatory. -x|--no-internet: Whether the container should not have access to the internet -h|--help: This help message EOF } parse_args() { while [ -n "${1}" ]; do case "${1}" in "-n"|"--name") CONTAINER_NAME="${2}" shift 2 ;; "-x"|"--no-internet") NO_INTERNET=1 shift ;; "-h"|"--help") usage exit 0 ;; esac done } sanitize_args() { if [ -z "${CONTAINER_NAME}" ]; then error "You must specify a container name (-n)" fi } main() { parse_args "$@" sanitize_args import_image "${CONTAINER_NAME}" setup_container "${CONTAINER_NAME}" create_container "${CONTAINER_NAME}" log "Container '${CONTAINER_NAME}' created" } main "$@"