#!/usr/bin/env bash
set -Eeuo pipefail
set +x
umask 077

readonly LABEL=REDIS02_Q132_OFFLINE_SEMANAGE_INSTALL_AND_RESUME
readonly EXPECTED_HOST=sqjcredis02
readonly EXPECTED_IP=10.2.203.113
readonly BUNDLE=/root/q132-semanage-offline-rpms.tar.gz
readonly BUNDLE_SHA256=24aa7c3564a37aa3bfc85c05040720d310ba89c390dd794fb0162d997840b98f
readonly MANIFEST_SHA256=1a7fb47a34d1c91b8fc01720e965955a7bf163d94de361614be3ff863ec7aee7
readonly KEY_SHA256=006e79d37c10e74c24df6d07c4efc4176515cec009daa5ed493b06f5b6ef39c1
readonly KEY_FINGERPRINT=8AA16BF9F2CA5244010DCA963B477C60B675600B
readonly RESUME=/root/redis02-q132-selinux-acl-repair-activate-verify.sh
readonly RESUME_SHA256=5ebb623df5246c868960ac962527a7b2f015a1cf1ae04707a208acade60599af
readonly CACHE_DIAG_AUDIT=/var/backups/zhct-q132-semanage-cache-diagnosis/q132-semanage-cache-diagnosis-20260806T014301Z/operator.log
readonly SCRIPT_PATH="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)/$(basename -- "${BASH_SOURCE[0]}")"
RUN_ID="q132-offline-semanage-resume-$(date -u +%Y%m%dT%H%M%SZ)"
AUDIT_DIR="/var/backups/zhct-q132-offline-semanage-resume/${RUN_ID}"
AUDIT_LOG="${AUDIT_DIR}/operator.log"
WORK=''
DNF_HISTORY_BEFORE=''
package_install_started=0
success=0
static_mode=0

finish() {
    local rc=$?
    set +e
    if [[ "$static_mode" -eq 1 ]]; then
        printf '%s\n' \
            'Q132_OFFLINE_SEMANAGE_STATIC_FINISH=PASS_NO_REMOTE_MUTATION' \
            "END|${LABEL}|RC=${rc}|AUDIT_LOG=NOT_CREATED_STATIC_VALIDATE"
        exit "$rc"
    fi
    if [[ -n "$WORK" && -d "$WORK" && "$WORK" == /var/tmp/q132-offline-semanage.* ]]; then
        rm -rf -- "$WORK"
    fi
    if [[ "$rc" -eq 0 && "$success" -eq 1 ]]; then
        printf '%s\n' 'Q132_OFFLINE_SEMANAGE_INSTALL_AND_RESUME=PASS_REDIS02_LOCAL_ROLE_ACTIVATED'
    else
        if [[ "$package_install_started" -eq 0 ]]; then
            printf '%s\n' 'Q132_OFFLINE_SEMANAGE_ROLLBACK=NOT_REQUIRED_ZERO_PACKAGE_OR_ROLE_MUTATION'
        else
            printf '%s\n' 'Q132_OFFLINE_SEMANAGE_SUPPORT_PACKAGES=RETAINED_FOR_AUDIT_AND_SAFE_RETRY'
        fi
        printf '%s\n' 'Q132_OFFLINE_SEMANAGE_INSTALL_AND_RESUME=FAIL_STOP'
    fi
    printf '%s\n' \
        'SECRET_VALUES=NOT_READ_BY_WRAPPER_NOT_OUTPUT_NOT_HASHED' \
        'SENTINEL_HA=NOT_CONFIGURED' \
        'ORCHESTRATOR_RAFT=NOT_CONFIGURED' \
        'VIP=DISABLED' \
        'CROSS_HOST_HA=NOT_ACCEPTED' \
        "END|${LABEL}|RC=${rc}|AUDIT_LOG=${AUDIT_LOG}"
    exit "$rc"
}
trap finish EXIT

static_validate() {
    bash -n "$SCRIPT_PATH"
    grep -Fq -- "--disablerepo='*'" "$SCRIPT_PATH"
    grep -Fq -- '--assumeno install "${rpms[@]}"' "$SCRIPT_PATH"
    grep -Fq -- '-y install "${rpms[@]}"' "$SCRIPT_PATH"
    grep -Fq -- '"$RESUME"' "$SCRIPT_PATH"
    if grep -En 'curl|wget|dnf[[:space:]].*--refresh|systemctl[[:space:]]+(start|restart|enable).*\b(sentinel5|sentinel7|orchestrator)\.service|ip[[:space:]]+addr[[:space:]]+add' "$SCRIPT_PATH" |
        grep -v 'grep -En'; then
        return 1
    fi
    if grep -En 'cat[[:space:]]+[^|]*(redis5\.password|redis7\.password)|sha256sum[^|]*(redis5\.password|redis7\.password)' "$SCRIPT_PATH" |
        grep -v 'grep -En'; then
        return 1
    fi
    printf '%s\n' \
        'Q132_OFFLINE_SEMANAGE_RESUME_STATIC_VALIDATE=PASS' \
        'NETWORK_REPOSITORIES=DISABLED' \
        'RPM_SIGNATURE_GATE=REQUIRED' \
        'DNF_PLAN=INSTALL_ONLY' \
        'AUXILIARY_UNITS=DISABLED_INACTIVE'
}

