!/bin/bash

RUN ON moly

#

set -e set -u

VG=vg0 SUITE=wheezy MIRROR=http://ftp.us.debian.org/debian

SPONSOR="xx"

check_installed() { local p for p in "$@"; do if ! dpkg -l "$p" 2>/dev/null | grep -q '^ii'; then echo >&2 "Error: package $p not installed:" echo >&2 " apt-get install $" exit 1 fi done } get_sshkey_fprs() { local f for f in etc/ssh/ssh_host_key.pub; do echo -n " " ssh-keygen -l -f "$f" done } cleanup() { set +x if [ -n "$disk" ]; then echo "Maybe:" echo "lvremove $disk" fi echo if [ -n "${target:-}" ] && [ -e "$target" ]; then cd / if [ "$(stat -f / -c %i)" != "$(stat -f "$target" -c %i)" ]; then umount "$target" fi rmdir "$target" fi

if [ -n "${part1:-}" ]; then
    kpartx -d -p -p -v "$disk"
fi

} check_installed debootstrap debian-archive-keyring kpartx ipv6calc

echo -n "New VM's name: " if [ -n "${1:-}" ]; then echo "$1"; guest="$1"; shift; else read guest; fi echo echo -n "Disk size: [8g]" if [ -n "${1:-}" ]; then echo "$1"; disksize="$1"; shift; else read disksize; fi disksize=${disksize:-8g}

trap cleanup EXIT

LV="$guest" lvcreate -L "$disksize" -n "$LV" "$VG"

disk="/dev/mapper/$VG-$(echo $guest | sed -e 's/-/--/')" target="/mnt/target-$guest"

if ! [ -e "$disk" ]; then echo >&2 "Error: Disk $disk does not exist." exit 1 fi if [ -e "$target" ]; then echo >&2 "Error: Directory $target already exists." exit 1 fi

if [ "$(head -c 65536 "$disk" | sha1sum | awk '{print $1}')" != "1adc95bebe9eea8c112d40cd04ab7a8d75c4f961" ]; then echo -n "Warning: Disk appears to be not be empty. Continue anyway? [y/N] " read ans [ "$ans" = "y" ] || exit 0 fi

echo -n "ipaddr: " if [ -n "${1:-}" ]; then echo "$1"; ipaddr="$1"; shift; else read ipaddr; fi netmask=255.255.255.192 gateway=38.229.72.1 ip6addr=2620:0:6b0:b:1a1a::${ipaddr} ip6gateway=2620:0:6b0:b::1

set -x

if [ -e "$disk-part1" ]; then # we already had a partition table and udev/kpartx got it at boot time kpartx -v -d -p -part $disk fi echo '2048,,L,*' | sfdisk -u S --Linux "$disk" kpartx -v -p -p -a "$disk" part1="${disk}-p1" mkfs.ext4 "$part1"

mkdir "$target" mount "$part1" "$target" cd "$target"

debootstrap --variant=minbase --keyring=/usr/share/keyrings/debian-archive-keyring.gpg "$SUITE" . "$MIRROR"

Set up swap and fstab

dd if=/dev/zero of=swapfile bs=1024k count=512 chmod 0 swapfile mkswap ./swapfile

uuidroot=$(blkid -s UUID -o value ${part1}) && cat > etc/fstab << EOF UUID=$uuidroot / ext4 errors=remount-ro 0 1 /swapfile none swap sw 0 0 EOF echo 'RAMTMP=yes' >> etc/default/tmpfs

Set up basic networking stuff

echo "$guest" > etc/hostname cat > etc/hosts << EOF 127.0.0.1 localhost

The following lines are desirable for IPv6 capable hosts

::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ff02::3 ip6-allhosts EOF rm -fv etc/udev/rules.d/70-persistent-* mkdir -p etc/udev/rules.d/ touch etc/udev/rules.d/75-persistent-net-generator.rules

cat > etc/network/interfaces << EOF auto lo iface lo inet loopback

auto eth0 iface eth0 inet static address $ipaddr netmask $netmask up ip route add $gateway/32 dev \$IFACE up ip route add default via $gateway dev \$IFACE down ip route del default via $gateway dev \$IFACE down ip route del $gateway/32 dev \$IFACE iface eth0 inet6 static address $ip6addr gateway $ip6gateway netmask 64 accept_ra 0 EOF

cat > etc/resolv.conf << EOF nameserver 8.8.8.8 search torproject.org EOF

A couple packages

mv etc/apt/sources.list etc/apt/sources.list.d/debian.list chroot . apt-get update echo "Apt::Install-Recommends 0;" > etc/apt/apt.conf.d/local-recommends chroot . apt-get install -y locales-all net-tools iproute ifupdown dialog vim netbase udev psmisc usbutils pciutils

Set up kernel and bootloader

chroot . apt-get install -y linux-image-amd64 DEBIAN_FRONTEND=noninteractive chroot . apt-get install -y grub2

! [ -e dev/vda ] ! [ -e dev/vda1 ] cp -av readlink -f "$disk" dev/new-root cp -av readlink -f "$part1" dev/new-root1 chroot . grub-install --modules=part_msdos /dev/new-root rm -v dev/new-root*

cp -av readlink -f "$disk" dev/vda cp -av readlink -f "$part1" dev/vda1 rm boot/grub/device.map chroot . update-grub rm -v dev/vda*

rootpw="$(head -c 12 /dev/urandom | base64)" echo "root:$rootpw" | chroot . chpasswd

install ssh

chroot . apt-get install -y ssh sed -i -e "s/hostname\$/$guest/" etc/ssh/ssh_host*_key.pub sshkeys="$(get_sshkey_fprs)" rsahostkey="$(cat etc/ssh/ssh_host_rsa_key.pub)"

clean up

trap - EXIT cleanup

echo "$guest's root password is $rootpw" echo "SSH host key fingerprints are:" echo "$sshkeys" echo "IP addresses:" echo " $ipaddr" echo " $ip6addr"

echo echo "ud-ldap ldpavi snippet:" cat << EOF add host=$guest,ou=hosts,dc=torproject,dc=org host: $guest hostname: $guest.torproject.org objectClass: top objectClass: debianServer l: Germany distribution: Debian GNU/Linux access: restricted admin: torproject-admin@torproject.org architecture: amd64 sshRSAHostKey: $rsahostkey ipHostNumber: $ipaddr ipHostNumber: ipv6calc --in ipv6addr --out ipv6addr $ip6addr mXRecord: 0 INCOMING-MX physicalHost: hostname -f description: XXX purpose: XXX

EOF

sponsor: $SPONSOR

echo "Maybe run this now: " echo " cd /etc/tor-virt && git pull && virsh define hostname/$guest.xml && virsh autostart $guest" echo "And then:" echo " virsh start $guest"