mirror of
https://github.com/philmmanjaro/alma.git
synced 2025-07-27 07:29:29 +02:00
178 lines
5.1 KiB
Bash
Executable File
178 lines
5.1 KiB
Bash
Executable File
#!/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-2020 Collabora Ltd.
|
|
# Copyright © 2019-2020 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
|
|
|
|
DISK= # --disk=
|
|
PARTSET= # --partset=
|
|
|
|
SYMLINKS_DIR=/dev/disk/by-partsets
|
|
|
|
[ -e /usr/lib/steamos/steamos-partitions-lib ] && \
|
|
. /usr/lib/steamos/steamos-partitions-lib || \
|
|
{ echo "Failed to source '/usr/lib/steamos/steamos-partitions-lib'"; exit 1; }
|
|
|
|
# Helpers
|
|
|
|
fail() { echo >&2 "$@"; exit 1; }
|
|
|
|
usage() {
|
|
local status=${1-2}
|
|
|
|
if [ $status -ne 0 ]; then
|
|
exec >&2
|
|
fi
|
|
|
|
echo
|
|
echo "Usage: $(basename $0) [--disk=DISK] --partset=A|B|self|other -- COMMAND"
|
|
echo
|
|
echo "Run COMMAND in a chroot. The chroot is SteamOS specific, which means"
|
|
echo "that the various SteamOS partitions are mounted within the chroot."
|
|
echo
|
|
echo "There are two use-cases for this command:"
|
|
echo
|
|
echo "1. Chroot into the 'other' SteamOS, useful for atomic update. For example:"
|
|
echo
|
|
echo " $(basename $0) --partset other -- COMMAND"
|
|
echo
|
|
echo "2. Chroot into another SteamOS install, on another disk. For example:"
|
|
echo
|
|
echo " $(basename $0) --disk /dev/sdb --partset A -- COMMAND"
|
|
echo
|
|
echo "The second mode works if SteamOS is installed alone on the disk, however"
|
|
echo "if there are other partitions on the disk then it's not guaranteed to work."
|
|
echo "This is because we rely on partition labels to find SteamOS partitions and"
|
|
echo "setup the chroot. This is too fragile, and if we're unlucky there could be"
|
|
echo "another partition that doesn't belong to SteamOS but uses the same partition"
|
|
echo "label."
|
|
echo
|
|
|
|
exit $status
|
|
}
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
-h|--help)
|
|
usage 0
|
|
;;
|
|
-d|--disk)
|
|
shift
|
|
[ "${1:-}" ] || usage 1
|
|
DISK=$1
|
|
shift
|
|
;;
|
|
-p|--partset)
|
|
shift
|
|
[ "${1:-}" ] || usage 1
|
|
PARTSET=$1
|
|
shift
|
|
;;
|
|
--)
|
|
shift
|
|
break
|
|
;;
|
|
*)
|
|
usage 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
[ "$PARTSET" ] || usage 1
|
|
|
|
# Find devices
|
|
|
|
ESP_DEVICE=
|
|
EFI_DEVICE=
|
|
ROOTFS_DEVICE=
|
|
|
|
if [ "$DISK" ]; then
|
|
# A disk was provided, which means that we're chrooting into another
|
|
# SteamOS install. We do our best to 'guess' the partitions, ie. we
|
|
# mostly rely on partition labels. This is OK if SteamOS is alone on
|
|
# this disk, but it's fragile if it's installed along another OS.
|
|
[ -b "$DISK" ] || fail "'$DISK' is not a block device"
|
|
ROOTFS_DEVICE=$(get_device_by_partlabel $DISK rootfs-$PARTSET)
|
|
EFI_DEVICE=$(get_device_by_partlabel $DISK efi-$PARTSET)
|
|
VAR_DEVICE=$(get_device_by_partlabel $DISK var-$PARTSET)
|
|
ESP_DEVICE=$(get_device_by_partlabel $DISK esp)
|
|
if [ -z "$ESP_DEVICE" ]; then
|
|
ESP_DEVICE=$(get_device_by_typeuuid $DISK \
|
|
c12a7328-f81f-11d2-ba4b-00a0c93ec93b)
|
|
fi
|
|
else
|
|
# No disk was provided, which means that we're chrooting into the
|
|
# 'other' install, A or B. We can find these partitions reliably
|
|
# using the existing symlinks.
|
|
ROOTFS_DEVICE=$(realpath $SYMLINKS_DIR/$PARTSET/rootfs)
|
|
EFI_DEVICE=$(realpath $SYMLINKS_DIR/$PARTSET/efi)
|
|
ESP_DEVICE=$(realpath $SYMLINKS_DIR/shared/esp)
|
|
VAR_DEVICE=$(realpath $SYMLINKS_DIR/$PARTSET/var)
|
|
fi
|
|
|
|
[ -b "$ROOTFS_DEVICE" ] || fail "'$ROOTFS_DEVICE' is not a block device"
|
|
[ -b "$EFI_DEVICE" ] || fail "'$EFI_DEVICE' is not a block device"
|
|
[ -b "$ESP_DEVICE" ] || fail "'$ESP_DEVICE' is not a block device"
|
|
[ -b "$VAR_DEVICE" ] || fail "'$VAR_DEVICE' is not a block device"
|
|
|
|
# Do the job
|
|
|
|
prepare_chroot_at() {
|
|
|
|
local dir=$1
|
|
|
|
mount -o ro "$ROOTFS_DEVICE" $dir
|
|
mount --bind /dev $dir/dev
|
|
mount --bind /proc $dir/proc
|
|
mount --bind /run $dir/run
|
|
mount --bind /sys $dir/sys
|
|
mount --bind /sys/firmware/efi/efivars $dir/sys/firmware/efi/efivars
|
|
mount -t tmpfs -o size=128M tmpfs $dir/tmp
|
|
mount "$EFI_DEVICE" $dir/efi
|
|
mount "$ESP_DEVICE" $dir/esp
|
|
mount "$VAR_DEVICE" $dir/var
|
|
if [ -d $dir/var/boot ]; then
|
|
mount --bind $dir/var/boot $dir/boot
|
|
fi
|
|
}
|
|
|
|
cleanup_chroot_at() {
|
|
|
|
local dir=$1
|
|
|
|
if mountpoint -q $dir/boot; then
|
|
umount $dir/boot || :
|
|
fi
|
|
umount $dir/var || :
|
|
umount $dir/esp || :
|
|
umount $dir/efi || :
|
|
umount $dir/tmp || :
|
|
umount $dir/sys/firmware/efi/efivars || :
|
|
umount -R $dir/sys || :
|
|
umount $dir/run || :
|
|
umount -R $dir/proc || :
|
|
umount $dir/dev || :
|
|
umount $dir || :
|
|
|
|
rmdir $dir
|
|
}
|
|
|
|
CHROOTDIR=$(mktemp -d)
|
|
trap "cleanup_chroot_at $CHROOTDIR" EXIT
|
|
|
|
prepare_chroot_at $CHROOTDIR
|
|
chroot $CHROOTDIR "$@"
|