printf 'BEGIN|%s|%s\n' "$LABEL" "$(date '+%Y-%m-%dT%H:%M:%S%z')"
if [[ "${1:-}" == --static-validate ]]; then
    static_mode=1
    static_validate
    exit 0
fi
[[ $# -eq 0 ]]
[[ $(id -u) -eq 0 ]]
actual_host=$(hostname -s)
[[ "$actual_host" == "$EXPECTED_HOST" ]]
ip -o -4 addr show scope global | awk '{split($4,a,"/"); print a[1]}' | grep -Fxq "$EXPECTED_IP"
printf 'Q132_OFFLINE_RESUME_TARGET_IDENTITY=PASS|host=%s|ip=%s\n' "$actual_host" "$EXPECTED_IP"

for command_name in tar gzip sha256sum rpm dnf gpg systemctl ss getfacl stat install tee mktemp; do
    command -v "$command_name" >/dev/null 2>&1 || {
        printf 'ERROR: required command is missing: %s\n' "$command_name" >&2
        exit 1
    }
done
[[ -f "$BUNDLE" && ! -L "$BUNDLE" && $(stat -c '%U:%G' "$BUNDLE") == root:root ]]
printf '%s  %s\n' "$BUNDLE_SHA256" "$BUNDLE" | sha256sum -c -
[[ -f "$RESUME" && ! -L "$RESUME" && $(stat -c '%U:%G:%a' "$RESUME") == root:root:750 ]]
printf '%s  %s\n' "$RESUME_SHA256" "$RESUME" | sha256sum -c -
[[ -f "$CACHE_DIAG_AUDIT" && ! -L "$CACHE_DIAG_AUDIT" ]]
grep -Fxq 'CACHED_SUPPORT_RPM_COUNT=0' "$CACHE_DIAG_AUDIT"
grep -Fxq 'CACHE_ONLY_REPOQUERY_RC=0' "$CACHE_DIAG_AUDIT"
grep -Fxq 'CACHE_ONLY_INSTALL_PLAN=PASS_RESOLVED_INSTALL_ONLY' "$CACHE_DIAG_AUDIT"
grep -Fxq 'Q132_SEMANAGE_CACHE_DIAGNOSIS=PASS_READ_ONLY' "$CACHE_DIAG_AUDIT"
grep -Fxq 'PACKAGE_INSTALL=NOT_PERFORMED' "$CACHE_DIAG_AUDIT"
grep -Fxq 'ROLE_ACTIVATION=NOT_PERFORMED' "$CACHE_DIAG_AUDIT"

! rpm -q policycoreutils-python-utils >/dev/null 2>&1
! command -v semanage >/dev/null 2>&1
for unit in redis5.service redis7.service sentinel5.service sentinel7.service orchestrator.service; do
    [[ $(systemctl is-enabled "$unit" 2>/dev/null || true) == disabled ]]
    [[ $(systemctl is-active "$unit" 2>/dev/null || true) == inactive ]]
done
! ss -lntupH | grep -E ':(6379|6387|26379|26387|3000|10008)([[:space:]]|$)' >/dev/null
[[ $(stat -c '%U:%G:%a' /etc) == root:root:750 ]]
[[ $(stat -c '%U:%G:%a' /etc/redis) == root:root:750 ]]
! getfacl -cp /etc | grep -q '^user:redis:'
printf 'Q132_OFFLINE_RESUME_PREWRITE_GATE=PASS\n'

install -d -o root -g root -m 0700 "$AUDIT_DIR"
exec > >(tee -a "$AUDIT_LOG") 2>&1
printf 'AUDIT_BEGIN|%s|%s\n' "$LABEL" "$(date '+%Y-%m-%dT%H:%M:%S%z')"
printf 'RUN_ID=%s\n' "$RUN_ID"

if tar -tzf "$BUNDLE" | grep -Eq '(^/|(^|/)\.\.(/|$))'; then
    printf '%s\n' 'ERROR: unsafe archive member' >&2
    exit 1
fi
WORK=$(mktemp -d /var/tmp/q132-offline-semanage.XXXXXX)
tar --no-same-owner -xzf "$BUNDLE" -C "$WORK"
ROOT="$WORK/q132-semanage-offline-rpms"
[[ -d "$ROOT" && ! -L "$ROOT" ]]
[[ $(find "$ROOT" -mindepth 1 -type l -print -quit | wc -l) -eq 0 ]]
[[ $(find "$ROOT" -mindepth 1 -print | wc -l) -eq 12 ]]
[[ $(find "$ROOT/rpms" -maxdepth 1 -type f -name '*.rpm' | wc -l) -eq 8 ]]
printf '%s  %s\n' "$MANIFEST_SHA256" "$ROOT/SHA256SUMS" | sha256sum -c -
printf '%s  %s\n' "$KEY_SHA256" "$ROOT/RPM-GPG-KEY-openEuler" | sha256sum -c -
(cd "$ROOT" && sha256sum -c SHA256SUMS)
fingerprint=$(gpg --batch --show-keys --with-colons "$ROOT/RPM-GPG-KEY-openEuler" 2>/dev/null |
    awk -F: '$1 == "fpr" {print $10; exit}')
[[ "$fingerprint" == "$KEY_FINGERPRINT" ]]
printf 'Q132_OFFLINE_KEY_GATE=PASS|fingerprint=%s\n' "$fingerprint"

mapfile -d '' rpms < <(find "$ROOT/rpms" -maxdepth 1 -type f -name '*.rpm' -print0 | sort -z)
[[ ${#rpms[@]} -eq 8 ]]
expected_nevra=$(printf '%s\n' \
    'checkpolicy-0:3.5-1.oe2403sp1.x86_64' \
    'policycoreutils-python-utils-0:3.5-3.oe2403sp1.noarch' \
    'python3-IPy-0:1.01-2.oe2403sp1.noarch' \
    'python3-audit-1:3.1.2-7.oe2403sp1.x86_64' \
    'python3-libselinux-0:3.5-3.oe2403sp1.x86_64' \
    'python3-libsemanage-0:3.5-1.oe2403sp1.x86_64' \
    'python3-policycoreutils-0:3.5-3.oe2403sp1.noarch' \
    'python3-setools-0:4.4.3-1.oe2403sp1.x86_64')
actual_nevra=$(rpm -qp --qf '%{NAME}-%{EPOCHNUM}:%{VERSION}-%{RELEASE}.%{ARCH}\n' "${rpms[@]}" 2>/dev/null | sort)
[[ "$actual_nevra" == "$expected_nevra" ]]
printf '%s\n' "$actual_nevra"
printf 'Q132_OFFLINE_NEVRA_GATE=PASS|rpm_count=8\n'

rpmdb=$(mktemp -d /var/tmp/q132-offline-rpmdb.XXXXXX)
rpm --dbpath "$rpmdb" --initdb
rpm --dbpath "$rpmdb" --import "$ROOT/RPM-GPG-KEY-openEuler"
for rpm_file in "${rpms[@]}"; do
    rpm --dbpath "$rpmdb" --define '_pkgverify_level signature' -K "$rpm_file"
done
rm -rf -- "$rpmdb"
printf 'Q132_OFFLINE_RPM_SIGNATURES=PASS|rpm_count=8\n'

plan_file="$AUDIT_DIR/offline-assumeno.log"
set +e
dnf --disablerepo='*' --setopt=strict=True --setopt=install_weak_deps=False \
    --setopt=localpkg_gpgcheck=False --assumeno install "${rpms[@]}" >"$plan_file" 2>&1
plan_rc=$?
set -e
cat "$plan_file"
[[ "$plan_rc" -eq 1 ]]
grep -Fq 'Install  8 Packages' "$plan_file"
! grep -Eq 'Removing:|Upgrading:|Downgrading:' "$plan_file"
printf 'Q132_OFFLINE_DNF_PLAN=PASS_INSTALL_ONLY_8\n'

DNF_HISTORY_BEFORE=$(dnf history list 2>/dev/null | awk 'NR > 2 && $1 ~ /^[0-9]+$/ {print $1; exit}')
package_install_started=1
dnf --disablerepo='*' --setopt=strict=True --setopt=install_weak_deps=False \
    --setopt=localpkg_gpgcheck=False -y install "${rpms[@]}"
command -v semanage >/dev/null 2>&1
rpm -q policycoreutils-python-utils checkpolicy python3-IPy python3-audit \
    python3-libselinux python3-libsemanage python3-policycoreutils python3-setools
DNF_HISTORY_AFTER=$(dnf history list 2>/dev/null | awk 'NR > 2 && $1 ~ /^[0-9]+$/ {print $1; exit}')
[[ -n "$DNF_HISTORY_AFTER" && "$DNF_HISTORY_AFTER" != "$DNF_HISTORY_BEFORE" ]]
printf 'Q132_OFFLINE_SEMANAGE_INSTALL=PASS|dnf_transaction=%s\n' "$DNF_HISTORY_AFTER"

"$RESUME"
for unit in redis5.service redis7.service; do
    [[ $(systemctl is-enabled "$unit") == enabled ]]
    [[ $(systemctl is-active "$unit") == active ]]
done
for unit in sentinel5.service sentinel7.service orchestrator.service; do
    [[ $(systemctl is-enabled "$unit" 2>/dev/null || true) == disabled ]]
    [[ $(systemctl is-active "$unit" 2>/dev/null || true) == inactive ]]
done
! ip -o -4 addr show | grep -Fq '10.2.203.117/'
success=1
printf '%s\n' \
    'Q132_OFFLINE_SEMANAGE_RESUME_VERIFY=PASS_REDIS02_LOCAL_ONLY' \
    'SENTINEL5=DISABLED_INACTIVE' \
    'SENTINEL7=DISABLED_INACTIVE' \
    'ORCHESTRATOR=DISABLED_INACTIVE' \
    'VIP=DISABLED'
