summaryrefslogtreecommitdiff
path: root/debvm-create
diff options
context:
space:
mode:
Diffstat (limited to 'debvm-create')
-rwxr-xr-xdebvm-create158
1 files changed, 158 insertions, 0 deletions
diff --git a/debvm-create b/debvm-create
new file mode 100755
index 0000000..6728e90
--- /dev/null
+++ b/debvm-create
@@ -0,0 +1,158 @@
+#!/bin/sh
+# Copyright 2022 Helmut Grohne <helmut@subdivi.de>
+# SPDX-License-Identifier: MIT
+
+# shellcheck disable=SC2016 # Intentional quoting technique
+
+set -u
+
+ARCHITECTURE=$(dpkg --print-architecture)
+IMAGE=rootfs.ext2
+INCLUDE_PACKAGES=init
+MIRROR="http://deb.debian.org/debian"
+SIZE=$((1024*1024*1024))
+SSHKEY=
+SUITE=unstable
+VMNAME=testvm
+
+die() {
+ echo "$*" 1>&2
+ exit 1
+}
+
+usage() {
+ die "usage: $0 [-a architecture] [-h hostname] [-k sshkey] [-m mirror] [-o output] [-p packages] [-r release] [-s size_in_GB]"
+}
+
+
+while test "$#" -gt 0; do
+ case "$1" in
+ -a)
+ test "$#" -eq 1 && usage
+ ARCHITECTURE=$2
+ shift 2
+ ;;
+ -h)
+ test "$#" -eq 1 && usage
+ VMNAME=$2
+ shift 2
+ ;;
+ -k)
+ test "$#" -eq 1 && usage
+ SSHKEY=$2
+ shift 2
+ ;;
+ -m)
+ test "$#" -eq 1 && usage
+ MIRROR=$2
+ shift 2
+ ;;
+ -o)
+ test "$#" -eq 1 && usage
+ IMAGE=$2
+ shift 2
+ ;;
+ -p)
+ test "$#" -eq 1 && usage
+ INCLUDE_PACKAGES="$INCLUDE_PACKAGES,$2"
+ shift 2
+ ;;
+ -r)
+ test "$#" -eq 1 && usage
+ SUITE=$2
+ shift 2
+ ;;
+ -s)
+ test "$#" -eq 1 && usage
+ SIZE=$(($2*1024*1024*1024))
+ shift 2
+ ;;
+ *)
+ usage
+ ;;
+ esac
+done
+
+if test -n "$SSHKEY" && ! test -f "$SSHKEY"; then
+ die "error: ssh keyfile '$SSHKEY' not found"
+fi
+
+KERNEL_SUFFIX=
+if test "$ARCHITECTURE" = amd64; then
+ KERNEL_SUFFIX=-cloud
+fi
+if test "$SUITE" = jessie || test "$SUITE" = stretch; then
+ KERNEL_SUFFIX=
+fi
+
+INCLUDE_PACKAGES="$INCLUDE_PACKAGES,linux-image$KERNEL_SUFFIX-$ARCHITECTURE"
+
+if test -n "$SSHKEY"; then
+ INCLUDE_PACKAGES="$INCLUDE_PACKAGES,openssh-server"
+fi
+
+# construct mmdebstrap options as $@:
+set -- \
+ --verbose \
+ --variant=apt \
+ "--architecture=$ARCHITECTURE" \
+ "--include=$INCLUDE_PACKAGES"
+
+# unless we set up a fstab, / will be read-only
+case "$ARCHITECTURE" in
+ s390x)
+ DISKDEV=vda
+ ;;
+ *)
+ DISKDEV=sda
+ ;;
+esac
+set -- "$@" "--customize-hook=echo '/dev/$DISKDEV / ext4 defaults 0 1' >"'"$1/etc/fstab"'
+
+# set up a hostname
+set -- "$@" \
+ "--customize-hook=echo $VMNAME >"'"$1/etc/hostname"' \
+ "--customize-hook=echo 127.0.0.1 localhost $VMNAME >"'"$1/etc/hosts"'
+
+# allow password-less root login
+set -- "$@" '--customize-hook=sed -i -e "s/^root:\\*:/root::/" $1/etc/shadow'
+#set -- "$@" '--customize-hook=chroot "$1" passwd --delete root'
+
+# dhcp on all network interfaces
+set -- "$@" \
+ '--customize-hook=systemctl --root="$1" enable systemd-networkd.service' \
+ "--customize-hook=printf '"'[Match]\nName=en*\nName=eth*\n[Network]\nDHCP=yes\n'"'"' > "$1/etc/systemd/network/20-wired.network"'
+
+# add ssh key for root
+if test -n "$SSHKEY"; then
+ set -- "$@" \
+ '--customize-hook=mkdir -p "$1/root/.ssh"' \
+ "--customize-hook=upload $SSHKEY /root/.ssh/authorized_keys"
+fi
+
+set -- "$@" '--customize-hook=chroot "$1" apt update'
+
+case "$SUITE" in
+ jessie)
+ # Use obsolete and expired keys.
+ set -- "$@" '--keyring=/usr/share/keyrings/debian-archive-removed-keys.gpg'
+ set -- "$@" --aptopt='Apt::Key::gpgvcommand "/usr/libexec/mmdebstrap/gpgvnoexpkeysig"'
+ # chfn does not work, because libpam-runtime.postinst is late setting up /etc/pam.d/common-auth et al
+ set -- "$@" --extract-hook='chroot "$1" pam-auth-update --package --force'
+ ;;
+ buster)
+ # We need /var/lib/dpkg/available for dpkg --set-selections to work.
+ set -- "$@" '--customize-hook=cat "$1"/var/lib/apt/lists/*_Packages | chroot "$1" dpkg --update-avail'
+ ;;
+esac
+
+# suite target mirror
+set -- "$@" "$SUITE" "$IMAGE" "deb $MIRROR $SUITE main"
+
+set -ex
+
+mmdebstrap "$@"
+
+truncate -s "$SIZE" "$IMAGE"
+/sbin/resize2fs "$IMAGE"
+/sbin/tune2fs -i 0 -O extents,uninit_bg,dir_index,has_journal "$IMAGE"