From df0deb63ad7f62183e38103a7e35d1334f1a7770 Mon Sep 17 00:00:00 2001 From: Sergio Durigan Junior Date: Mon, 3 Jun 2024 19:04:46 -0400 Subject: [PATCH] Initial release --- nspawner.sh | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 nspawner.sh diff --git a/nspawner.sh b/nspawner.sh new file mode 100644 index 0000000..08c9fe7 --- /dev/null +++ b/nspawner.sh @@ -0,0 +1,132 @@ +#!/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 "$@"