#!/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."