Files
truenas-truecloud-patch/recover.sh
T
flan 4e0814028c v0.5.0: TrueNAS alert when an update is available
Raises a real alert in the TrueNAS UI bell -- not a log line nobody reads. On by
default, checked once a day. install.sh --no-update-alerts turns it off.

It does not nag
---------------
A release whose CHANGELOG contains only a "### Docs" section changed no code and
raises nothing. Anything else raises INFO; a "### Security" section raises WARNING.

The CHANGELOG's own section headings are the signal, and a security fix anywhere in
the range escalates the whole span -- a docs-only release sitting on top of a
security fix still reports as security rather than hiding it.

Why an AlertSource and not midclt
----------------------------------
TrueNAS cannot raise an alert from the CLI. midclt exposes only alert.dismiss,
alert.list, alert.list_categories, alert.list_policies and alert.restore -- alert
CREATION is internal to middlewared, and none of its ~60 one-shot classes is
generic enough to reuse. Registering an AlertSource is the only way.

It is also the least invasive thing this patch does. The providers and nested
modules both APPEND CODE TO STOCK middleware files; the alert source ADDS ONE FILE
and modifies none. It is the native mechanism -- the same one every built-in
TrueNAS alert uses -- and TrueNAS polls it itself, so there is no cron job and no
systemd timer.

- Fail-safe: every error path returns None; it cannot take middlewared down.
- Read-only: `git ls-remote` plus an HTTPS fetch of the CHANGELOG. It never writes
  to .git, so it cannot leave root-owned objects behind the way a `git fetch` from
  middlewared (running as root) would.
- Removed by uninstall.sh (mw_patch.revert_all).
- It only tells you; it never updates anything.

Verified against the real repo and remote, with middlewared stubbed:
  on v0.4.1, only a README-only v0.4.2 available -> NO ALERT
  on v0.4.0, v0.4.1 fixed real bugs             -> INFO
  on v0.3.2, v0.3.3 was the password fix        -> SECURITY / WARNING

139 tests, ruff and shellcheck -S style clean.
2026-07-13 16:45:26 +00:00

86 lines
3.0 KiB
Bash
Executable File

#!/bin/bash
# recover.sh — emergency recovery if middlewared won't start after installing truecloud-patch.
#
# Run this from the TrueNAS shell (local console, SSH, or debug shell):
#
# bash /mnt/tank/truenas-truecloud-patch/recover.sh
#
# What it does:
# 1. Creates a "disabled" file in the repo root — apply.sh checks for this
# file at boot and skips all patching, so the next boot is always clean.
# 2. Unmounts any active truecloud overlays so the original /usr files are
# visible immediately (no reboot required).
# 3. Restarts middlewared against the unpatched files.
#
# To re-enable the patch after investigating:
# rm /mnt/tank/truenas-truecloud-patch/disabled
# bash /mnt/tank/truenas-truecloud-patch/patch/apply.sh
# systemctl restart middlewared
VERSION="0.5.0"
PATCH_DIR="$(cd "$(dirname "$0")" && pwd)"
echo "=== TrueNAS TrueCloud Provider Patch v${VERSION} — Recover ==="
echo ""
if [ "$(id -u)" -ne 0 ]; then
echo "ERROR: must be run as root." >&2
exit 1
fi
if [ ! -d "$PATCH_DIR" ]; then
echo "ERROR: $PATCH_DIR not found — truecloud-patch may not be installed." >&2
exit 1
fi
touch "$PATCH_DIR/disabled"
echo "Kill switch set: $PATCH_DIR/disabled created."
echo "Unmounting truecloud overlays ..."
_any=0
for _tag in mw ui; do
if mount | grep -qF "truecloud-${_tag} on "; then
_mnt=$(mount | grep "truecloud-${_tag} on " | awk '{print $3}' | head -1)
if umount "$_mnt" 2>/dev/null; then
echo " Unmounted: $_mnt"
_any=1
else
echo " WARNING: Could not unmount $_mnt — a reboot will restore original files."
fi
fi
done
[ "$_any" -eq 0 ] && echo " No overlays active."
# Nested-snapshot staging trees are bind mounts that PIN their ZFS snapshots, so
# leaving them mounted blocks those snapshots from ever being destroyed. The
# overlays above are volatile, but these are not self-healing without a reboot,
# and recover.sh is expected to work without one.
echo "Unmounting nested-snapshot staging trees ..."
# Best-effort: never block recovery. Same tested implementation as uninstall.sh.
python3 "$PATCH_DIR/patch/truecloud_nested.py" cleanup || true
# Cancel a deferred boot restart if one is still queued — we restart ourselves.
systemctl stop truecloud-mw-restart.service 2>/dev/null
systemctl reset-failed truecloud-mw-restart.service 2>/dev/null
echo "Restarting middlewared ..."
if systemctl restart middlewared; then
echo ""
echo "middlewared started successfully."
echo "Your system is back to normal (Storj-only TrueCloud Backup)."
else
echo ""
echo "WARNING: middlewared did not start cleanly even with the patch disabled."
echo "The problem is unrelated to truecloud-patch."
echo "Check the system log for details:"
echo " journalctl -u middlewared -n 50"
exit 1
fi
echo ""
echo "To re-enable the patch once you have investigated:"
echo " rm $PATCH_DIR/disabled"
echo " bash $PATCH_DIR/patch/apply.sh"
echo " systemctl restart middlewared"