use livefs-editor to make customized isos

a while ago I rewrote inject-subiquity-snap in python, generalized it
and put it at https://github.com/mwhudson/livefs-editor.  TBH, it's
always been better than the shell version but now there's a reason to
switch to it: the impish live server ISO use layers, which the current
shell scripts do not support and livefs-editor now does.
This commit is contained in:
Michael Hudson-Doyle 2021-07-19 14:44:22 +12:00
parent c284ff140e
commit 9a4871f416
3 changed files with 29 additions and 150 deletions

1
.gitignore vendored
View File

@ -66,6 +66,7 @@ venv
# top level dependencies fetched from git, ignore top level only. # top level dependencies fetched from git, ignore top level only.
/probert/ /probert/
/curtin/ /curtin/
/livefs-editor/
# installer isos # installer isos
*.iso *.iso

View File

@ -2,31 +2,33 @@
set -eux set -eux
cmds= LIVEFS_EDITOR="${LIVEFS_EDITOR-$(readlink -f "$(dirname $(dirname ${0}))/livefs-editor")}"
interactive=no [ -d $LIVEFS_EDITOR ] || git clone https://github.com/mwhudson/livefs-editor $LIVEFS_EDITOR
edit_filesystem=no
source_installer=old_iso/casper/installer.squashfs LIVEFS_EDITOR=$(readlink -f $LIVEFS_EDITOR)
source_filesystem=
# Path on disk to a custom snapd (e.g. one that trusts the test keys) # Path on disk to a custom snapd (e.g. one that trusts the test keys)
snapd_pkg= snapd_pkg=
store_url= store_url=
tracking=stable tracking=stable
LIVEFS_OPTS=
add_livefs_opts () {
LIVEFS_OPTS="${LIVEFS_OPTS+$LIVEFS_OPTS }$@"
}
while getopts ":ifc:s:n:p:u:t:" opt; do while getopts ":ifc:s:n:p:u:t:" opt; do
case "${opt}" in case "${opt}" in
i) i)
interactive=yes add_livefs_opts --shell
;; ;;
c) c)
cmds="${OPTARG}" add_livefs_opts --shell "${OPTARG}"
;; ;;
f) f|s|n)
edit_filesystem=yes echo "switch to livefs-editor directly please" >2
;; exit 1
s)
source_installer="$(readlink -f "${OPTARG}")"
;;
n)
source_filesystem="$(readlink -f "${OPTARG}")"
;; ;;
p) p)
snapd_pkg="$(readlink -f "${OPTARG}")" snapd_pkg="$(readlink -f "${OPTARG}")"
@ -50,147 +52,32 @@ shift $((OPTIND-1))
OLD_ISO="$(readlink -f "${1}")" OLD_ISO="$(readlink -f "${1}")"
SUBIQUITY_SNAP_PATH="$(readlink -f "${2}")" SUBIQUITY_SNAP_PATH="$(readlink -f "${2}")"
SUBIQUITY_SNAP="$(basename $SUBIQUITY_SNAP_PATH)" SUBIQUITY_SNAP="$(basename $SUBIQUITY_SNAP_PATH)"
SUBIQUITY_ASSERTION="${SUBIQUITY_SNAP_PATH%.snap}.assert"
if [ ! -f "$SUBIQUITY_ASSERTION" ]; then
SUBIQUITY_ASSERTION=
fi
NEW_ISO="$(readlink -f "${3}")" NEW_ISO="$(readlink -f "${3}")"
tmpdir="$(mktemp -d)" tmpdir="$(mktemp -d)"
cd "${tmpdir}" cd "${tmpdir}"
_MOUNTS=()
do_mount_existing () {
local mountpoint="${!#}"
mount "$@"
_MOUNTS=("${mountpoint}" "${_MOUNTS[@]+"${_MOUNTS[@]}"}")
}
do_mount () {
local mountpoint="${!#}"
mkdir "${mountpoint}"
do_mount_existing "$@"
}
cleanup () { cleanup () {
for m in "${_MOUNTS[@]+"${_MOUNTS[@]}"}"; do
umount "${m}"
done
rm -rf "${tmpdir}" rm -rf "${tmpdir}"
} }
trap cleanup EXIT trap cleanup EXIT
add_overlay() {
local lower="$1"
local mountpoint="$2"
local work="$(mktemp -dp "${tmpdir}")"
if [ -n "${3-}" ]; then
local upper="${3}"
else
local upper="$(mktemp -dp "${tmpdir}")"
fi
chmod go+rx "${work}" "${upper}"
do_mount -t overlay overlay -o lowerdir="${lower}",upperdir="${upper}",workdir="${work}" "${mountpoint}"
}
do_mount -t iso9660 -o loop,ro "${OLD_ISO}" old_iso
unsquashfs -d new_installer "${source_installer}"
do_mount -t squashfs ${source_filesystem:-old_iso/casper/filesystem.squashfs} old_filesystem
add_overlay old_filesystem tree new_installer
do_mount_existing dev-live -t devtmpfs "tree/dev"
do_mount_existing devpts-live -t devpts "tree/dev/pts"
do_mount_existing proc-live -t proc "tree/proc"
do_mount_existing sysfs-live -t sysfs "tree/sys"
do_mount_existing securityfs-live -t securityfs "tree/sys/kernel/security"
python3 -c '
import os, sys, yaml
with open("tree/var/lib/snapd/seed/seed.yaml") as fp:
old_seed = yaml.safe_load(fp)
new_snaps = []
subiquity_snap = {
"name": "subiquity",
"classic": True,
"file": sys.argv[1],
"channel": sys.argv[3],
}
if sys.argv[2] == "":
subiquity_snap["unasserted"] = True
for snap in old_seed["snaps"]:
if snap["name"] == "subiquity":
new_snaps.append(subiquity_snap)
else:
new_snaps.append(snap)
with open("tree/var/lib/snapd/seed/seed.yaml", "w") as fp:
yaml.dump({"snaps": new_snaps}, fp)
' "$SUBIQUITY_SNAP" "$SUBIQUITY_ASSERTION" "$tracking"
rm -f tree/var/lib/snapd/seed/assertions/subiquity*.assert
rm -f tree/var/lib/snapd/seed/snaps/subiquity*.snap
cp "${SUBIQUITY_SNAP_PATH}" tree/var/lib/snapd/seed/snaps/
if [ -n "${SUBIQUITY_ASSERTION}" ]; then
cp "${SUBIQUITY_ASSERTION}" tree/var/lib/snapd/seed/assertions/
fi
if [ -n "$store_url" ]; then if [ -n "$store_url" ]; then
STORE_CONFIG=tree/etc/systemd/system/snapd.service.d/store.conf cat > "store.conf" <<EOF
mkdir -p "$(dirname $STORE_CONFIG)"
cat > "$STORE_CONFIG" <<EOF
[Service] [Service]
Environment=SNAPD_DEBUG=1 SNAPD_DEBUG_HTTP=7 SNAPPY_TESTING=1 Environment=SNAPD_DEBUG=1 SNAPD_DEBUG_HTTP=7 SNAPPY_TESTING=1
Environment=SNAPPY_FORCE_API_URL=$store_url Environment=SNAPPY_FORCE_API_URL=$store_url
EOF EOF
add_livefs_opts --setup-rootfs --shell 'mkdir -p rootfs/etc/systemd/system/snapd.service.d/' \
--cp store.conf rootfs/etc/systemd/system/snapd.service.d/store.conf
fi fi
if [ -n "$snapd_pkg" ]; then if [ -n "$snapd_pkg" ]; then
cp "$snapd_pkg" tree/ add_livefs_opts --setup-rootfs \
chroot tree dpkg -i $(basename "$snapd_pkg") --cp "$snapd_pkg" rootfs \
rm tree/$(basename "$snapd_pkg") --shell "chroot rootfs dpkg -i $(basename "$snapd_pkg")"
--shell "rm rootfs/$(basename "$snapd_pkg")"
fi fi
add_overlay old_iso new_iso PYTHONPATH=$LIVEFS_EDITOR python3 -m livefs_edit $OLD_ISO $NEW_ISO --inject-snap $SUBIQUITY_SNAP_PATH $tracking $LIVEFS_OPTS
if [ "$edit_filesystem" = "yes" ]; then
do_mount -t squashfs ${source_filesystem:-old_iso/casper/filesystem.squashfs} old_filesystem
add_overlay old_filesystem new_filesystem
fi
if [ -n "$cmds" ]; then
bash -c "$cmds"
fi
if [ "$interactive" = "yes" ]; then
bash
fi
/usr/lib/snapd/snap-preseed --reset $(realpath tree)
/usr/lib/snapd/snap-preseed $(realpath tree)
chroot tree apparmor_parser --skip-read-cache --write-cache --skip-kernel-load --verbose -j `nproc` /etc/apparmor.d
if [ "$edit_filesystem" = "yes" ]; then
rm new_iso/casper/filesystem.squashfs
mksquashfs new_filesystem new_iso/casper/filesystem.squashfs
elif [ -n "${source_filesystem}" ]; then
rm new_iso/casper/filesystem.squashfs
cp "${source_filesystem}" new_iso/casper/filesystem.squashfs
fi
rm new_iso/casper/installer.squashfs new_iso/casper/installer.squashfs.gpg
mksquashfs new_installer new_iso/casper/installer.squashfs
(
cd new_iso
sed -i'' '/\.\/casper\/installer.squashfs/d' md5sum.txt
md5sum ./casper/installer.squashfs >> md5sum.txt
)
opts="$(xorriso -indev ${OLD_ISO} -report_el_torito as_mkisofs)"
eval set -- ${opts}
xorriso -as mkisofs "$@" -o ${NEW_ISO} -V Ubuntu\ custom new_iso

View File

@ -4,19 +4,10 @@ set -eux
# make-edge-iso.sh $old_iso $new_iso # make-edge-iso.sh $old_iso $new_iso
INJECT_SNAP=$(readlink -f "$(dirname ${0})/inject-subiquity-snap.sh") LIVEFS_EDITOR="${LIVEFS_EDITOR-$(readlink -f "$(dirname $(dirname ${0}))/livefs-editor")}"
[ -d $LIVEFS_EDITOR ] || git clone https://github.com/mwhudson/livefs-editor $LIVEFS_EDITOR
OLD_ISO="$(readlink -f "${1}")" OLD_ISO="$(readlink -f "${1}")"
NEW_ISO="$(readlink -f "${2}")" NEW_ISO="$(readlink -f "${2}")"
tmpdir="$(mktemp -d)" PYTHONPATH=$LIVEFS_EDITOR python3 -m livefs_edit $OLD_ISO $NEW_ISO --add-snap-from-store subiquity edge
cd "${tmpdir}"
cleanup () {
rm -rf "${tmpdir}"
}
trap cleanup EXIT
snap download --channel edge subiquity
$INJECT_SNAP $OLD_ISO subiquity_*.snap $NEW_ISO