#!/usr/bin/env bash set -Eeuo pipefail umask 022 # STEP028 - SERVER ATTESO: 215.6 / ax-accessi # # Target esclusivo: # /var/www/html/presenze.distribuite # # Elimina esclusivamente: # components/templates/custom_templates/tmpwip # # Motivo: # - 0 riferimenti esterni rilevati; # - circa 26 MiB; # - 2018 file duplicati rispetto al modulo canonico ax_mensa. # # Preserva e verifica: # components/templates/custom_templates/ax_mensa # libs/stimulsoft_legacy # bower_components e node_modules condivisi # # Nessun altro portale custom viene toccato. # Nessun backup: presenze.distribuite è ambiente test sacrificabile. START_DIR="$PWD" STAMP="$(date '+%Y%m%d_%H%M%S')" BASE="STEP028_2156_DISTRIBUITE_REMOVE_TMPWIP_DUPLICATE_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=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}" TMPWIP_DIR="${TARGET_DIR}/components/templates/custom_templates/tmpwip" CANONICAL_DIR="${TARGET_DIR}/components/templates/custom_templates/ax_mensa" LEGACY_STIMULSOFT="${TARGET_DIR}/libs/stimulsoft_legacy" 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}, rimozione=${REMOVED}, 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 "RIMOZIONE ESCLUSIVA: $TMPWIP_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 "Rimozione esclusiva: $TMPWIP_DIR" echo "Modulo canonico preservato: $CANONICAL_DIR" 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 find du numfmt basename dirname stat sha256sum 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" [[ "$TMPWIP_DIR" == "/var/www/html/presenze.distribuite/components/templates/custom_templates/tmpwip" ]] \ || fail "percorso tmpwip inatteso: $TMPWIP_DIR" [[ "$CANONICAL_DIR" == "/var/www/html/presenze.distribuite/components/templates/custom_templates/ax_mensa" ]] \ || fail "percorso canonico inatteso: $CANONICAL_DIR" [[ -d "$TARGET_DIR" ]] || fail "target assente: $TARGET_DIR" [[ ! -L "$TARGET_DIR" ]] || fail "target root non deve essere symlink" [[ -d "$TMPWIP_DIR" ]] || fail "tmpwip assente: $TMPWIP_DIR" [[ ! -L "$TMPWIP_DIR" ]] || fail "tmpwip non deve essere symlink" [[ -d "$CANONICAL_DIR" ]] || fail "modulo canonico ax_mensa assente" [[ ! -L "$CANONICAL_DIR" ]] || fail "ax_mensa canonico non deve essere symlink" [[ -d "$LEGACY_STIMULSOFT" ]] || fail "stimulsoft_legacy assente" [[ -L "${TARGET_DIR}/bower_components" ]] || fail "bower_components non è symlink" [[ -L "${TARGET_DIR}/node_modules" ]] || fail "node_modules non è symlink" [[ "$FAILURES" -eq 0 ]] || exit 22 manifest_hash() { local root="$1" ( cd "$root" find . -xdev -type f -print0 \ | sort -z \ | xargs -0 -r sha256sum ) | sha256sum | awk '{print $1}' } log "[1/6] Precheck dimensioni e contenuti" TMPWIP_BYTES="$(du -sbx -- "$TMPWIP_DIR" | awk '{print $1}')" TMPWIP_HUMAN="$(numfmt --to=iec-i --suffix=B "$TMPWIP_BYTES" 2>/dev/null || printf '%sB' "$TMPWIP_BYTES")" TMPWIP_FILES="$(find "$TMPWIP_DIR" -xdev -type f | wc -l | tr -d ' ')" TMPWIP_DIRS="$(find "$TMPWIP_DIR" -xdev -type d | wc -l | tr -d ' ')" CANONICAL_BYTES_BEFORE="$(du -sbx -- "$CANONICAL_DIR" | awk '{print $1}')" CANONICAL_FILES_BEFORE="$(find "$CANONICAL_DIR" -xdev -type f | wc -l | tr -d ' ')" CANONICAL_DIRS_BEFORE="$(find "$CANONICAL_DIR" -xdev -type d | wc -l | tr -d ' ')" CANONICAL_HASH_BEFORE="$(manifest_hash "$CANONICAL_DIR")" TARGET_BYTES_BEFORE="$(du -sbx -- "$TARGET_DIR" | awk '{print $1}')" { printf 'voce\tvalore\n' printf 'tmpwip_byte\t%s\n' "$TMPWIP_BYTES" printf 'tmpwip_spazio\t%s\n' "$TMPWIP_HUMAN" printf 'tmpwip_file\t%s\n' "$TMPWIP_FILES" printf 'tmpwip_directory\t%s\n' "$TMPWIP_DIRS" printf 'canonical_byte_before\t%s\n' "$CANONICAL_BYTES_BEFORE" printf 'canonical_file_before\t%s\n' "$CANONICAL_FILES_BEFORE" printf 'canonical_directory_before\t%s\n' "$CANONICAL_DIRS_BEFORE" printf 'canonical_manifest_hash_before\t%s\n' "$CANONICAL_HASH_BEFORE" printf 'target_byte_before\t%s\n' "$TARGET_BYTES_BEFORE" } >"${WORKDIR}/01_PRECHECKS.tsv" log "[2/6] Verifica assenza riferimenti esterni a tmpwip" CODE_FILES="${WORKDIR}/02_CODE_FILES.list" REFERENCES="${WORKDIR}/03_EXTERNAL_REFERENCES.tsv" find "$TARGET_DIR" \ -xdev \ \( \ -path "$TMPWIP_DIR" \ -o -path "${TARGET_DIR}/bower_components" \ -o -path "${TARGET_DIR}/node_modules" \ -o -path "$LEGACY_STIMULSOFT" \ \) -prune \ -o -type f \ \( \ -name '*.php' \ -o -name '*.js' \ -o -name '*.json' \ -o -name '*.html' \ -o -name '*.htm' \ -o -name '*.css' \ -o -name '*.xml' \ -o -name '*.ini' \ -o -name '*.conf' \ -o -name '*.tpl' \ -o -name '*.mrt' \ -o -name '*.txt' \ \) \ -print0 >"$CODE_FILES" printf 'file\triga\ttesto\n' >"$REFERENCES" while IFS= read -r -d '' file; do while IFS= read -r match; do [[ -n "$match" ]] || continue lineno="${match%%:*}" content="${match#*:}" clean="$(printf '%s' "$content" | tr '\t\r\n' ' ' | cut -c1-500)" printf '%s\t%s\t%s\n' "$file" "$lineno" "$clean" >>"$REFERENCES" done < <(grep -nI -E 'tmpwip' "$file" 2>/dev/null || true) done <"$CODE_FILES" REFERENCE_COUNT=$(( $(wc -l <"$REFERENCES") - 1 )) [[ "$REFERENCE_COUNT" -eq 0 ]] \ || fail "trovati ${REFERENCE_COUNT} riferimenti esterni a tmpwip" [[ "$FAILURES" -eq 0 ]] || exit 23 log "[3/6] Rimozione esclusiva tmpwip" rm -rf --one-file-system -- "$TMPWIP_DIR" REMOVED=1 log "[4/6] Verifica rimozione" [[ ! -e "$TMPWIP_DIR" && ! -L "$TMPWIP_DIR" ]] \ || fail "tmpwip ancora presente dopo la rimozione" log "[5/6] Verifica integrità modulo canonico e strutture condivise" CANONICAL_BYTES_AFTER="$(du -sbx -- "$CANONICAL_DIR" | awk '{print $1}')" CANONICAL_FILES_AFTER="$(find "$CANONICAL_DIR" -xdev -type f | wc -l | tr -d ' ')" CANONICAL_DIRS_AFTER="$(find "$CANONICAL_DIR" -xdev -type d | wc -l | tr -d ' ')" CANONICAL_HASH_AFTER="$(manifest_hash "$CANONICAL_DIR")" TARGET_BYTES_AFTER="$(du -sbx -- "$TARGET_DIR" | awk '{print $1}')" FREED_BYTES=$((TARGET_BYTES_BEFORE - TARGET_BYTES_AFTER)) FREED_HUMAN="$(numfmt --to=iec-i --suffix=B "$FREED_BYTES" 2>/dev/null || printf '%sB' "$FREED_BYTES")" [[ "$CANONICAL_BYTES_AFTER" == "$CANONICAL_BYTES_BEFORE" ]] \ || fail "dimensione ax_mensa canonico variata" [[ "$CANONICAL_FILES_AFTER" == "$CANONICAL_FILES_BEFORE" ]] \ || fail "numero file ax_mensa canonico variato" [[ "$CANONICAL_DIRS_AFTER" == "$CANONICAL_DIRS_BEFORE" ]] \ || fail "numero directory ax_mensa canonico variato" [[ "$CANONICAL_HASH_AFTER" == "$CANONICAL_HASH_BEFORE" ]] \ || fail "contenuto ax_mensa canonico variato" [[ -d "$LEGACY_STIMULSOFT" ]] || fail "stimulsoft_legacy non più presente" [[ -f "${LEGACY_STIMULSOFT}/viewer.php" ]] || fail "viewer.php legacy assente" [[ -f "${LEGACY_STIMULSOFT}/designer.php" ]] || fail "designer.php legacy assente" [[ -L "${TARGET_DIR}/bower_components" ]] || fail "bower_components symlink perso" [[ -L "${TARGET_DIR}/node_modules" ]] || fail "node_modules symlink perso" [[ "$FAILURES" -eq 0 ]] || exit 24 { printf 'controllo\tatteso\trilevato\n' printf 'tmpwip_residuo\tASSENTE\t%s\n' "$([[ -e "$TMPWIP_DIR" || -L "$TMPWIP_DIR" ]] && echo PRESENTE || echo ASSENTE)" printf 'riferimenti_esterni_tmpwip\t0\t%s\n' "$REFERENCE_COUNT" printf 'canonical_byte\t%s\t%s\n' "$CANONICAL_BYTES_BEFORE" "$CANONICAL_BYTES_AFTER" printf 'canonical_file\t%s\t%s\n' "$CANONICAL_FILES_BEFORE" "$CANONICAL_FILES_AFTER" printf 'canonical_directory\t%s\t%s\n' "$CANONICAL_DIRS_BEFORE" "$CANONICAL_DIRS_AFTER" printf 'canonical_manifest_hash\t%s\t%s\n' "$CANONICAL_HASH_BEFORE" "$CANONICAL_HASH_AFTER" printf 'target_byte_before\t%s\t%s\n' "$TARGET_BYTES_BEFORE" "$TARGET_BYTES_BEFORE" printf 'target_byte_after\t-\t%s\n' "$TARGET_BYTES_AFTER" printf 'spazio_liberato_byte\t-\t%s\n' "$FREED_BYTES" printf 'spazio_liberato\t-\t%s\n' "$FREED_HUMAN" } >"${WORKDIR}/04_POSTCHECKS.tsv" log "[6/6] Esito" { echo "PATCH COMPLETATA" echo "Server: 215.6 / ax-accessi" echo "Target esclusivo: $TARGET_DIR" echo "Directory rimossa: components/templates/custom_templates/tmpwip" echo "File rimossi: $TMPWIP_FILES" echo "Directory rimosse: $TMPWIP_DIRS" echo "Spazio tmpwip prima: $TMPWIP_HUMAN" echo "Spazio realmente liberato: $FREED_HUMAN" echo "Riferimenti esterni tmpwip: $REFERENCE_COUNT" echo "ax_mensa canonico preservato: SI" echo "stimulsoft_legacy preservato: SI" echo "bower_components/node_modules condivisi preservati: SI" echo "Altri portali custom toccati: NO" } >"${WORKDIR}/99_SUMMARY.txt" report "Rimosso esclusivamente tmpwip da presenze.distribuite." report "Spazio liberato: $FREED_HUMAN." report "ax_mensa canonico e librerie condivise preservati." report "Altri portali custom non toccati." log "PATCH COMPLETATA E VERIFICATA"