Users who delete the cloned repo after install had no way to uninstall without re-cloning. Now install.sh copies uninstall.sh to PATCH_DIR alongside recover.sh, so the uninstall path is always the stable /data/truecloud-patch/uninstall.sh. README updated to match.
130 lines
5.2 KiB
Bash
Executable File
130 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# install.sh — run once on the TrueNAS box to set up truecloud-patch.
|
|
#
|
|
# Prerequisites: run as root on TrueNAS SCALE with middlewared running.
|
|
#
|
|
# What this does:
|
|
# 1. Copies patch files to /data/truecloud-patch/ (survives OS updates).
|
|
# 2. Registers a PREINIT initshutdownscript in the TrueNAS database so
|
|
# apply.sh re-applies the patches on every boot before middlewared starts.
|
|
# 3. Applies the patches immediately (no reboot required).
|
|
# 4. Restarts middlewared so the backend change takes effect now.
|
|
|
|
set -euo pipefail
|
|
|
|
PATCH_DIR="/data/truecloud-patch"
|
|
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
if [ ! -f "$REPO_DIR/patch/sitecustomize.py" ]; then
|
|
echo "ERROR: patch files not found at $REPO_DIR/patch/" >&2
|
|
echo "Run install.sh from the cloned repository, not via pipe:" >&2
|
|
echo " git clone https://github.com/sudolulo/truenas-truecloud-patch" >&2
|
|
echo " cd truenas-truecloud-patch && bash install.sh" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "=== TrueNAS TrueCloud Provider Patch — Install ==="
|
|
echo ""
|
|
|
|
# ── Preflight ─────────────────────────────────────────────────────────────────
|
|
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "ERROR: must be run as root." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v midclt &>/dev/null; then
|
|
echo "ERROR: midclt not found. Run this script on TrueNAS SCALE." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! midclt call core.ping &>/dev/null; then
|
|
echo "ERROR: middlewared is not responding. Is TrueNAS fully booted?" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ── Copy files ────────────────────────────────────────────────────────────────
|
|
|
|
echo "Copying patch files to $PATCH_DIR ..."
|
|
mkdir -p "$PATCH_DIR"
|
|
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/"
|
|
cp "$REPO_DIR/recover.sh" "$PATCH_DIR/"
|
|
cp "$REPO_DIR/uninstall.sh" "$PATCH_DIR/"
|
|
chmod +x "$PATCH_DIR/apply.sh" "$PATCH_DIR/create_task.py" "$PATCH_DIR/recover.sh" "$PATCH_DIR/uninstall.sh"
|
|
echo "Done."
|
|
echo ""
|
|
|
|
# ── Register PREINIT script ───────────────────────────────────────────────────
|
|
|
|
echo "Registering PREINIT boot hook ..."
|
|
|
|
EXISTING_ID=$(midclt call initshutdownscript.query '[]' | \
|
|
python3 -c "
|
|
import sys, json
|
|
for s in json.load(sys.stdin):
|
|
if s.get('script') == '/data/truecloud-patch/apply.sh':
|
|
print(s['id'])
|
|
break
|
|
" 2>/dev/null || true)
|
|
|
|
if [ -n "$EXISTING_ID" ]; then
|
|
echo "Already registered (id=$EXISTING_ID). Ensuring it is enabled ..."
|
|
midclt call initshutdownscript.update "$EXISTING_ID" \
|
|
'{"enabled": true}' > /dev/null
|
|
else
|
|
midclt call initshutdownscript.create \
|
|
'{"type":"SCRIPT","script":"/data/truecloud-patch/apply.sh","when":"PREINIT","enabled":true,"comment":"TrueCloud provider patch (S3/B2)"}' \
|
|
> /dev/null
|
|
echo "Registered."
|
|
fi
|
|
echo ""
|
|
|
|
# ── Clear kill switch if set ──────────────────────────────────────────────────
|
|
|
|
if [ -f "$PATCH_DIR/disabled" ]; then
|
|
rm "$PATCH_DIR/disabled"
|
|
echo "Removed kill switch ($PATCH_DIR/disabled) left from a previous recovery."
|
|
echo ""
|
|
fi
|
|
|
|
# ── Apply now ─────────────────────────────────────────────────────────────────
|
|
|
|
echo "Applying patches ..."
|
|
_log_start=$(wc -c < "$PATCH_DIR/apply.log" 2>/dev/null || echo 0)
|
|
bash "$PATCH_DIR/apply.sh"
|
|
echo ""
|
|
echo "Patch log ($PATCH_DIR/apply.log):"
|
|
tail -30 "$PATCH_DIR/apply.log"
|
|
echo ""
|
|
if tail -c "+$((_log_start + 1))" "$PATCH_DIR/apply.log" 2>/dev/null | grep -qE "WARNING:|ERROR:"; then
|
|
echo "WARNING: apply.sh reported one or more issues — see log above for details."
|
|
echo ""
|
|
fi
|
|
|
|
# ── Restart middlewared ───────────────────────────────────────────────────────
|
|
|
|
echo "Restarting middlewared so the backend patch takes effect ..."
|
|
if ! systemctl restart middlewared; then
|
|
echo "" >&2
|
|
echo "ERROR: middlewared failed to restart." >&2
|
|
echo " The patch IS installed and will activate automatically on the next boot." >&2
|
|
echo " To activate now, resolve the issue below and run: systemctl restart middlewared" >&2
|
|
echo " Check the system log for the root cause:" >&2
|
|
echo " journalctl -u middlewared -n 50" >&2
|
|
echo "If the problem is unrelated to this patch, recover with:" >&2
|
|
echo " bash $PATCH_DIR/recover.sh" >&2
|
|
exit 1
|
|
fi
|
|
echo "Done."
|
|
echo ""
|
|
echo "Verify the backend patch loaded correctly:"
|
|
echo " python3 $PATCH_DIR/create_task.py verify"
|
|
echo ""
|
|
echo "Refresh your browser to pick up the UI change."
|
|
echo ""
|
|
echo "To create a TrueCloud Backup task with S3 or B2 credentials:"
|
|
echo " python3 $PATCH_DIR/create_task.py --help"
|