mirror of
https://github.com/philmmanjaro/alma.git
synced 2025-07-27 07:29:29 +02:00
243 lines
5.5 KiB
Bash
Executable File
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
|