diff --git a/emhttp/plugins/unRAIDServer/unRAIDServer.plg b/emhttp/plugins/unRAIDServer/unRAIDServer.plg index a9ddf690a3..9e95fc77a5 100644 --- a/emhttp/plugins/unRAIDServer/unRAIDServer.plg +++ b/emhttp/plugins/unRAIDServer/unRAIDServer.plg @@ -366,6 +366,22 @@ rm -f /boot/config/plugins/dynamix.plg if [[ -x /usr/local/emhttp/plugins/unraid.patch/scripts/patch.php ]]; then /usr/local/emhttp/plugins/unraid.patch/scripts/patch.php check &version; fi +# Fire the generic 'os_update' event: a pre-reboot hook for an OS update that +# any plugin can register for (config migration, backups, compatibility checks +# and - for out-of-tree driver plugins - staging a build matching the INCOMING +# kernel so a reboot never lands on a kernel without its driver). The new release +# files - including changes.txt - are already on the flash here; pass the +# incoming Unraid version and kernel release as context (consumers ignore what +# they do not need). Hooks run synchronously, so the reboot prompt below only +# appears once they have finished. Self-registering: a plugin just installs an +# executable at its event/os_update path - no hardcoded list. +new_kernel=$(awk '/[Ll]inux kernel/{f=3} f>0{if(match($0,/[0-9]+(\.[0-9]+)+/)){print substr($0,RSTART,RLENGTH);exit}f--}' /boot/changes.txt 2>/dev/null | head -1) +if [ -n "$new_kernel" ]; then new_kernel="${new_kernel}-Unraid"; fi +if [ -x /usr/local/sbin/emhttp_event ]; then + # Bound the whole dispatch so a wedged hook cannot stall the update forever; + # a hook that needs longer should background itself and notify (see emhttp_event). + timeout 300 /usr/local/sbin/emhttp_event os_update "&version;" "$new_kernel" +fi # ensure writes to USB flash boot device have completed sync -f /boot if [ -z "${plg_update_helper}" ]; then diff --git a/sbin/emhttp_event b/sbin/emhttp_event index c9aab091f6..64f1dbbdcc 100755 --- a/sbin/emhttp_event +++ b/sbin/emhttp_event @@ -79,6 +79,22 @@ # Note that if array is not Started, emhttpd will not spin down any disk, but emhttpd will # still poll SMART data (for spun-up devices) and generate this event. +# os_update +# Occurs during an Unraid OS update, after the new release files (including +# /boot/changes.txt) have been written to the flash but BEFORE the user reboots. +# Fired by the unRAIDServer plugin, not by emhttpd. A general pre-reboot hook +# for an OS update: any plugin can run work that must happen before rebooting +# into the new release - e.g. migrate/convert config, back something up, warn +# about an incompatibility, or (for out-of-tree driver plugins) stage a build +# matching the incoming kernel so the reboot never lands on a kernel without it. +# Extra arguments, passed as context (ignore if not needed): $2 = incoming +# Unraid version, $3 = incoming kernel release (uname -r form, e.g. +# 6.18.33-Unraid; empty if it could not be determined). +# Hooks run synchronously and the whole dispatch is bounded by a timeout, so +# keep them quick and use network timeouts. A hook that genuinely needs long +# or async work should fork itself, return promptly, and surface its own result +# via notify - rather than blocking the OS update. + # Invoke all 'any_event' scripts that might exist for Dir in /usr/local/emhttp/plugins/* ; do if [ -d $Dir/event/any_event ]; then