alma_philmmanjaro/presets/steam/steamos/bin/pacman-system-update
2023-07-03 14:31:13 +02:00

243 lines
5.5 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright (c) 2020 Gaël PORTAY
#
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# https://www.freedesktop.org/software/systemd/man/systemd.offline-updates.html
set -e
set -u
set -o pipefail
VERSION="1.1"
opts=(--noconfirm --noprogressbar --cachedir /var/lib/system-update)
while [[ "$#" -ne 0 ]]
do
if [[ "$1" =~ (-h|--help) ]]
then
echo "Usage: ${0##*/} [--now] [--force] [--] [pacman-extra-flags]"
exit 0
elif [[ "$1" =~ (-V|--version) ]]
then
echo "$VERSION"
exit
elif [[ "$1" == "--now" ]]
then
now=true
elif [[ "$1" == "--force" ]]
then
force=true
elif [[ "$1" == "--" ]]
then
shift
break
else
echo "$1: Invalid argument" >&2
exit 1
fi
shift
done
if [[ -z "${now:-}" ]]
then
if [[ ! -e /system-update ]] || [[ "${force:-}" ]]
then
echo ":: Preparing offline system updates..."
mkdir -p /var/lib/system-update
pacman "${opts[@]}" --downloadonly -Syu "$@"
mapfile -t pkgs < <(find /var/lib/system-update -name "*.pkg.tar.*")
if [[ "${#pkgs[@]}" -eq 0 ]]
then
exit 0
fi
ln -sf /var/lib/system-update /system-update
if [[ "$#" -gt 0 ]]
then
echo "$@" >/var/lib/system-update/.flags
fi
fi
echo ":: Please reboot the machine to trigger the offline system updates."
if [[ -e /var/lib/system-update/.flags ]]
then
cat /var/lib/system-update/.flags
fi
exit
fi
# As the first step, an update service should check if the /system-update
# symlink points to the location used by that update service. In case it does
# not exist or points to a different location, the service must exit without
# error.
if [[ ! -L /system-update ]] ||
[[ "$(readlink -f /system-update)" != "/var/lib/system-update" ]]
then
echo ":: No offline system updates prepared."
exit 0
fi
# Make sure to remove the /system-update symlink as early as possible in the
# update script to avoid reboot loops in case the update fails.
rm -f /system-update
progress() {
if plymouth --ping 2>/dev/null
then
plymouth system-update --progress="$1"
fi
echo -n "$1 "
}
if [[ -r /var/lib/system-update/.flags ]]
then
read -r -a extraflags < <(cat /var/lib/system-update/.flags)
if [[ "${#extraflags[@]}" -gt 0 ]]
then
set -- "$@" "${extraflags[@]}"
fi
rm -f /var/lib/system-update/.flags
fi
# If your script succeeds you should trigger the reboot in your own code, for
# example by invoking logind's Reboot() call or calling systemctl reboot. See
# logind dbus API for details.
# shellcheck disable=SC2154
trap 'ret="$?"; trap - 0; if [ "$ret" -eq 0 ]; then systemctl reboot; return "$ret"; fi' 0 INT
if plymouth --ping 2>/dev/null
then
plymouth change-mode --system-upgrade
plymouth system-update --progress=0
fi
i=0
step=
while read -r -a words
do
# empty line: skip it!
if [[ "${#words[@]}" -eq 0 ]]
then
continue
fi
# the pacman steps:
# :: Synchronizing package databases...
# :: Starting full system upgrade...
# :: Proceed with installation? [Y/n]
# :: Retrieving packages...
# :: Running pre-transaction hooks...
# :: Processing package changes...
# :: Running post-transaction hooks...
if [[ "${words[0]}" =~ :: ]]
then
i=0
step="${words[*]:1}"
if [[ "$step" == "Synchronizing package databases..." ]] ||
[[ "$step" == "Retrieving packages..." ]] ||
[[ "$step" == "Running pre-transaction hooks..." ]] ||
[[ "$step" == "Running post-transaction hooks..." ]]
then
echo "$step"
fi
continue
fi
# nothing to do: exit early!
if [[ "${words[0]}" == "there is nothing to do" ]]
then
echo "Nothing to do, rebooting..."
break
fi
# :: Starting full system upgrade...
# resolving dependencies...
# looking for conflicting packages...
#
# Packages (4) pkg1 pkg2 pkg3 pkg4
#
# Total Download Size: ##.## MiB
# Total Installed Size: ##.## MiB
# Net Upgrade Size: ##.## MiB
#
if [[ "${words[0]}" == "Packages" ]]
then
# Packages (4) (...)
if [[ "${words[1]}" =~ ^\([0-9]+\)$ ]]
then
count="${words[1]:1:$((${#words[1]}-2))}"
fi
# :: Retrieving packages...
# downloading pkg...
# :: Processing package changes...
# upgrading pkg...
elif [[ "${words[0]}" =~ ^(downloading|installing|upgrading)$ ]] &&
[[ "$step" != "Synchronizing package databases..." ]]
then
i="$((i+1))"
processing="${words[0]:0:1}"
processing="${processing^^}"
processing+="${words[0]:1}"
if [[ -z "${count:-}" ]]
then
echo "$processing ${words[1]}"
continue
elif [[ "${words[0]}" == downloading ]]
then
echo "$processing ${words[1]} ($i/$count)"
continue
fi
progress "$((20+(60*i)/count))"
echo "$processing ${words[1]} ($i/$count)"
continue
# :: Running pre-transaction hooks...
# ( #/##) Doing something...
# (##/##) Doing another thing...
# :: Running post-transaction hooks...
# (#/#) Doing a last thing...
elif [[ "$step" == "Running pre-transaction hooks..." ]] ||
[[ "$step" == "Running post-transaction hooks..." ]]
then
# ( #/##) (...): remove the parasite space.
if [[ "${words[0]}" == "(" ]]
then
words[1]="${words[0]}${words[1]}"
words[0]=
words=("${words[@]:1}")
fi
if ! [[ "${words[0]}" =~ ^\([0-9]+/[0-9]+\)$ ]]
then
echo "${words[*]}"
continue
fi
if [[ "$step" == "Running pre-transaction hooks..." ]]
then
base=0
else
base=80
fi
val="${words[0]:1:$((${#words[0]}-2))}"
progress "$((base+20*${val// /}))"
echo "${words[*]:1} ${words[0]}"
continue
fi
done < <(pacman "${opts[@]}" -Su "$@")
rm -f /var/lib/system-update/*.pkg.tar.*
if plymouth --ping 2>/dev/null
then
plymouth change-mode --boot-up
plymouth display-message --text="Rebooting..."
fi
echo "Rebooting..."
sleep 5s