diff options
author | iliana etaoin <iliana@buttslol.net> | 2023-12-29 19:05:19 +0000 |
---|---|---|
committer | iliana etaoin <iliana@buttslol.net> | 2023-12-29 19:05:19 +0000 |
commit | c50eb80f23c08f1ffc824d4983d5b9a740fb1273 (patch) | |
tree | 1835a1f498ef7cd59a393c25f0914f0f1c786773 /repack.sh | |
download | fauxlo-c50eb80f23c08f1ffc824d4983d5b9a740fb1273.tar.gz |
initial commit
Diffstat (limited to 'repack.sh')
-rwxr-xr-x | repack.sh | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/repack.sh b/repack.sh new file mode 100755 index 0000000..2b324ab --- /dev/null +++ b/repack.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +set -euo pipefail +if [[ $# -lt 2 ]]; then + >&2 echo "usage: repack.sh IN_ROOTFS OUT_DIR" + exit 1 +fi +if [[ $EUID -ne 0 ]]; then + >&2 echo "this script must be run as root" + exit 1 +fi + +set -x +script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) +in_rootfs="$1" +out_dir="$2" +out_tmp=$(mktemp -d -p "$(dirname "$out_dir")" .tmp.XXXXXXXXXX) +chmod 0755 "$out_tmp" +mountpoint=$(mktemp -d) +_cleanup() { + # FIXME: this doesn't handle `gpgconf --kill all` + mountpoint -q "$mountpoint" && umount --recursive "$mountpoint" + rmdir "$mountpoint" + rm -rf "$out_tmp" +} +trap _cleanup EXIT + +cp "$in_rootfs" "$out_tmp"/rootfs.img +# Randomize filesystem UUID +fs_uuid=$(uuidgen) +btrfstune -fU "$fs_uuid" "$out_tmp"/rootfs.img +# Mount and mark read-only +mount -o compress=zstd "$out_tmp"/rootfs.img "$mountpoint" +btrfs property set -ts "$mountpoint" ro false +# Mount /dev and /proc for mkinitcpio, etc. +mount -t devtmpfs dev "$mountpoint"/dev +mount -t proc proc "$mountpoint"/proc +# Set up the usual tmpfs suspects +mount -t tmpfs -o mode=755 tmpfs "$mountpoint"/run +mount -t tmpfs tmpfs "$mountpoint"/tmp +# Ensure no writes to /home or /var +mount -t tmpfs -o mode=755 tmpfs "$mountpoint"/home +mount -t tmpfs -o mode=755 tmpfs "$mountpoint"/var +# Get network resolution working in the chroot. +mount --bind "$(realpath /etc/resolv.conf)" "$mountpoint"/etc/resolv.conf + +# Modify /etc/os-release and /lib/steamos-atomupd/manifest.json. We want +# VERSION_ID/version to remain the same as upstream so that Steam can still load +# changelog entries. +version=$(jq -r .version <"$mountpoint"/lib/steamos-atomupd/manifest.json) +# We want to set our own BUILD_ID/buildid so that we can make multiple image +# updates even if upstream doesn't make any changes. SteamOS requires the build +# ID is of the form YYYYMMDD.N. The N must be an integer, at least as far as +# Python 3's `int` built-in function is concerned; leading zeroes parse fine, +# but when it's rendered back out to a string they get dropped, so we may as +# well remove them ourselves. +buildid=$(date +%Y%m%d.%H%M%S | sed -e 's/\.0\+\(.\+\)$/.\1/') +jq --arg buildid "$buildid" '.buildid = $buildid' \ + <"$mountpoint"/lib/steamos-atomupd/manifest.json >"$out_tmp"/manifest.json +cat "$out_tmp"/manifest.json >"$mountpoint"/lib/steamos-atomupd/manifest.json +sed -i -e "/^BUILD_ID=/c BUILD_ID=$buildid" "$mountpoint"/etc/os-release +# For lack of a better place to make it incredibly obvious that this is an +# unofficial image, modify NAME and PRETTY_NAME. (This sadly doesn't show up in +# the Steam Deck UI, that seems to pull from /etc/lsb-release?) +sed -i -e "/^NAME=/c NAME=\"SteamOS (iliana's version)\"" "$mountpoint"/etc/os-release +sed -i -e "/^PRETTY_NAME=/c PRETTY_NAME=\"SteamOS (iliana's version)\"" "$mountpoint"/etc/os-release +# Swap URLs in /etc/steamos-atomupd/client.conf. +cat "$script_dir/atomupd-client.conf" >"$mountpoint"/etc/steamos-atomupd/client.conf +# Replace /etc/rauc/keyring.pem. +cat "$script_dir/iliana-rauc-keyring.pem" >"$mountpoint"/etc/rauc/keyring.pem + +# # We need a valid keyring to verify the signature of packages we want to +# # install. We don't really want to mess with the state /etc/pacman.d/gnupg is in +# # on the SteamOS rootfs, so we put one on /tmp. +# chroot "$mountpoint" pacman-key --gpgdir /tmp/gnupg --init +# chroot "$mountpoint" pacman-key --gpgdir /tmp/gnupg --populate +# # Terminate GPG agent processes +# chroot "$mountpoint" gpgconf --homedir /tmp/gnupg --kill all + +# Add our repo. +sed -i -e '/\[testing\]/s;^;[fauxlo]\nServer = https://fauxlo.ili.fyi/pacman/$arch\nSigLevel = Never\n\n;' "$mountpoint"/etc/pacman.conf +# Synchronize the fauxlo repo behind pacman's back. (-Sy would otherwise refresh +# the other repos, which we want frozen in time.) +curl -Ro "$mountpoint"/usr/lib/holo/pacmandb/sync/fauxlo.db https://fauxlo.ili.fyi/pacman/x86_64/fauxlo.db +# Install packages. +pacman --sysroot "$mountpoint" --gpgdir /tmp/gnupg --noconfirm -S \ + linux-neptune-61 + +# Set FastConnectable=true in /etc/bluetooth, as we don't have any concern over +# battery life +sed -i -e '/^#\?FastConnectable/c FastConnectable = true' "$mountpoint"/etc/bluetooth/main.conf +# Don't disable multicast DNS. +rm "$mountpoint"/usr/lib/systemd/resolved.conf.d/00-disable-mdns.conf + +# Mark read-only and unmount +btrfs property set -ts "$mountpoint" ro true +fstrim -v "$mountpoint" +umount --recursive "$mountpoint" + +# Prepare bundle +mkdir "$out_tmp"/bundle +echo "$fs_uuid" >"$out_tmp"/bundle/UUID +casync make --store="$out_tmp/steamdeck-$buildid-$version.castr" "$out_tmp"/bundle/rootfs.img.caibx "$out_tmp"/rootfs.img +cat >"$out_tmp"/bundle/manifest.raucm <<EOF +[update] +compatible=steamos-amd64 +version=$version + +[image.rootfs] +sha256=$(sha256sum "$out_tmp"/rootfs.img | awk '{ print $1 }') +size=$(stat -c %s "$out_tmp"/rootfs.img) +filename=rootfs.img.caibx +EOF + +mv "$out_tmp" "$out_dir/$buildid" +chown -R "$(logname)":"$(id -gn "$(logname)")" "$out_dir/$buildid" +echo "$out_dir/$buildid" |