-
-
Save iliana/44c53bfa7eab4f04e952d6387d3e70ae to your computer and use it in GitHub Desktop.
/usr/lib/rauc/post-install.sh from steamos-customizations-jupiter 3.5.20231122.1-1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*- | |
# vim: et sts=4 sw=4 | |
# SPDX-License-Identifier: LGPL-2.1+ | |
# | |
# Copyright © 2019-2021 Collabora Ltd. | |
# Copyright © 2019-2021 Valve Corporation. | |
# | |
# This file is part of steamos-customizations. | |
# | |
# steamos-customizations is free software; you can redistribute it and/or | |
# modify it under the terms of the GNU Lesser General Public License as | |
# published by the Free Software Foundation; either version 2.1 of the License, | |
# or (at your option) any later version. | |
set -e | |
set -u | |
ERR=0 # the error code returned by this script | |
SYMLINKS_DIR=/dev/disk/by-partsets | |
BOOTCONF_RELDIR=SteamOS/conf | |
PARTSETS_RELDIR=SteamOS/partsets | |
ROOTHASH_RELPATH=SteamOS/roothash | |
RAUC_RUNTIME_DIR=/run/rauc | |
REBOOT_FOR_UPDATE=/run/steamos-atomupd/reboot_for_update | |
# | |
# Helpers | |
# | |
log () { echo >&2 "$@"; } | |
warn() { echo >&2 "Warning:" "$@"; } | |
err () { echo >&2 "Error:" "$@"; ERR=1; } | |
fail() { echo >&2 "Error:" "$@"; exit 1; } | |
# | |
# Re-enable systemd timers | |
# | |
ACTIVE_TIMERS=$RAUC_RUNTIME_DIR/active-timers | |
if [ -e "$ACTIVE_TIMERS" ]; then | |
while read -r service; do | |
[[ "$service" ]] || continue | |
systemctl start "$service" | |
done < "$ACTIVE_TIMERS" | |
fi | |
rm -f $ACTIVE_TIMERS | |
# | |
# Take a slot and the json from steamos-atomupd/manifest.json and make | |
# a suitable boot menu label, falling back to something generic | |
# | |
boot_label () { | |
local slot=${1:-\?} | |
local blob=${2:-"{}"} | |
local version=$(jq -rc '.version' <<<"$blob") | |
local product=$(jq -rc '.product' <<<"$blob") | |
local buildid=$(jq -rc '.buildid' <<<"$blob") | |
case ${buildid} in (null) buildid=""; ;; esac | |
case ${version} in (snapshot|null) version=""; ;; esac | |
case ${product,,} in (steamos|null|'') product=SteamOS; ;; esac | |
local ident=${version}${version:+-}${buildid} | |
echo "${product}-$slot${ident:+-}${ident}" | |
} | |
# | |
# Handle the 'other' efi partition | |
# | |
configure_other_efi() { | |
local efi=$1 | |
local keep_slot=$2 | |
local update_slot=$3 | |
local bootconf= | |
local confdir= | |
local partsets= | |
local roothash= | |
local title= | |
local ident= | |
local self_partsets= | |
# bootconf needs the partset data now so set it up first: | |
partsets=$efi/$PARTSETS_RELDIR | |
if ! [ -e "$partsets" ]; then | |
self_partsets="/efi/$PARTSETS_RELDIR" | |
log "Initializing 'other' efi partsets: '$self_partsets' -> '$partsets'" | |
mkdir -p "$partsets" | |
cp "$self_partsets/all" "$partsets/" | |
cp "$self_partsets/shared" "$partsets/" | |
# the updated slot partset info goes into self, | |
# and the preserved slot info goes into other | |
# we could just swap self and other, but we want to support | |
# updates while the dev slot is booted as well as A/B: | |
cp "$self_partsets/$update_slot" "$partsets/self" | |
cp "$self_partsets/$keep_slot" "$partsets/other" | |
if [ -e "$self_partsets/dev" ]; then | |
cp "$self_partsets/dev" "$partsets/dev" | |
fi | |
fi | |
ident=$update_slot | |
confdir=/esp/$BOOTCONF_RELDIR | |
bootconf=$confdir/${ident}.conf | |
if ! [ -e "$bootconf" ]; then | |
log "Initializing 'other' esp bootconf: '$bootconf'" | |
mkdir -p "$confdir" | |
steamos-bootconf create --conf-dir "$confdir" --image "$ident" --set title "$ident" | |
fi | |
roothash=$efi/$ROOTHASH_RELPATH | |
if [ -e "$RAUC_UPDATE_SOURCE/roothash" ]; then | |
mkdir -p "$(dirname "$roothash")" | |
cp -f "$roothash_update_file" "$roothash" | |
fi | |
} | |
log "Detecting 'other' efi partition" | |
declare -r BOOTED_SLOT=$(steamos-bootconf this-image) | |
PRESERVED_SLOT= | |
UPDATED_SLOT= | |
log "Booted into slot $BOOTED_SLOT" | |
case $BOOTED_SLOT in | |
A) | |
PRESERVED_SLOT=A | |
UPDATED_SLOT=B | |
EFI_DEVICE_OTHER=$(realpath $SYMLINKS_DIR/other/efi) | |
;; | |
B) | |
PRESERVED_SLOT=B | |
UPDATED_SLOT=A | |
EFI_DEVICE_OTHER=$(realpath $SYMLINKS_DIR/other/efi) | |
;; | |
*) | |
while read valid slot x | |
do | |
case $valid$slot in | |
+A) | |
UPDATED_SLOT=B | |
PRESERVED_SLOT=A | |
;; | |
+B) | |
UPDATED_SLOT=A | |
PRESERVED_SLOT=B | |
;; | |
esac | |
done < <(steamos-bootconf list-images) | |
EFI_DEVICE_OTHER=$(realpath $SYMLINKS_DIR/$UPDATED_SLOT/efi) | |
;; | |
esac | |
log "Update slot candidate is $UPDATED_SLOT" | |
log "Configuring the 'other' efi partition $EFI_DEVICE_OTHER " \ | |
"($PRESERVED_SLOT -> $UPDATED_SLOT)" | |
[ -b "$EFI_DEVICE_OTHER" ] || \ | |
fail "Other efi device '$EFI_DEVICE_OTHER' not found" | |
mount "$EFI_DEVICE_OTHER" /mnt | |
configure_other_efi /mnt $PRESERVED_SLOT $UPDATED_SLOT || \ | |
err "Failed to configure the 'other' efi" | |
umount /mnt | |
# | |
# Handle the 'other' var partition | |
# | |
ismounted() { | |
local device=$1 | |
findmnt --real --source "$device" >/dev/null 2>&1 | |
} | |
reformat_device_ext4() { | |
local device=$1 | |
local opts= | |
local label= | |
device=$(readlink -f "$device") | |
if ! [ -b "$device" ]; then | |
warn "'$device' is not a block device" | |
return | |
fi | |
if ismounted "$device"; then | |
umount -v "$device" | |
fi | |
if ismounted "$device"; then | |
umount -v -f "$device" | |
fi | |
label=$(e2label "$device") | |
if [ "$label" ]; then | |
opts="$opts -L $label" | |
fi | |
mkfs.ext4 -q -F $opts "$device" | |
} | |
sync_var_mountpoints() { | |
local src=$1 | |
local dst=$2 | |
# --one-file-system makes sure that we ignore all the directories from /home | |
# that are bind-mounted onto /var directories. | |
# | |
# We exclude the directories /var/lib/{dkms,modules,pacman}, as they don't | |
# really represent a state that we want to keep, but rather a part of the | |
# rootfs that ends up leaving in /var for technical reasons. These pieces | |
# must be empty on first boot, so that they can be initialized from the | |
# factory that is shipped with the rootfs. | |
# | |
# We also need to exclude /var/boot, which might contain the initrd that | |
# was rebuilt to include nvidia drivers built by DKMS. Once again, this is | |
# not a state that we want to keep. | |
# | |
# Exclude `/etc/os-release` changes because that file is used by the Steam | |
# client to show the current image version, and we don't want to preserve | |
# outdated info across updates. | |
# | |
# We also exclude any potential user changes to the RAUC configuration | |
# to avoid the risk of breaking the updates by using an unexpected config. | |
# | |
# Do not copy the gnupg keyring - the new image is RO and it makes little | |
# sense to have keyring around. People will either use steamos-devmode | |
# enable - which will regenerate it for them, or if they manually flip off | |
# the RO mode, they can issue pacman-key manually. | |
fsfreeze -f "$src" | |
rsync \ | |
--archive \ | |
--delete \ | |
--one-file-system \ | |
--exclude="/boot/" \ | |
--exclude="/lib/dkms/" \ | |
--exclude="/lib/modules/" \ | |
--exclude="/lib/pacman/" \ | |
--exclude="/lib/NetworkManager/" \ | |
--exclude="/lost+found/" \ | |
--exclude="/lib/overlays/etc/upper/os-release" \ | |
--exclude="/lib/overlays/etc/upper/rauc" \ | |
--exclude="/lib/overlays/etc/upper/pacman.d/gnupg" \ | |
"$src/" "$dst/" | |
fsfreeze -u "$src" | |
# Explicitly remove and mask/whiteout the .updated files in /var and /etc | |
# respectively. Counter intuitively The timestamp stored is for the /usr | |
# folder. Without this services like ldconfig won't trigger and we'll end up | |
# with potential references to the other partset. | |
# | |
# Note: We want the explicit -r here since the user may have removed the | |
# file and created a folder in its place. | |
rm -rf "$dst/.updated" || : | |
rm -rf "$dst/lib/overlays/etc/upper/.updated" || : | |
mknod -m 000 "$dst/lib/overlays/etc/upper/.updated" || : | |
} | |
log "Syncing the var partitions from 'self' to 'other'" | |
VAR_DEVICE_OTHER=$(realpath $SYMLINKS_DIR/$UPDATED_SLOT/var) | |
VAR_DEVICE_FROM= | |
VAR_FROM= | |
case $BOOTED_SLOT in | |
A|B) | |
VAR_FROM=/var | |
;; | |
dev) | |
mkdir -p /tmp/from-var | |
VAR_DEVICE_FROM=$(realpath $SYMLINKS_DIR/$PRESERVED_SLOT/var) | |
VAR_FROM=/tmp/from-var | |
;; | |
esac | |
[ -b "$VAR_DEVICE_OTHER" ] || \ | |
fail "Other var device '$VAR_DEVICE_OTHER' not found" | |
if [ -n "$VAR_DEVICE_FROM" ] | |
then | |
[ -b "$VAR_DEVICE_FROM" ] || | |
fail "Source var device '$VAR_DEVICE_FROM' not found" | |
mount "$VAR_DEVICE_FROM" "$VAR_FROM" | |
fi | |
reformat_device_ext4 "$VAR_DEVICE_OTHER" || \ | |
err "Failed to reformat other var partition" | |
mount "$VAR_DEVICE_OTHER" /mnt | |
sync_var_mountpoints "$VAR_FROM" /mnt || \ | |
err "Failed to sync var partitions" | |
# Remove the old rootfs index to ensure that we either have the correct one | |
# or that we don't have it at all. | |
rm -f /mnt/lib/steamos-atomupd/rootfs.caibx | |
mkdir -p /mnt/lib/steamos-atomupd | |
cp "$RAUC_BUNDLE_MOUNT_POINT"/rootfs.img.caibx /mnt/lib/steamos-atomupd/rootfs.caibx || \ | |
warn "Failed to copy the rootfs seed index file" | |
umount /mnt | |
if [ -n "$VAR_DEVICE_FROM" ] | |
then | |
umount "$VAR_FROM" | |
fi | |
# | |
# Handle the bootloaders and network configuration | |
# | |
log "Installing the bootloaders" | |
# any newer image should have finalize-install but a downgrade may be missing it; | |
# if so look for an older post-install script | |
steamos-chroot --partset $UPDATED_SLOT -- steamos-finalize-install --no-kernel || \ | |
steamos-chroot --partset $UPDATED_SLOT -- steamos-boot-install --no-kernel || \ | |
err "Failed to install bootloaders" | |
# Mark the new partition valid, otherwise it will not boot | |
# (note; you can't call rauc status mark-good here) | |
(( $ERR == 0 )) && steamos-bootconf config --image $UPDATED_SLOT --set image-invalid 0 | |
# Store the installed update version in a temporary file to record that we | |
# have a pending reboot to switch to the new image | |
if [ $ERR == 0 ]; then | |
update_manifest=$(steamos-chroot --partset $UPDATED_SLOT -- cat "/etc/steamos-atomupd/manifest.json") | |
update_buildid=$(jq -r '.buildid | select(type == "string")' <<< "$update_manifest") | |
echo "$update_buildid" > "$REBOOT_FOR_UPDATE" | |
label=$(boot_label "$UPDATED_SLOT" "$update_manifest") | |
if [ -n "${label:-}" ]; then | |
steamos-chroot --partset $UPDATED_SLOT -- \ | |
steamos-bootconf config --set title "${label:-}" | |
fi | |
fi | |
exit $ERR |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment