#!/bin/bash -e # deb-ostree-builder - Build bootable Debian OSTree commits # This version has been modified to install extra packages from # /root/extra-packages. # # Copyright (C) 2017 Dan Nicholson # Copyright (C) 2019 Simon McVittie # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. PROG=$(readlink -f "$0") PROGDIR=$(dirname "$PROG") # Defaults ARCH=$(dpkg --print-architecture) BUILDDIR= GPG_SIGN=() GPG_HOMEDIR= usage() { cat <&2 exit 1 fi CONFIG=$1 SUITE=$2 REPO=$3 # Mount cleanup handler DEVICES_MOUNTED=false cleanup_mounts() { if $DEVICES_MOUNTED; then echo "Unmounting filesystems in $BUILDDIR" for dir in dev/pts dev sys proc; do umount "$BUILDDIR/$dir" done DEVICES_MOUNTED=false fi } # Exit handler TMP_BUILDDIR= cleanup() { cleanup_mounts || true if [ -n "$TMP_BUILDDIR" ]; then rm -rf "$TMP_BUILDDIR" fi } trap cleanup EXIT if [ -n "$BUILDDIR" ]; then # Create specified build directory echo "Creating $BUILDDIR" mkdir -p "$BUILDDIR" else # Create a temporary build directory in /var/tmp since it could be # fairly large TMP_BUILDDIR=$(mktemp -d -p /var/tmp deb-ostree-builder-XXXXXXXX) BUILDDIR=$TMP_BUILDDIR echo "Using temporary directory $BUILDDIR for build" fi # Ensure that dracut makes generic initramfs instead of looking just # at the host configuration. This is also in the dracut-config-generic # package, but that only gets installed after dracut makes the first # initramfs. echo "Configuring dracut for generic initramfs" mkdir -p "$BUILDDIR"/etc/dracut.conf.d cat > "$BUILDDIR"/etc/dracut.conf.d/90-deb-ostree.conf < "$BUILDDIR"/usr/sbin/policy-rc.d </dev/null vmlinuz_match=(vmlinuz*) vmlinuz_file=${vmlinuz_match[0]} initrd_match=(initrd.img* initramfs*) initrd_file=${initrd_match[0]} csum=$(cat ${vmlinuz_file} ${initrd_file} | \ sha256sum --binary | \ awk '{print $1}') echo "OSTree boot checksum: ${csum}" mv ${vmlinuz_file} ${vmlinuz_file}-${csum} mv ${initrd_file} ${initrd_file/initrd.img/initramfs}-${csum} popd >/dev/null # OSTree only commits files or symlinks rm -rf "$BUILDDIR"/dev mkdir -p "$BUILDDIR"/dev # Fixup home directory base paths for OSTree sed -i -e 's|DHOME=/home|DHOME=/sysroot/home|g' \ "${BUILDDIR}"/etc/adduser.conf sed -i -e 's|# HOME=/home|HOME=/sysroot/home|g' \ "${BUILDDIR}"/etc/default/useradd # Move /etc to /usr/etc. # # FIXME: Need to handle passwd and group to be updatable. This can be # done with libnss-altfiles, though that has other drawbacks. if [ -d "${BUILDDIR}"/usr/etc ]; then echo "ERROR: Non-empty /usr/etc found!" >&2 ls -lR "${BUILDDIR}"/usr/etc exit 1 fi mv "${BUILDDIR}"/etc "${BUILDDIR}"/usr # Move dpkg database to /usr so it's accessible after the OS /var is # mounted, but make a symlink so it works without modifications to dpkg # or apt mkdir -p "${BUILDDIR}"/usr/share/dpkg if [ -e "${BUILDDIR}"/usr/share/dpkg/database ]; then echo "ERROR: /usr/share/dpkg/database already exists!" >&2 ls -lR "${BUILDDIR}"/usr/share/dpkg/database >&2 exit 1 fi mv "${BUILDDIR}"/var/lib/dpkg "${BUILDDIR}"/usr/share/dpkg/database ln -sr "${BUILDDIR}"/usr/share/dpkg/database \ "${BUILDDIR}"/var/lib/dpkg # tmpfiles.d setup to make the ostree root compatible with persistent # directories in the sysroot. cat > "${BUILDDIR}"/usr/lib/tmpfiles.d/ostree.conf <