Add kill switch and recover.sh for emergency recovery

If the patch ever prevents middlewared from starting, users now have a
clear escape hatch that requires no knowledge of Python internals:

  bash /data/truecloud-patch/recover.sh

Or at a bare shell prompt:

  touch /data/truecloud-patch/disabled
  systemctl restart middlewared

sitecustomize.py checks for /data/truecloud-patch/disabled at Python
startup and skips the import hook entirely when the file exists.
apply.sh does the same so the PREINIT script also does nothing on reboot.

recover.sh is copied to /data/truecloud-patch/ by install.sh so it is
available even without the original repo directory.

README gains an "Emergency recovery" section above Troubleshooting.
This commit is contained in:
2026-06-15 02:35:55 +00:00
parent 2d32c81485
commit 8f24725078
5 changed files with 84 additions and 1 deletions
+30
View File
@@ -167,6 +167,36 @@ restart.
---
## Emergency recovery
If middlewared stops starting after installing this patch, run this from the
TrueNAS shell (local console, SSH, or the debug shell in the UI):
```bash
bash /data/truecloud-patch/recover.sh
```
That creates a kill-switch file (`/data/truecloud-patch/disabled`) that
`sitecustomize.py` checks at startup. With the switch set, the import hook is
skipped entirely and middlewared starts clean. Your system returns to
Storj-only TrueCloud Backup — nothing else is affected.
If you cannot run a script and only have a bare shell prompt:
```bash
touch /data/truecloud-patch/disabled
systemctl restart middlewared
```
To re-enable the patch after investigating:
```bash
rm /data/truecloud-patch/disabled
bash /data/truecloud-patch/apply.sh
```
---
## Troubleshooting
**Apply log** (check after each reboot or install):
+2 -1
View File
@@ -43,7 +43,8 @@ cp "$REPO_DIR/patch/sitecustomize.py" "$PATCH_DIR/"
cp "$REPO_DIR/patch/patch_ui.py" "$PATCH_DIR/"
cp "$REPO_DIR/patch/apply.sh" "$PATCH_DIR/"
cp "$REPO_DIR/patch/create_task.py" "$PATCH_DIR/"
chmod +x "$PATCH_DIR/apply.sh" "$PATCH_DIR/create_task.py"
cp "$REPO_DIR/recover.sh" "$PATCH_DIR/"
chmod +x "$PATCH_DIR/apply.sh" "$PATCH_DIR/create_task.py" "$PATCH_DIR/recover.sh"
echo "Done."
echo ""
+9
View File
@@ -29,6 +29,15 @@ fi
exec >> "$LOG" 2>&1
echo "=== $(date -Iseconds) ==="
# Kill switch: if this file exists, skip all patching and exit cleanly.
# Recovery: touch /data/truecloud-patch/disabled (then reboot or restart middlewared).
if [ -f "$PATCH_DIR/disabled" ]; then
echo "Kill switch active ($PATCH_DIR/disabled exists) — patch not applied."
echo "To re-enable: rm $PATCH_DIR/disabled"
echo "=== done ==="
exit 0
fi
# ── Helpers ───────────────────────────────────────────────────────────────────
warn() { echo "WARNING: $*"; }
+3
View File
@@ -183,6 +183,9 @@ _PATCHES = {
def _install():
import importlib.util
import os
if os.path.exists("/data/truecloud-patch/disabled"):
return # kill switch: touch /data/truecloud-patch/disabled to bypass this hook
if importlib.util.find_spec("middlewared") is None:
return # not a middlewared Python process; nothing to do
sys.meta_path.append(_Finder())
Executable
+40
View File
@@ -0,0 +1,40 @@
#!/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 /data/truecloud-patch/recover.sh
#
# What it does:
# 1. Creates /data/truecloud-patch/disabled — sitecustomize.py checks for this
# file at startup and skips the import hook entirely, so middlewared starts
# clean without any of our code running.
# 2. Restarts middlewared.
#
# To re-enable the patch after investigating:
# rm /data/truecloud-patch/disabled
# bash /data/truecloud-patch/apply.sh
PATCH_DIR="/data/truecloud-patch"
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 "Restarting middlewared ..."
systemctl restart middlewared
echo ""
echo "middlewared restarted without the truecloud-patch hook."
echo "Your system should be back to normal (Storj-only TrueCloud Backup)."
echo ""
echo "To re-enable the patch once you have investigated:"
echo " rm $PATCH_DIR/disabled"
echo " bash $PATCH_DIR/apply.sh"