#!/usr/bin/env bash
# =====================================================================
# LogShip template cleanup — step 0: defuse a fresh production clone
# ---------------------------------------------------------------------
# Run as root ON THE CLONE, ideally while its NIC is still link_down
# (via `qm guest exec`). Idempotent. NEVER run on production — guarded.
#
# What it does:
# 1. Hard guard: refuses to run if this host is production
# 2. Backs up + wipes the root crontab (DHL crawler, customer reports,
# accounting jobs must never fire from a clone)
# 3. Disables postfix (no outbound mail)
# 4. Clears frontend runtime data (SQLite DBs + data/ subdirs: contract
# signing, amazon-ads, bank imports, call transcripts, mobile releases,
# per-user caches, DB backups)
# 5. Removes the data.logship.de line from the cloud-init hosts template
# 6. Rebinds Elasticsearch to 127.0.0.1 only (drops the prod-IP bind)
# 7. Points accounting scripts' DB config at 127.0.0.1
# 8. Wipes production files outside the DBs (/root/storage PDFs, /root
# leftovers, stale deploy copies) — several GB of customer documents
# 9. Drops the Check_MK agent registration (prod UUID/cert); agent stays
# The .env neutralization is done separately (03-neutralize-env.sh),
# because it needs the key list reviewed per clone generation.
# =====================================================================
set -euo pipefail
# pm2 lives under nvm — not on PATH in non-login shells (ssh cmd, qm guest exec)
for d in /root/.nvm/versions/node/*/bin; do [ -d "$d" ] && PATH="$PATH:$d"; done; export PATH
# --- 1. production guard --------------------------------------------------
if hostname | grep -q '^logship-production$'; then
echo "FATAL: hostname is logship-production — refusing to run." >&2
exit 1
fi
if ip -4 addr show 2>/dev/null | grep -q '192\.168\.12\.72/'; then
echo "FATAL: this host holds 192.168.12.72 (production IP) — refusing to run." >&2
exit 1
fi
echo "Guard OK: $(hostname) / $(hostname -I 2>/dev/null || true)"
# --- 2. crontab -----------------------------------------------------------
if crontab -l >/dev/null 2>&1; then
if [ ! -f /root/crontab.production.bak ]; then
crontab -l > /root/crontab.production.bak
echo "root crontab backed up to /root/crontab.production.bak"
fi
crontab -r || true
echo "root crontab removed"
else
echo "root crontab already empty"
fi
# --- 3. postfix -----------------------------------------------------------
systemctl disable --now postfix 2>/dev/null || true
systemctl disable --now 'postfix@-' 2>/dev/null || true
echo "postfix disabled"
# --- 4. frontend runtime data ---------------------------------------------
# data/*.db push subscriptions, FCM tokens, chat, contract signing,
# legal docs, amazon-ads inbox, email verification
# data/
/ contract-signing (signed PDFs), amazon-ads (uploads),
# bank-file-import (CAMT files), call-transcripts,
# mobile-releases (APK history + manifests)
# data/*.json eBay signing keys
# logship_*.db per-user SQLite caches in the app root (sqliteHelper.ts)
# -db-backups/ amazon-ads DB snapshots
APP=/opt/erp-nuxt-frontend
if [ -d "$APP/data" ]; then
pm2 stop erpfrontend >/dev/null 2>&1 || true
find "$APP/data" -mindepth 1 ! -name '.gitkeep' -delete 2>/dev/null || true
rm -f "$APP"/logship_*.db "$APP"/*.sqlite 2>/dev/null || true
rm -rf /opt/erp-nuxt-frontend-db-backups/* 2>/dev/null || true
echo "frontend runtime data cleared: $(find "$APP/data" -mindepth 1 | wc -l) entries left in data/ (pm2 erpfrontend left stopped; restart later)"
fi
# --- 5. cloud-init hosts template ----------------------------------------
TPL=/etc/cloud/templates/hosts.debian.tmpl
if [ -f "$TPL" ] && grep -q 'data\.logship\.de' "$TPL"; then
sed -i.bak '/data\.logship\.de/d' "$TPL"
echo "removed data.logship.de from $TPL (takes effect next boot)"
fi
sed -i '/data\.logship\.de/d' /etc/hosts || true
# --- 6. Elasticsearch bind ------------------------------------------------
COMPOSE=/root/idempiere-elastic/docker-compose.yml
if [ -f "$COMPOSE" ] && grep -q '192\.168\.12\.72:9200' "$COMPOSE"; then
sed -i.bak '/192\.168\.12\.72:9200/d' "$COMPOSE"
echo "removed prod-IP ES bind from $COMPOSE (recreate with: cd /root/idempiere-elastic && docker compose up -d)"
fi
# --- 7. accounting scripts DB config -------------------------------------
DBCFG=/opt/logship-scripts/accounting/db_config.json
if [ -f "$DBCFG" ] && grep -q '192\.168\.12\.72' "$DBCFG"; then
sed -i.bak 's/192\.168\.12\.72/127.0.0.1/g' "$DBCFG"
echo "pointed $DBCFG at 127.0.0.1"
fi
# --- 8. production files outside the databases ----------------------------
# /root/storage: label/shipment/invoice/picklist PDFs written by server/api/print/*
# (keep the directory skeleton — the routes mkdir lazily but some assume it).
if [ -d /root/storage ]; then
before=$(du -sh /root/storage 2>/dev/null | cut -f1)
find /root/storage -type f -delete
echo "/root/storage files wiped (was $before)"
fi
# ad-hoc leftovers of production debugging / one-off jobs
rm -rf /root/backup-dhl-invoices /root/sent /root/stuck_parcels_census_*.csv \
/root/SHIPMENT_LABEL.pdf /root/Schweres_Paket_Label_*.pdf /root/resubmit_*.json \
/root/crontab_backup_*.txt /root/felix-cache 2>/dev/null || true
# stale deploy copies (previous builds carry the prod .env!). Keep the live
# release if /opt/erp-nuxt-frontend is a symlink into -releases.
rm -rf /opt/erp-nuxt-frontend-temp /opt/erp-nuxt-frontend-rollback/* 2>/dev/null || true
if [ -d /opt/erp-nuxt-frontend-releases ]; then
live=""
if [ -L /opt/erp-nuxt-frontend ]; then live=$(basename "$(readlink -f /opt/erp-nuxt-frontend)"); fi
for d in /opt/erp-nuxt-frontend-releases/*; do
[ -e "$d" ] || continue
[ -n "$live" ] && [ "$(basename "$d")" = "$live" ] && continue
rm -rf "$d"
done
echo "deploy copies pruned (live release kept: ${live:-none, app dir is not a symlink})"
fi
# --- 9. Check_MK agent registration ---------------------------------------
# The clone carries production's agent UUID + certificate for the monitoring
# site. Drop the registration; the agent + plugins stay installed so a real
# instance can register itself (cmk-agent-ctl register ...).
if command -v cmk-agent-ctl >/dev/null 2>&1; then
cmk-agent-ctl delete-all >/dev/null 2>&1 && echo "Check_MK registration removed" \
|| echo "Check_MK: nothing to deregister"
fi
echo "DEFUSE COMPLETE."