diff options
-rw-r--r-- | .gitlab-ci.yml | 8 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rwxr-xr-x | bin/debvm-create (renamed from debvm-create) | 59 | ||||
-rwxr-xr-x | bin/debvm-run (renamed from debvm-run) | 3 | ||||
-rwxr-xr-x | bin/debvm-waitssh (renamed from debvm-waitssh) | 0 | ||||
-rwxr-xr-x | share/customize-autologin.sh | 23 | ||||
-rwxr-xr-x | share/customize-dpkgavailable.sh | 12 | ||||
-rwxr-xr-x | share/customize-networkd.sh | 37 | ||||
-rwxr-xr-x | share/customize-resolved.sh | 26 | ||||
-rwxr-xr-x | useraddhook/customize.sh | 2 |
10 files changed, 120 insertions, 52 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 456e8d9..29e0783 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,14 +5,14 @@ shellcheck: - apt-get update - apt-get dist-upgrade --yes - apt-get --no-install-recommends --yes install shellcheck - - shellcheck -P tests debvm-* tests/*.sh + - shellcheck -P tests bin/* share/*.sh tests/*.sh codespell: script: - apt-get update - apt-get dist-upgrade --yes - apt-get --no-install-recommends --yes install codespell - - codespell debvm-* tests/*.sh + - codespell bin/* share/*.sh tests/*.sh release_test: parallel: @@ -28,7 +28,7 @@ release_test: - apt-get update - apt-get dist-upgrade --yes - apt-get --no-install-recommends --yes install e2fsprogs genext2fs mmdebstrap openssh-client qemu-kvm - - PATH=.:$PATH ./tests/create-and-run.sh $(dpkg --print-architecture) "$RELEASE" + - PATH=$(pwd)/bin:$PATH ./tests/create-and-run.sh $(dpkg --print-architecture) "$RELEASE" arch_test: parallel: @@ -46,4 +46,4 @@ arch_test: - apt-get update - apt-get dist-upgrade --yes - apt-get --no-install-recommends --yes install e2fsprogs genext2fs mmdebstrap openssh-client qemu-system binfmt-support arch-test qemu-user-static - - PATH=.:$PATH ./tests/create-and-run.sh "$ARCHITECTURE" sid + - PATH=$(pwd)/bin:$PATH ./tests/create-and-run.sh "$ARCHITECTURE" sid @@ -23,7 +23,7 @@ invocation. The following two invocations will give you a shell inside a qemu virtual machine of the native architecture, leaving all the settings at their defaults: - ./debvm-create && ./debvm-run + ./bin/debvm-create && ./bin/debvm-run What do I need? =============== diff --git a/debvm-create b/bin/debvm-create index d21fd7b..b34399b 100755 --- a/debvm-create +++ b/bin/debvm-create @@ -11,7 +11,7 @@ debvm-create - Create a VM image for various Debian releases and architectures =head1 SYNOPSIS -B<debvm-create> [B<-a> I<architecture>] [B<-h> I<hostname>] [B<-k> F<sshkey>] [B<-m> I<mirror>] [B<-o> F<output>] [B<-p> I<package>] [B<-r> I<release>] [B<-s> <task>] [B<-z> I<size_in_GB>] [B<--> I<mmdebstrap options>] +B<debvm-create> [B<-a> I<architecture>] [B<-h> I<hostname>] [B<-k> F<sshkey>] [B<-m> I<mirror>] [B<-o> F<output>] [B<-r> I<release>] [B<-s> <task>] [B<-z> I<size_in_GB>] [B<--> I<mmdebstrap options>] =head1 DESCRIPTION @@ -54,13 +54,6 @@ By default, L<http://deb.debian.org/debian> is being used. Specify the file name of the resulting virtual machine image. By default, it is written to F<rootfs.ext4>. -=item B<-p> I<package>, B<--package>=I<package> - -Request additional packages to be installed into the virtual machine image. -This option can be specified multiple times and packages can be separated by a comma. -Package recommendations are not honoured. -If a linux-image is passed here, it will also C<--skip=kernel>. - =item B<-r> I<release>, B<--release>=I<release> Use the given Debian release. @@ -108,6 +101,7 @@ The default is 1 GB. All options beyond a double dash are passed to B<mmdebstrap> before the suite, target and mirror specification. This can be used to provide additional hooks for image customization. +You can also request additional packages to be installed into the image using B<mmdebstrap>'s B<--include> option. =back @@ -130,6 +124,8 @@ SSHKEY= SUITE=unstable VMNAME=testvm +SHARE_DIR="${0%/*}/../share" + nth_arg() { shift "$1" printf "%s" "$1" @@ -140,7 +136,7 @@ die() { exit 1 } usage() { - die "usage: $0 [-a architecture] [-h hostname] [-k sshkey] [-m mirror] [-o output] [-p packages] [-r release] [-z size_in_GB] [-- mmdebstrap options]" + die "usage: $0 [-a architecture] [-h hostname] [-k sshkey] [-m mirror] [-o output] [-r release] [-s task] [-z size_in_GB] [-- mmdebstrap options]" } usage_error() { echo "error: $*" 1>&2 @@ -165,12 +161,6 @@ opt_sshkey() { opt_output() { IMAGE=$1 } -opt_package() { - INCLUDE_PACKAGES="$INCLUDE_PACKAGES,$1" - case "$1" in linux-image*) - opt_skip kernel - ;; esac -} opt_release() { SUITE=$1 } @@ -178,14 +168,13 @@ opt_size() { SIZE=$(($1*1024*1024*1024)) } -while getopts :a:h:k:m:o:p:r:s:z:-: OPTCHAR; do +while getopts :a:h:k:m:o:r:s:z:-: OPTCHAR; do case "$OPTCHAR" in a) opt_architecture "$OPTARG" ;; h) opt_hostname "$OPTARG" ;; k) opt_sshkey "$OPTARG" ;; m) opt_mirror "$OPTARG" ;; o) opt_output "$OPTARG" ;; - p) opt_package "$OPTARG" ;; r) opt_release "$OPTARG" ;; s) opt_skip "$OPTARG" ;; z) opt_size "$OPTARG" ;; @@ -194,12 +183,12 @@ while getopts :a:h:k:m:o:p:r:s:z:-: OPTCHAR; do help) usage ;; - architecture|hostname|mirror|output|package|release|size|skip|sshkey) + architecture|hostname|mirror|output|release|size|skip|sshkey) test "$OPTIND" -gt "$#" && usage_error "missing argument for --$OPTARG" "opt_$OPTARG" "$(nth_arg "$OPTIND" "$@")" OPTIND=$((OPTIND+1)) ;; - architecture=*|hostname=*|mirror=*|output=*|package=*|release=*|size=*|skip=*|sshkey=*) + architecture=*|hostname=*|mirror=*|output=*|release=*|size=*|skip=*|sshkey=*) "opt_${OPTARG%%=*}" "${OPTARG#*=}" ;; *) @@ -296,17 +285,8 @@ fi if ! check_skip systemdnetwork; then # add a DNS resolver - if test "$DEBVER" -ge 9; then - INCLUDE_PACKAGES="$INCLUDE_PACKAGES,libnss-resolve" - fi - if test "$DEBVER" -le 11; then - set -- '--customize-hook=chroot "$1" systemctl enable systemd-resolved.service' "$@" - fi - if test "$DEBVER" -le 9; then - set -- '--customize-hook=ln -fs ../run/systemd/resolve/resolv.conf "$1/etc/resolv.conf"' "$@" - elif test "$DEBVER" -le 11; then - set -- '--customize-hook=ln -fs ../run/systemd/resolve/stub-resolv.conf "$1/etc/resolv.conf"' "$@" - fi + INCLUDE_PACKAGES="$INCLUDE_PACKAGES,?exact-name(libnss-resolve)" + set -- "--customize-hook=$SHARE_DIR/customize-resolved.sh" "$@" fi # construct mmdebstrap options as $@: @@ -331,15 +311,7 @@ set -- '--customize-hook=chroot "$1" passwd --delete root' "$@" if ! check_skip systemdnetwork; then # dhcp on all network interfaces - SYSD_NET_MATCH='Name=en*\n' - test "$DEBVER" -le 8 && SYSD_NET_MATCH="${SYSD_NET_MATCH}Name=eth*\\n" - SYSD_NET_NET='DHCP=yes\n' - # This anchor is included by default since bullseye. Fails DNSSEC validation when missing. - test "$DEBVER" -le 11 && SYSD_NET_NET="${SYSD_NET_NET}DNSSECNegativeTrustAnchors=home.arpa\\n" - set -- \ - '--customize-hook=chroot "$1" systemctl enable systemd-networkd.service' \ - "--customize-hook=printf \"[Match]\\n$SYSD_NET_MATCH\\n[Network]\\n$SYSD_NET_NET"'\n[DHCP]\nUseDomains=yes\n" > "$1/etc/systemd/network/20-wired.network"' \ - "$@" + set -- "--customize-hook=$SHARE_DIR/customize-networkd.sh" "$@" fi # add ssh key for root @@ -352,9 +324,7 @@ fi if ! check_skip packagelists; then set -- --skip=cleanup/apt/lists "$@" - - # We need /var/lib/dpkg/available for dpkg --set-selections to work. - set -- '--customize-hook=chroot "$1" apt-cache dumpavail | chroot "$1" dpkg --update-avail' "$@" + set -- "--customize-hook=$SHARE_DIR/customize-dpkgavailable.sh" "$@" fi if test "$DEBVER" -le 8; then @@ -369,10 +339,7 @@ if test "$DEBVER" -ge 12 && ! check_skip usrmerge; then set -- --hook-dir=/usr/share/mmdebstrap/hooks/merged-usr "$@" fi -set -- \ - '--customize-hook=mkdir "$1/etc/systemd/system/serial-getty@.service.d"' \ - "--customize-hook=sed -n -e '1i[Service]' -e '1iExecStart=' -e 's,^ExecStart=-/sbin/agetty ,&-a root ,p'"' "$1/lib/systemd/system/serial-getty@.service" > "$1/etc/systemd/system/serial-getty@.service.d/autologin.conf"' \ - "$@" +set -- "--customize-hook=$SHARE_DIR/customize-autologin.sh" "$@" # suite target mirror set -- "$@" "$SUITE" "$IMAGE" "deb $MIRROR $SUITE main" diff --git a/debvm-run b/bin/debvm-run index 6f48089..6ed47c4 100755 --- a/debvm-run +++ b/bin/debvm-run @@ -267,6 +267,9 @@ if test -z "$GRAPHICAL"; then KERNEL_CMDLINE="$KERNEL_CMDLINE console=ttyS0" ;; esac + if test -t 0 && test -t 1 && test -n "$TERM"; then + KERNEL_CMDLINE="$KERNEL_CMDLINE TERM=$TERM" + fi fi if test -n "$SSHPORT"; then diff --git a/debvm-waitssh b/bin/debvm-waitssh index 82eb14d..82eb14d 100755 --- a/debvm-waitssh +++ b/bin/debvm-waitssh diff --git a/share/customize-autologin.sh b/share/customize-autologin.sh new file mode 100755 index 0000000..b9a4a8b --- /dev/null +++ b/share/customize-autologin.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# Copyright 2022 Helmut Grohne <helmut@subdivi.de> +# SPDX-License-Identifier: MIT +# +# This is a mmdebstrap customize hook that configures automatic root login on a +# serial console. It also parses the debvm.term kernel cmdline and passes it as +# TERM to agetty. + +set -eu + +TARGET=$1 + +UNIT=serial-getty@.service + +mkdir "$TARGET/etc/systemd/system/$UNIT.d" + +( + echo '[Service]' + printf '%s\n' 'ExecStartPre=/bin/sed -n -e "s/^\\(.* \\)\\?\\(TERM=[^ ]*\\).*/\\2/w/run/debvmterm" /proc/cmdline' + echo 'EnvironmentFile=-/run/debvmterm' + echo 'ExecStart=' + sed -n 's,^ExecStart=-/sbin/agetty ,&-a root ,p' "$TARGET/lib/systemd/system/$UNIT" +) > "$TARGET/etc/systemd/system/$UNIT.d/autologin.conf" diff --git a/share/customize-dpkgavailable.sh b/share/customize-dpkgavailable.sh new file mode 100755 index 0000000..f35b81f --- /dev/null +++ b/share/customize-dpkgavailable.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# Copyright 2022 Helmut Grohne <helmut@subdivi.de> +# SPDX-License-Identifier: MIT +# +# This is a mmdebstrap customize hook that initializes dpkg's available +# database from an updated apt package list cache. +# +# Without the available database, dpkg --set-selections won't work. + +set -eu + +APT_CONFIG=$MMDEBSTRAP_APT_CONFIG apt-cache dumpavail | dpkg --root "$1" --update-avail diff --git a/share/customize-networkd.sh b/share/customize-networkd.sh new file mode 100755 index 0000000..c89aae2 --- /dev/null +++ b/share/customize-networkd.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# Copyright 2022 Helmut Grohne <helmut@subdivi.de> +# SPDX-License-Identifier: MIT +# +# This is a mmdebstrap customize hook that enables and configures +# systemd-networkd on various Debian releases. + +set -eu + +TARGET=$1 + +SYSTEMD_VERSION=$(dpkg-query --root "$TARGET" -f '${Version}' -W systemd) + +if test "${MMDEBSTRAP_MODE:-}" = chrootless; then + systemctl --root "$TARGET" enable systemd-networkd.service +else + chroot "$TARGET" systemctl enable systemd-networkd.service +fi + +{ + echo '[Match]' + echo 'Name=en*' + if dpkg --compare-versions "$SYSTEMD_VERSION" lt 220-7~; then + echo 'Name=eth*' + fi + + echo '[Network]' + echo 'DHCP=yes' + + if dpkg --compare-versions "$SYSTEMD_VERSION" lt 249; then + # This anchor is included by default since bullseye. Fails DNSSEC + # validation when missing. + echo 'DNSSECNegativeTrustAnchors=home.arpa' + fi + echo '[DHCP]' + echo 'UseDomains=yes' +} >"$TARGET/etc/systemd/network/20-wired.network" diff --git a/share/customize-resolved.sh b/share/customize-resolved.sh new file mode 100755 index 0000000..e8fe248 --- /dev/null +++ b/share/customize-resolved.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# Copyright 2022 Helmut Grohne <helmut@subdivi.de> +# SPDX-License-Identifier: MIT +# +# This is a mmdebstrap customize hook that enables systemd-resolved on various +# Debian releases. + +set -eu + +TARGET=$1 + +LIBNSS_RESOLVE_VERSION=$(dpkg-query --root "$TARGET" -f '${Version}' -W libnss-resolve 2>/dev/null) || : + +if dpkg --compare-versions "$LIBNSS_RESOLVE_VERSION" lt 251.3-2~exp1; then + if test "${MMDEBSTRAP_MODE:-}" = chrootless; then + systemctl --root "$TARGET" enable systemd-resolved.service + else + chroot "$TARGET" systemctl enable systemd-resolved.service + fi + + if test -z "$LIBNSS_RESOLVE_VERSION"; then + ln -fs ../run/systemd/resolve/resolv.conf "$TARGET/etc/resolv.conf" + else + ln -fs ../run/systemd/resolve/stub-resolv.conf "$TARGET/etc/resolv.conf" + fi +fi diff --git a/useraddhook/customize.sh b/useraddhook/customize.sh index a4390bd..3bba263 100755 --- a/useraddhook/customize.sh +++ b/useraddhook/customize.sh @@ -13,7 +13,7 @@ # # Example usage: # -# $ debvm-create -p sudo -k ~/.ssh/id_rsa.pub -- --hook-dir=.../useraddhook +# $ debvm-create -k ~/.ssh/id_rsa.pub -- --hook-dir=.../useraddhook --include sudo # $ debvm-run -s 8022 # $ ssh -l user -p 8022 127.0.0.1 whoami # user |