Current Dir: /snap/canonical-livepatch/418/resources/
[DIR] tests [ delete | rename ]
[FILE] 20canonical-livepatch [ edit | delete | rename ]
[FILE] 99-livepatch-kernel-upgrade-required [ edit | delete | rename ]
[FILE] livepatch-kernel-installed [ edit | delete | rename ]
[FILE] reboot-required-check [ edit | delete | rename ]
Viewing: /snap/canonical-livepatch/418/resources/reboot-required-check
#!/bin/sh
#
# $SNAP/resources/reboot-required-check
#
# Run from /etc/apt/apt.conf.d/20canonical-livepatch as a DPkg::Post-Invoke
# hook, after all dpkg calls (and therefore after zz-update-grub has
# regenerated /boot/grub/grub.cfg). It removes /var/run/reboot-required and
# /var/run/reboot-required.pkgs only when Livepatch can prove the currently
# running kernel is covered.
#
NOTE="/run/canonical-livepatch-kernel-installed"
GRUB_CFG="/boot/grub/grub.cfg"
REBOOT_REQUIRED="/var/run/reboot-required"
REBOOT_REQUIRED_PKGS="/var/run/reboot-required.pkgs"
LIVEPATCH="/snap/bin/canonical-livepatch"
TIMEOUT_SECONDS=10
REFRESH_TIMEOUT_SECONDS=20
# Step 1: no note means no kernel was installed in this apt run.
if [ ! -f "$NOTE" ]; then
exit 0
fi
# Step 2: not a GRUB system. Exit early.
if [ ! -f "$GRUB_CFG" ]; then
rm -f "$NOTE"
exit 0
fi
# Step 3: grub.cfg is not newer than the note, so update-grub has not run
# yet for this kernel. Keep the note; a later apt run will see a fresh
# grub.cfg.
if [ "$NOTE" -nt "$GRUB_CFG" ]; then
exit 0
fi
# Step 4: one removal attempt per kernel install. If the note still exists
# afterwards, it cannot be removed; stop here so this does not retry forever
# on every apt run.
rm -f "$NOTE"
if [ -f "$NOTE" ]; then
exit 0
fi
# Step 5: no reboot-required marker, or reboot-required.pkgs does not
# unambiguously list only pending kernel packages.
if [ ! -f "$REBOOT_REQUIRED" ]; then
exit 0
fi
if [ ! -f "$REBOOT_REQUIRED_PKGS" ] || [ ! -r "$REBOOT_REQUIRED_PKGS" ] || [ ! -s "$REBOOT_REQUIRED_PKGS" ]; then
exit 0
fi
saw_linux_pkg=0
while IFS= read -r line || [ -n "$line" ]; do
case "$line" in
# Ignore blank lines in the package list.
"")
continue
;;
# Record that at least one pending package is a kernel image.
linux-image*)
saw_linux_pkg=1
;;
# Allow linux-base, which update-notifier also records for kernel installs.
linux-base)
;;
# Keep the reboot notice for any other pending package.
*)
exit 0
;;
esac
done < "$REBOOT_REQUIRED_PKGS"
if [ "$saw_linux_pkg" -ne 1 ]; then
exit 0
fi
# Step 6: the livepatch client must be present, and the admin must have opted
# into livepatch-aware reboot notifications.
if [ ! -x "$LIVEPATCH" ]; then
exit 0
fi
policy=$(
timeout "$TIMEOUT_SECONDS" "$LIVEPATCH" config reboot-notification-policy --format=json 2> /dev/null
)
if [ $? -ne 0 ]; then
exit 0
fi
case "$policy" in
'{"reboot-notification-policy":"livepatch-aware"}')
;;
*)
exit 0
;;
esac
# Step 7: refresh so the daemon re-reads the now-fresh grub.cfg and fetches
# the latest Kernel-Upgrade data before asking it to decide.
echo "Livepatch: checking kernel coverage..."
timeout "$REFRESH_TIMEOUT_SECONDS" "$LIVEPATCH" refresh > /dev/null 2>&1
if [ $? -ne 0 ]; then
exit 0
fi
# Step 8: only a proven-covered kernel (exit 1) removes the notice. Any other
# exit code, including a timeout, leaves both files untouched.
timeout "$TIMEOUT_SECONDS" "$LIVEPATCH" kernel-upgrade-required > /dev/null 2>&1
code=$?
if [ "$code" -ne 1 ]; then
exit 0
fi
rm -f "$REBOOT_REQUIRED_PKGS" || exit 0
rm -f "$REBOOT_REQUIRED" || exit 0
echo "Livepatch: reboot-required notice removed; the running kernel is covered by Livepatch."