Add instructions for testing ostree-boot
Co-authored-by: Felix Krull <f_krull@gmx.de>
This commit is contained in:
1 parent
784abb792c
commit
7fb5ae2204
5 files changed
+759
No files matched your search
@@ -0,0 +1,321 @@
|
||||
#!/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 <nicholson@endlessm.com>
|
||||
# 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 <<EOF
|
||||
Usage: $0 [OPTION...] CONFIG SUITE REPO
|
||||
|
||||
-a, --arch build architecture
|
||||
-d, --dir build directory
|
||||
--gpg-sign GPG key ID to use for signing
|
||||
--gpg-homedir GPG homedir to find keys
|
||||
-h, --help show this message and exit
|
||||
|
||||
deb-ostree-builder constructs a Debian OS for use as a bootable
|
||||
OSTree. It uses debootstrap to construct the OS, adjusts it to be
|
||||
compatible with OSTree, and then commits it to a repository.
|
||||
|
||||
CONFIG is a multistrap configuration file. SUITE is the distribution
|
||||
codename. This is used for the OSTree ref and must match the
|
||||
multistrap configuration. REPO is the path the the OSTree repository
|
||||
where the commit will be made.
|
||||
EOF
|
||||
}
|
||||
|
||||
ARGS=$(getopt -n "$0" \
|
||||
-o a:d:h \
|
||||
-l arch:,dir:,gpg-sign:,gpg-homedir:,help \
|
||||
-- "$@")
|
||||
eval set -- "$ARGS"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-a|--arch)
|
||||
ARCH=$2
|
||||
shift 2
|
||||
;;
|
||||
-d|--dir)
|
||||
BUILDDIR=$2
|
||||
shift 2
|
||||
;;
|
||||
--gpg-sign)
|
||||
GPG_SIGN+=($2)
|
||||
shift 2
|
||||
;;
|
||||
--gpg-homedir)
|
||||
GPG_HOMEDIR=$2
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $# -lt 3 ]; then
|
||||
echo "Must specify CONFIG, SUITE and REPO" >&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 <<EOF
|
||||
# Don't make host-specific initramfs
|
||||
hostonly=no
|
||||
EOF
|
||||
|
||||
# Define a temporary policy-rc.d that ensures that no daemons are
|
||||
# launched from the installation.
|
||||
mkdir -p "$BUILDDIR"/usr/sbin
|
||||
cat > "$BUILDDIR"/usr/sbin/policy-rc.d <<EOF
|
||||
#!/bin/sh
|
||||
exit 101
|
||||
EOF
|
||||
chmod +x "$BUILDDIR"/usr/sbin/policy-rc.d
|
||||
|
||||
# Mount common kernel filesystems. dracut expects /dev to be mounted.
|
||||
echo "Mounting filesystems in $BUILDDIR"
|
||||
DEVICES_MOUNTED=true
|
||||
for dir in proc sys dev dev/pts; do
|
||||
mkdir -p "$BUILDDIR/$dir"
|
||||
mount --bind "/$dir" "$BUILDDIR/$dir"
|
||||
done
|
||||
|
||||
# Build with multistrap
|
||||
echo "Building system with multistrap in $BUILDDIR"
|
||||
multistrap -f "$CONFIG" -d "$BUILDDIR"
|
||||
|
||||
# This is a hack for testing ostree-boot before it is in the Debian archive
|
||||
if [ -d /root/extra-packages ]; then
|
||||
mkdir "$BUILDDIR/root/extra-packages"
|
||||
cp /root/extra-packages/*.deb "$BUILDDIR/root/extra-packages"
|
||||
chroot "$BUILDDIR" apt -y update
|
||||
chroot "$BUILDDIR" apt -y install /root/extra-packages/*.deb
|
||||
rm -fr "$BUILDDIR/root/extra-packages"
|
||||
fi
|
||||
|
||||
# All done with filesystems
|
||||
cleanup_mounts
|
||||
|
||||
# Remove temporary policy-rc.d
|
||||
rm -f "$BUILDDIR"/usr/sbin/policy-rc.d
|
||||
|
||||
# Cleanup cruft
|
||||
echo "Preparing system for OSTree"
|
||||
rm -rf \
|
||||
"$BUILDDIR"/boot/*.bak \
|
||||
"$BUILDDIR"/etc/apt/sources.list~ \
|
||||
"$BUILDDIR"/etc/apt/trusted.gpg~ \
|
||||
"$BUILDDIR"/etc/{passwd,group,shadow,gshadow}- \
|
||||
"$BUILDDIR"/var/cache/debconf/*-old \
|
||||
"$BUILDDIR"/var/lib/dpkg/*-old \
|
||||
"$BUILDDIR"/boot/{initrd.img,vmlinuz} \
|
||||
"$BUILDDIR"/{initrd.img,vmlinuz}{,.old}
|
||||
|
||||
# Remove dbus machine ID cache (makes each system unique)
|
||||
rm -f "$BUILDDIR"/var/lib/dbus/machine-id "$BUILDDIR"/etc/machine-id
|
||||
|
||||
# Remove resolv.conf copied from the host by debootstrap. The settings
|
||||
# are only valid on the target host and will be populated at runtime.
|
||||
rm -f "$BUILDDIR"/etc/resolv.conf
|
||||
|
||||
# Remove temporary files
|
||||
rm -rf "$BUILDDIR"/var/cache/man/*
|
||||
rm -rf "$BUILDDIR"/tmp "$BUILDDIR"/var/tmp
|
||||
mkdir -p "$BUILDDIR"/tmp "$BUILDDIR"/var/tmp
|
||||
chmod 1777 "$BUILDDIR"/tmp "$BUILDDIR"/var/tmp
|
||||
|
||||
# OSTree uses a single checksum of the combined kernel and initramfs
|
||||
# to manage boot. Determine the checksum and rename the files the way
|
||||
# OSTree expects.
|
||||
echo "Renaming kernel and initramfs per OSTree requirements"
|
||||
pushd "$BUILDDIR"/boot >/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 <<EOF
|
||||
d /sysroot/home 0755 root root -
|
||||
d /sysroot/root 0700 root root -
|
||||
d /var/opt 0755 root root -
|
||||
d /var/local 0755 root root -
|
||||
d /run/media 0755 root root -
|
||||
L /var/lib/dpkg - - - - ../../usr/share/dpkg/database
|
||||
EOF
|
||||
|
||||
# Create symlinks in the ostree for persistent directories.
|
||||
mkdir -p "${BUILDDIR}"/sysroot
|
||||
rm -rf "${BUILDDIR}"/{home,root,media,opt} "${BUILDDIR}"/usr/local
|
||||
ln -s /sysroot/ostree "${BUILDDIR}"/ostree
|
||||
ln -s /sysroot/home "${BUILDDIR}"/home
|
||||
ln -s /sysroot/root "${BUILDDIR}"/root
|
||||
ln -s /var/opt "${BUILDDIR}"/opt
|
||||
ln -s /var/local "${BUILDDIR}"/usr/local
|
||||
ln -s /run/media "${BUILDDIR}"/media
|
||||
|
||||
# Now ready to commit. Make the repo if necessary. An archive-z2 repo
|
||||
# is used since the intention is to use this repo to serve updates
|
||||
# from.
|
||||
mkdir -p "$REPO"
|
||||
if [ ! -f "$REPO"/config ]; then
|
||||
echo "Initialiazing OSTree repo $REPO"
|
||||
ostree --repo="$REPO" init --mode=archive-z2
|
||||
fi
|
||||
|
||||
# Make the commit. The ostree ref is flatpak style.
|
||||
branch="os/debian/$ARCH/$SUITE"
|
||||
COMMIT_OPTS=(
|
||||
--repo="$REPO"
|
||||
--branch="$branch"
|
||||
--subject="Build $SUITE $ARCH $(date --iso-8601=seconds)"
|
||||
--skip-if-unchanged
|
||||
--table-output
|
||||
)
|
||||
for id in ${GPG_SIGN[@]}; do
|
||||
COMMIT_OPTS+=(--gpg-sign="$id")
|
||||
done
|
||||
if [ -n "$GPG_HOMEDIR" ]; then
|
||||
COMMIT_OPTS+=(--gpg-homedir="$GPG_HOMEDIR")
|
||||
fi
|
||||
echo "Committing $BUILDDIR to $REPO branch $branch"
|
||||
ostree commit "${COMMIT_OPTS[@]}" "$BUILDDIR"
|
||||
|
||||
# Update the repo summary
|
||||
SUMMARY_OPTS=(
|
||||
--repo="$REPO"
|
||||
--update
|
||||
)
|
||||
for id in ${GPG_SIGN[@]}; do
|
||||
SUMMARY_OPTS+=(--gpg-sign="$id")
|
||||
done
|
||||
if [ -n "$GPG_HOMEDIR" ]; then
|
||||
SUMMARY_OPTS+=(--gpg-homedir="$GPG_HOMEDIR")
|
||||
fi
|
||||
echo "Updating $REPO summary file"
|
||||
ostree summary "${SUMMARY_OPTS[@]}"
|
||||
Reference in new issue
Block a user