#!/bin/sh # Caller holds the production deployment lock. Does not restart any service. set -eu REMOTE_DIR="${1:-/opt/caiwuxitong}" SOURCE_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" LEGACY_STUB="$SOURCE_DIR/retired-activation.sh" [ "$(id -u)" -eq 0 ] || { echo 'Release protection must be installed as root' >&2; exit 1; } [ -f "$LEGACY_STUB" ] || { echo 'Missing retired activation stub' >&2; exit 1; } is_immutable() { lsattr -d "$1" 2>/dev/null | awk '{print $1}' | grep -q i; } needs_install=0 for legacy in activate-release.sh activate-incremental-release.sh; do if cmp -s "$LEGACY_STUB" "$REMOTE_DIR/$legacy" && is_immutable "$REMOTE_DIR/$legacy"; then continue fi if is_immutable "$REMOTE_DIR/$legacy"; then echo "Unexpected immutable legacy entry point: $legacy; verify it before changing protection" >&2 exit 1 fi needs_install=1 done [ "$needs_install" -eq 1 ] || exit 0 # Test support on an owned temporary file before touching either entry point. probe="$(mktemp "$REMOTE_DIR/.release-protection.XXXXXX")" cleanup_probe() { chattr -i "$probe" 2>/dev/null || true; rm -f "$probe"; } trap cleanup_probe EXIT chattr +i "$probe" || { echo 'Filesystem cannot protect legacy entry points; no application was changed' >&2; exit 1; } chattr -i "$probe" backup="$REMOTE_DIR/runtime/private/release-protection/$(date -u +%Y%m%dT%H%M%SZ)-$$" umask 077 mkdir -p "$backup" for legacy in activate-release.sh activate-incremental-release.sh; do if cmp -s "$LEGACY_STUB" "$REMOTE_DIR/$legacy" && is_immutable "$REMOTE_DIR/$legacy"; then continue fi [ ! -f "$REMOTE_DIR/$legacy" ] || cp -p "$REMOTE_DIR/$legacy" "$backup/$legacy" install -m 700 "$LEGACY_STUB" "$REMOTE_DIR/.$legacy.next" mv "$REMOTE_DIR/.$legacy.next" "$REMOTE_DIR/$legacy" chattr +i "$REMOTE_DIR/$legacy" cmp -s "$LEGACY_STUB" "$REMOTE_DIR/$legacy" && is_immutable "$REMOTE_DIR/$legacy" done echo 'Legacy activation paths protected; current application and databases were not restarted'