#!/usr/bin/sh # vim:set ts=3: set -e shopt -s extglob POOL="pool" QUOTA="16G" [[ -n ${SUDO_UID} ]] || exec /usr/bin/sudo $0 if [[ -n ${SIUEUSER} ]] && id -Gn ${SUDO_UID} | grep -q -w professors; then MECH_UID=$(id -u ${SIUEUSER}) if ! [[ -n ${MECH_UID} ]]; then echo -e "\nERROR: Invalid value specified for SIUEUSER" 1>&2 exit 1 fi else MECH_UID=${SUDO_UID} fi if [[ -z ${INSTANCE} ]]; then INSTANCE=0 else if ! [[ ${INSTANCE} =~ ^[0-9]$ ]]; then echo -e "\nERROR: Invalid value specified for INSTANCE" 1>&2 exit 1 fi fi ID="${MECH_UID#14}${INSTANCE}" USERNAME="$(getent passwd ${MECH_UID} | cut -d ':' -f 1)" SRVRNAME="${USERNAME}-${INSTANCE}" SRVRPATH="/srv/${USERNAME}/${SRVRNAME}" if [[ -n ${STARTNAT} ]] && id -Gn ${SUDO_UID} | grep -q -w professors; then INTERNET="--network-veth-extra=vn-${SRVRNAME}:host9" fi if [[ -n ${TEMPLATE} ]]; then if zfs list -o name | grep -q "^${POOL}/${SRVRNAME}$"; then echo -e "\nERROR: TEMPLATE specified for existing instance ${SRVRNAME}. Remove TEMPLATE and retry." 1>&2 exit 1 fi if ! [[ ${TEMPLATE} =~ ^[0-9]{3}\.[0-9](@[0-9]{12})?$ ]]; then echo -e "\nERROR: Invalid value specified for TEMPLATE" 1>&2 exit 1 fi if ! [[ ${TEMPLATE} =~ @ ]]; then TEMPLATE=$(grep -m 1 "^${POOL}/${TEMPLATE}@" ${0%/*}/default) if [[ -z ${TEMPLATE} ]]; then echo -e "\nERROR: Invalid value specified for TEMPLATE" 1>&2 exit 1 fi fi fi #if ! ip link list ${SRVRNAME} &> /dev/null; then # ip tuntap add dev ${SRVRNAME} mod tap # ip link set up ${SRVRNAME} #fi # #if ! ip link list ns-${SRVRNAME} &> /dev/null; then # ip link add link ${SRVRNAME} name ns-${SRVRNAME} type macvlan mode passthru #fi mkdir -p ${SRVRPATH%/*} if ! mountpoint -q ${SRVRPATH}; then if ! zfs list -o name | grep -q "^${POOL}/${SRVRNAME}$"; then if ! [[ -n ${TEMPLATE} ]]; then echo -e "\nERROR: TEMPLATE not specified for new instance ${SRVRNAME}. Specify TEMPLATE and retry." 1>&2 exit 1 fi zfs clone -o mountpoint=${SRVRPATH} ${TEMPLATE} ${POOL}/${SRVRNAME} zfs set quota=${QUOTA} ${POOL}/${SRVRNAME} TEMP=${ID##*(0)} for i in {2..0}; do ADDRESS[$i]=$(($TEMP%256)) TEMP=$(($TEMP/256)) done IFS='.' command eval 'NAT="10.${ADDRESS[*]}/8"' mkdir -p ${SRVRPATH}/etc/systemd/resolved.conf.d cat <<- END > ${SRVRPATH}/etc/systemd/resolved.conf.d/llmnr.conf [Resolve] LLMNR=true END cat <<- END > ${SRVRPATH}/etc/systemd/network/00-host0.network [Match] Virtualization=container Name=host0 [Network] LinkLocalAddressing=0 ConfigureWithoutCarrier=1 Address=192.168.0.$((10+${INSTANCE}))/24 END cat <<- END > ${SRVRPATH}/etc/systemd/network/00-host9.network [Match] Name=host9 [Network] LinkLocalAddressing=0 ConfigureWithoutCarrier=1 Address=$NAT Gateway=10.255.255.254 LLMNR=false DNS=146.163.252.126 DNS=146.163.252.127 END else zfs mount ${POOL}/${SRVRNAME} fi fi if machinectl show ${SRVRNAME} &> /dev/null; then OPTIONS="--quiet --wait --machine=${SRVRNAME} --collect --service-type=exec" if [[ -n ${SSH_ORIGINAL_COMMAND} ]]; then exec systemd-run ${OPTIONS} --pipe /usr/bin/bash -c "${SSH_ORIGINAL_COMMAND}" else exec systemd-run ${OPTIONS} --pty --send-sighup /usr/bin/login -H -f root fi fi if [[ -z ${SSH_ORIGINAL_COMMAND} ]]; then exec systemd-nspawn --settings=trusted --quiet --console=interactive \ --link-journal=no --resolv-conf=off --timezone=off --capability=all --boot \ --directory=${SRVRPATH} --private-users=false --bind-ro=/sys/module \ --bind-ro=/lib/modules --network-zone=${USERNAME} ${INTERNET} # ip link del ns-${SRVRNAME} # ip link del ${SRVRNAME} else echo -e "\nERROR: ${SRVRNAME} is not running" 1>&2 exit 1 fi