#!/usr/bin/env bash set -Eeuo pipefail umask 022 # STEP024 - SERVER ATTESO: 215.6 / ax-accessi # # Target esclusivo: # /var/www/html/presenze.distribuite # # Elimina ricorsivamente file e directory legacy con basename: # *_old # *.old # ax_dipendentiold # # Ricerca case-insensitive. # Non segue symlink. # Non tocca altri portali custom. # Nessun backup: presenze.distribuite è ambiente test sacrificabile. START_DIR="$PWD" STAMP="$(date '+%Y%m%d_%H%M%S')" BASE="STEP024_2156_DISTRIBUITE_REMOVE_ALL_OLD_VARIANTS_PATCH_TEST_COMMIT_ZIP_ONLY_${STAMP}" WORKDIR="${START_DIR}/.${BASE}_work_$$" OUTZIP="${START_DIR}/${BASE}.zip" LOGFILE="${WORKDIR}/run.log" REPORT="${WORKDIR}/report.txt" PACKAGED=0 FAILURES=0 WARNINGS=0 REMOVED_FILES=0 REMOVED_DIRS=0 REMOVED_LINKS=0 REMOVED_BYTES=0 EXPECTED_HOST="${STEP_EXPECTED_HOST:-ax-accessi}" EXPECTED_IP="${STEP_EXPECTED_IP:-192.168.215.6}" SKIP_SERVER_CHECK="${STEP_SKIP_SERVER_CHECK:-0}" TARGET_DIR="${STEP_TARGET_DIR:-/var/www/html/presenze.distribuite}" mkdir -p "$WORKDIR" : >"$LOGFILE" : >"$REPORT" log() { printf '%s\n' "$*" | tee -a "$LOGFILE"; } report() { printf '%s\n' "$*" >>"$REPORT"; } fail() { FAILURES=$((FAILURES + 1)); log "ERRORE: $*"; report "ERRORE: $*"; } warn() { WARNINGS=$((WARNINGS + 1)); log "ATTENZIONE: $*"; report "ATTENZIONE: $*"; } package_results() { local rc="${1:-0}" local zip_rc=0 [[ "$PACKAGED" -eq 1 ]] && return 0 PACKAGED=1 report "" report "Esito finale: errori=${FAILURES}, avvisi=${WARNINGS}, exit_code=${rc}" rm -f -- "$OUTZIP" if ! command -v zip >/dev/null 2>&1; then rm -rf -- "$WORKDIR" printf '%s\n' "ERRORE: comando zip non disponibile" >&2 return 127 fi (cd "$WORKDIR" && zip -qr "$OUTZIP" .) || zip_rc=$? if [[ "$zip_rc" -eq 0 ]]; then zip -T "$OUTZIP" >>"$LOGFILE" 2>&1 || zip_rc=$? fi rm -rf -- "$WORKDIR" if [[ "$zip_rc" -ne 0 ]]; then rm -f -- "$OUTZIP" printf '%s\n' "ERRORE: creazione/verifica ZIP fallita (rc=${zip_rc})" >&2 return "$zip_rc" fi printf '%s\n' "ZIP CREATO E VERIFICATO: $OUTZIP" } on_exit() { local rc=$? trap - EXIT INT TERM HUP package_results "$rc" || rc=$? exit "$rc" } trap on_exit EXIT trap 'exit 130' INT trap 'exit 143' TERM HUP log "$BASE" log "SERVER ATTESO: 215.6 / ax-accessi" log "TARGET ESCLUSIVO: $TARGET_DIR" log "ALTRI PORTALI CUSTOM: NON TOCCATI" log "MODALITA': PATCH + TEST + COMMIT" log "Avvio: $(date --iso-8601=seconds)" ACTUAL_HOST="$(hostname -s 2>/dev/null || hostname)" ACTUAL_IPS="$(hostname -I 2>/dev/null | xargs || true)" { echo "STEP: $BASE" echo "Server atteso: 215.6 / ax-accessi" echo "Target esclusivo: $TARGET_DIR" echo "Pattern rimossi: *_old, *.old, ax_dipendentiold" echo "Ricerca case-insensitive: SI" echo "Altri portali custom: NON TOCCATI" echo "Modalita': PATCH + TEST + COMMIT" echo "Data: $(date --iso-8601=seconds)" echo "Hostname: $ACTUAL_HOST" echo "IP: $ACTUAL_IPS" echo } >>"$REPORT" for cmd in grep awk wc sort zip hostname xargs tr find du numfmt basename dirname stat readlink rm; do command -v "$cmd" >/dev/null 2>&1 || fail "comando richiesto non disponibile: $cmd" done [[ "$FAILURES" -eq 0 ]] || exit 20 if [[ "$SKIP_SERVER_CHECK" != "1" ]]; then [[ "$ACTUAL_HOST" == "$EXPECTED_HOST" ]] \ || fail "hostname ${ACTUAL_HOST}; previsto ${EXPECTED_HOST}" if [[ -n "$EXPECTED_IP" ]] && ! grep -qw -- "$EXPECTED_IP" <<<"$ACTUAL_IPS"; then fail "IP ${EXPECTED_IP} non presente tra: ${ACTUAL_IPS}" fi fi [[ "$FAILURES" -eq 0 ]] || exit 21 [[ "$TARGET_DIR" == "/var/www/html/presenze.distribuite" ]] \ || fail "target inatteso: $TARGET_DIR" [[ -d "$TARGET_DIR" ]] || fail "cartella target assente: $TARGET_DIR" [[ ! -L "$TARGET_DIR" ]] || fail "target non deve essere un symlink" [[ "$FAILURES" -eq 0 ]] || exit 22 log "[1/5] Individuazione candidati" CANDIDATES="${WORKDIR}/01_CANDIDATES.tsv" printf 'percorso\ttipo\tbyte\tspazio\n' >"$CANDIDATES" mapfile -d '' ITEMS < <( find "$TARGET_DIR" \ -xdev \ -depth \ -mindepth 1 \ \( -type f -o -type d -o -type l \) \ \( \ -iname '*_old' \ -o -iname '*.old' \ -o -iname 'ax_dipendentiold' \ \) \ -print0 2>>"$LOGFILE" ) CANDIDATE_COUNT="${#ITEMS[@]}" for item in "${ITEMS[@]}"; do [[ "$item" == "${TARGET_DIR}/"* ]] || { fail "candidato fuori target: $item" continue } [[ "$item" != "$TARGET_DIR" ]] || { fail "il target root non può essere rimosso" continue } if [[ -L "$item" ]]; then type="symlink" bytes=0 human="0B" elif [[ -f "$item" ]]; then type="file" bytes="$(stat -c '%s' "$item" 2>/dev/null || printf '0')" human="$(numfmt --to=iec-i --suffix=B "$bytes" 2>/dev/null || printf '%sB' "$bytes")" REMOVED_BYTES=$((REMOVED_BYTES + bytes)) elif [[ -d "$item" ]]; then type="directory" bytes="$(du -sbx -- "$item" 2>/dev/null | awk '{print $1}' || printf '0')" human="$(numfmt --to=iec-i --suffix=B "$bytes" 2>/dev/null || printf '%sB' "$bytes")" REMOVED_BYTES=$((REMOVED_BYTES + bytes)) else fail "tipo inatteso: $item" continue fi printf '%s\t%s\t%s\t%s\n' \ "$item" "$type" "$bytes" "$human" \ >>"$CANDIDATES" done [[ "$FAILURES" -eq 0 ]] || exit 23 REMOVED_HUMAN="$(numfmt --to=iec-i --suffix=B "$REMOVED_BYTES" 2>/dev/null || printf '%sB' "$REMOVED_BYTES")" log "[2/5] Rimozione candidati" for item in "${ITEMS[@]}"; do [[ "$item" == "${TARGET_DIR}/"* ]] || { fail "rimozione fuori target bloccata: $item" continue } if [[ -L "$item" ]]; then rm -f -- "$item" REMOVED_LINKS=$((REMOVED_LINKS + 1)) log "RIMOSSO SYMLINK: $item" elif [[ -f "$item" ]]; then rm -f -- "$item" REMOVED_FILES=$((REMOVED_FILES + 1)) log "RIMOSSO FILE: $item" elif [[ -d "$item" ]]; then rm -rf --one-file-system -- "$item" REMOVED_DIRS=$((REMOVED_DIRS + 1)) log "RIMOSSA DIRECTORY: $item" else log "GIA' ASSENTE: $item" fi done [[ "$FAILURES" -eq 0 ]] || exit 24 log "[3/5] Verifica assenza residui" REMAINING="${WORKDIR}/02_REMAINING.tsv" printf 'percorso\ttipo\n' >"$REMAINING" mapfile -d '' RESIDUALS < <( find "$TARGET_DIR" \ -xdev \ -mindepth 1 \ \( -type f -o -type d -o -type l \) \ \( \ -iname '*_old' \ -o -iname '*.old' \ -o -iname 'ax_dipendentiold' \ \) \ -print0 2>>"$LOGFILE" ) for item in "${RESIDUALS[@]}"; do if [[ -L "$item" ]]; then type="symlink" elif [[ -f "$item" ]]; then type="file" elif [[ -d "$item" ]]; then type="directory" else type="altro" fi printf '%s\t%s\n' "$item" "$type" >>"$REMAINING" done RESIDUAL_COUNT="${#RESIDUALS[@]}" [[ "$RESIDUAL_COUNT" -eq 0 ]] \ || fail "rimangono ${RESIDUAL_COUNT} elementi legacy" [[ "$FAILURES" -eq 0 ]] || exit 25 log "[4/5] Verifica strutture essenziali" ESSENTIALS=( "${TARGET_DIR}/components" "${TARGET_DIR}/libs/stimulsoft_legacy" "${TARGET_DIR}/libs/stimulsoft_legacy/viewer.php" "${TARGET_DIR}/libs/stimulsoft_legacy/designer.php" "${TARGET_DIR}/bower_components" "${TARGET_DIR}/node_modules" ) printf 'percorso\tesito\n' >"${WORKDIR}/03_ESSENTIALS.tsv" for path in "${ESSENTIALS[@]}"; do if [[ -e "$path" || -L "$path" ]]; then printf '%s\tOK\n' "$path" >>"${WORKDIR}/03_ESSENTIALS.tsv" else printf '%s\tASSENTE\n' "$path" >>"${WORKDIR}/03_ESSENTIALS.tsv" fail "struttura essenziale assente: $path" fi done [[ -L "${TARGET_DIR}/bower_components" ]] \ || fail "bower_components non è più un symlink" [[ -L "${TARGET_DIR}/node_modules" ]] \ || fail "node_modules non è più un symlink" [[ "$FAILURES" -eq 0 ]] || exit 26 log "[5/5] Esito" { printf 'controllo\tvalore\n' printf 'candidati_trovati\t%s\n' "$CANDIDATE_COUNT" printf 'file_rimossi\t%s\n' "$REMOVED_FILES" printf 'directory_rimosse\t%s\n' "$REMOVED_DIRS" printf 'symlink_rimossi\t%s\n' "$REMOVED_LINKS" printf 'residui\t%s\n' "$RESIDUAL_COUNT" printf 'spazio_candidati_byte\t%s\n' "$REMOVED_BYTES" printf 'spazio_candidati\t%s\n' "$REMOVED_HUMAN" } >"${WORKDIR}/04_SUMMARY.tsv" { echo "PATCH COMPLETATA" echo "Server: 215.6 / ax-accessi" echo "Target esclusivo: $TARGET_DIR" echo "Candidati trovati: $CANDIDATE_COUNT" echo "File rimossi: $REMOVED_FILES" echo "Directory rimosse: $REMOVED_DIRS" echo "Symlink rimossi: $REMOVED_LINKS" echo "Residui *_old / *.old / ax_dipendentiold: $RESIDUAL_COUNT" echo "Spazio candidati: $REMOVED_HUMAN" echo "stimulsoft_legacy preservato: SI" echo "bower_components condiviso preservato: SI" echo "node_modules condiviso preservato: SI" echo "Altri portali custom toccati: NO" } >"${WORKDIR}/99_SUMMARY.txt" report "Rimossi tutti gli elementi *_old, *.old e ax_dipendentiold da presenze.distribuite." report "Elementi residui: $RESIDUAL_COUNT." report "Altri portali custom non toccati." log "PATCH COMPLETATA E VERIFICATA"