mirror of
git://f0xx.org/android_cast
synced 2026-07-29 05:17:39 +03:00
sync infra
This commit is contained in:
@@ -6,6 +6,18 @@ Scripts for the BE Gitea instance at `https://apps.f0xx.org/app/androidcast_proj
|
||||
`/var/www/localhost/htdocs/apps/app/androidcast_project/android_cast`
|
||||
is **never** modified. Only Gitea-owned paths from `/etc/gitea/app.ini` are backed up or reset.
|
||||
|
||||
## Temp files (/tmp)
|
||||
|
||||
Gitea scripts use `mktemp` work dirs for `git clone --mirror` fallbacks. Each `*.mirror.git` tree is **removed after every repo** (success or failure) and the work dir is removed on script exit.
|
||||
|
||||
Stale dirs (e.g. after `kill -9`) are pruned automatically on the next run (default: older than **60 minutes**). Manual cleanup:
|
||||
|
||||
```bash
|
||||
sudo ./examples/crash_reporter/backend/scripts/gitea/gitea_cleanup_tmp.sh
|
||||
# immediate wipe of all gitea-* temps:
|
||||
GITEA_TMP_MAX_AGE_MIN=0 sudo ./gitea_cleanup_tmp.sh
|
||||
```
|
||||
|
||||
## Prerequisites (Alpine BE)
|
||||
|
||||
- Gitea installed (`apk add gitea`), config at `/etc/gitea/app.ini`
|
||||
|
||||
@@ -30,7 +30,7 @@ GITEA_OWNER="${GITEA_OWNER:-${GITEA_ORG:-AndroidCast}}"
|
||||
GITEA_REPO="${GITEA_REPO:-android_cast}"
|
||||
GITEA_MIRROR_INTERVAL="${GITEA_MIRROR_INTERVAL:-10m}"
|
||||
GITEA_PRIVATE="${GITEA_PRIVATE:-false}"
|
||||
WORK_DIR="${WORK_DIR:-/tmp/gitea-attach-$$}"
|
||||
WORK_DIR="${WORK_DIR:-}"
|
||||
|
||||
# First positional argument = mirror URL (convenience).
|
||||
if [ $# -ge 1 ] && [ -n "$1" ]; then
|
||||
@@ -151,22 +151,25 @@ create_repo_via_api() {
|
||||
[ -n "${GITEA_ADMIN_TOKEN:-}" ] || return 1
|
||||
need_cmd curl
|
||||
_api="$(gitea_api_base)"
|
||||
_http="$(curl -sS -o /tmp/gitea-create-repo.json -w '%{http_code}' \
|
||||
_resp="$(mktemp /tmp/gitea-create-repo-XXXXXX.json)"
|
||||
_http="$(curl -sS -o "$_resp" -w '%{http_code}' \
|
||||
-X POST "$_api/admin/users/$GITEA_OWNER/repos" \
|
||||
-H "Authorization: token $GITEA_ADMIN_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"name\":\"$GITEA_REPO\",\"private\":$GITEA_PRIVATE}")"
|
||||
_rc=1
|
||||
if [ "$_http" = "201" ] || [ "$_http" = "200" ]; then
|
||||
log "repo created via API"
|
||||
return 0
|
||||
fi
|
||||
if [ "$_http" = "409" ]; then
|
||||
_rc=0
|
||||
elif [ "$_http" = "409" ]; then
|
||||
log "repo already exists (API 409)"
|
||||
return 0
|
||||
_rc=0
|
||||
else
|
||||
warn "API create repo HTTP $_http"
|
||||
cat "$_resp" >&2 2>/dev/null || true
|
||||
fi
|
||||
warn "API create repo HTTP $_http"
|
||||
cat /tmp/gitea-create-repo.json >&2 2>/dev/null || true
|
||||
return 1
|
||||
gitea_rm_path "$_resp"
|
||||
return "$_rc"
|
||||
}
|
||||
|
||||
gitea_owner_uid() {
|
||||
@@ -211,24 +214,28 @@ EOF
|
||||
)
|
||||
|
||||
log "API migrate (pull mirror) uid=$_uid via $_api ..."
|
||||
_http="$(curl -sS -o /tmp/gitea-migrate.json -w '%{http_code}' \
|
||||
_resp="$(mktemp /tmp/gitea-migrate-XXXXXX.json)"
|
||||
_http="$(curl -sS -o "$_resp" -w '%{http_code}' \
|
||||
-X POST "$_api/repos/migrate" \
|
||||
-H "Authorization: token $_token" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$_payload")"
|
||||
|
||||
_rc=1
|
||||
if [ "$_http" = "201" ] || [ "$_http" = "200" ]; then
|
||||
log "mirror created via API (HTTP $_http)"
|
||||
cat /tmp/gitea-migrate.json
|
||||
cat "$_resp"
|
||||
printf '\n'
|
||||
return 0
|
||||
_rc=0
|
||||
else
|
||||
if [ "$_http" = "409" ] || [ "$_http" = "422" ]; then
|
||||
warn "migrate rejected HTTP $_http — repo may already exist; use mirror settings or delete repo first"
|
||||
fi
|
||||
warn "API migrate failed HTTP $_http:"
|
||||
cat "$_resp" >&2
|
||||
fi
|
||||
if [ "$_http" = "409" ] || [ "$_http" = "422" ]; then
|
||||
warn "migrate rejected HTTP $_http — repo may already exist; use mirror settings or delete repo first"
|
||||
fi
|
||||
warn "API migrate failed HTTP $_http:"
|
||||
cat /tmp/gitea-migrate.json >&2
|
||||
return 1
|
||||
gitea_rm_path "$_resp"
|
||||
return "$_rc"
|
||||
}
|
||||
|
||||
ensure_gitea_repo_exists() {
|
||||
@@ -237,27 +244,43 @@ ensure_gitea_repo_exists() {
|
||||
|
||||
mirror_via_git() {
|
||||
need_cmd git
|
||||
mkdir -p "$WORK_DIR"
|
||||
gitea_prune_stale_tmp
|
||||
if [ -n "$WORK_DIR" ]; then
|
||||
mkdir -p "$WORK_DIR"
|
||||
else
|
||||
WORK_DIR="$(gitea_make_work_dir gitea-attach)"
|
||||
fi
|
||||
trap 'gitea_rm_path "$WORK_DIR"' EXIT INT HUP TERM
|
||||
|
||||
_mirror="$WORK_DIR/${GITEA_REPO}.mirror.git"
|
||||
_rc=1
|
||||
|
||||
log "git clone --mirror $GITEA_MIRROR_URL"
|
||||
rm -rf "$_mirror"
|
||||
git clone --mirror "$GITEA_MIRROR_URL" "$_mirror"
|
||||
gitea_rm_path "$_mirror"
|
||||
if ! git clone --mirror "$GITEA_MIRROR_URL" "$_mirror"; then
|
||||
gitea_rm_path "$WORK_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ensure_gitea_repo_exists
|
||||
|
||||
_push_base="$(gitea_local_git_url)"
|
||||
_token="$(resolve_push_token)" || die "need credentials: export GITEA_ADMIN_TOKEN=... or run as root with gitea CLI"
|
||||
if _token="$(resolve_push_token)"; then
|
||||
_auth_url="${_push_base#http://}"
|
||||
_push_url="http://${_token}@${_auth_url}"
|
||||
log "git push --mirror -> $_push_base (localhost, no subpath)"
|
||||
if git -C "$_mirror" push --mirror "$_push_url"; then
|
||||
_rc=0
|
||||
log "one-time mirror push complete"
|
||||
fi
|
||||
else
|
||||
die "need credentials: export GITEA_ADMIN_TOKEN=... or run as root with gitea CLI"
|
||||
fi
|
||||
|
||||
_auth_url="${_push_base#http://}"
|
||||
_push_url="http://${_token}@${_auth_url}"
|
||||
|
||||
log "git push --mirror -> $_push_base (localhost, no subpath)"
|
||||
git -C "$_mirror" push --mirror "$_push_url"
|
||||
|
||||
log "one-time mirror push complete"
|
||||
warn "for automatic updates, re-run with API migrate or enable pull mirror in Gitea UI"
|
||||
rm -rf "$WORK_DIR"
|
||||
gitea_rm_path "$WORK_DIR"
|
||||
trap - EXIT INT HUP TERM
|
||||
return "$_rc"
|
||||
}
|
||||
|
||||
enable_mirror_sync_cron_hint() {
|
||||
|
||||
22
examples/crash_reporter/backend/scripts/gitea/gitea_cleanup_tmp.sh
Executable file
22
examples/crash_reporter/backend/scripts/gitea/gitea_cleanup_tmp.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/ash
|
||||
#
|
||||
# Remove stale gitea script temp dirs under /tmp (mirror clones, work dirs, json).
|
||||
# Safe to run anytime; does not touch running jobs younger than GITEA_TMP_MAX_AGE_MIN.
|
||||
#
|
||||
# Usage:
|
||||
# sudo ./gitea_cleanup_tmp.sh
|
||||
# GITEA_TMP_MAX_AGE_MIN=0 sudo ./gitea_cleanup_tmp.sh # aggressive (all ages)
|
||||
#
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=gitea_mirror_lib.sh
|
||||
. "$SCRIPT_DIR/gitea_mirror_lib.sh"
|
||||
|
||||
_before="$(find /tmp -maxdepth 1 \( -name 'gitea-migrate-*' -o -name 'gitea-submodules-*' \
|
||||
-o -name 'gitea-attach-*' -o -name 'gitea-mirror-*' -o -name 'gitea-*.json' \) 2>/dev/null | wc -l | tr -d ' ')"
|
||||
gitea_prune_stale_tmp
|
||||
_after="$(find /tmp -maxdepth 1 \( -name 'gitea-migrate-*' -o -name 'gitea-submodules-*' \
|
||||
-o -name 'gitea-attach-*' -o -name 'gitea-mirror-*' -o -name 'gitea-*.json' \) 2>/dev/null | wc -l | tr -d ' ')"
|
||||
printf '[gitea-cleanup] max_age_min=%s before=%s after=%s\n' \
|
||||
"${GITEA_TMP_MAX_AGE_MIN:-60}" "$_before" "$_after"
|
||||
@@ -36,7 +36,7 @@ GITEA_SKIP_MAIN="${GITEA_SKIP_MAIN:-0}"
|
||||
GITEA_SKIP_SUBMODULES="${GITEA_SKIP_SUBMODULES:-0}"
|
||||
GITEA_SKIP_ORG_SETUP="${GITEA_SKIP_ORG_SETUP:-0}"
|
||||
GITEA_SUBMODULES_CONF="${GITEA_SUBMODULES_CONF:-$SCRIPT_DIR/submodules.defaults.conf}"
|
||||
WORK_DIR="${WORK_DIR:-/tmp/gitea-migrate-$$}"
|
||||
WORK_DIR="${WORK_DIR:-}"
|
||||
|
||||
log() { printf '[gitea-migrate] %s\n' "$*"; }
|
||||
warn() { printf '[gitea-migrate] WARN: %s\n' "$*" >&2; }
|
||||
@@ -257,8 +257,13 @@ if command -v rc-service >/dev/null 2>&1; then
|
||||
rc-service gitea status 2>/dev/null | grep -qi started || rc-service gitea start 2>/dev/null || true
|
||||
fi
|
||||
|
||||
mkdir -p "$WORK_DIR"
|
||||
trap 'rm -rf "$WORK_DIR"' EXIT INT HUP TERM
|
||||
gitea_prune_stale_tmp
|
||||
if [ -n "$WORK_DIR" ]; then
|
||||
mkdir -p "$WORK_DIR"
|
||||
else
|
||||
WORK_DIR="$(gitea_make_work_dir gitea-migrate)"
|
||||
fi
|
||||
trap 'gitea_rm_path "$WORK_DIR"' EXIT INT HUP TERM
|
||||
|
||||
log "ini=$GITEA_APP_INI owner=$GITEA_OWNER ref=$GITEA_REF"
|
||||
|
||||
|
||||
@@ -21,6 +21,27 @@ gitea_api_base() {
|
||||
printf '%s' "${GITEA_LOCAL_API:-http://127.0.0.1:3000/api/v1}"
|
||||
}
|
||||
|
||||
# Remove abandoned gitea-* temp dirs/files (e.g. after kill -9). Default: older than 60 min.
|
||||
gitea_prune_stale_tmp() {
|
||||
_min="${GITEA_TMP_MAX_AGE_MIN:-60}"
|
||||
command -v find >/dev/null 2>&1 || return 0
|
||||
find /tmp -maxdepth 1 -type d \
|
||||
\( -name 'gitea-migrate-*' -o -name 'gitea-submodules-*' \
|
||||
-o -name 'gitea-attach-*' -o -name 'gitea-mirror-*' \) \
|
||||
-mmin "+$_min" -exec rm -rf {} + 2>/dev/null || true
|
||||
find /tmp -maxdepth 1 -type f -name 'gitea-*.json' \
|
||||
-mmin "+$_min" -delete 2>/dev/null || true
|
||||
}
|
||||
|
||||
gitea_make_work_dir() {
|
||||
_prefix="${1:-gitea-work}"
|
||||
mktemp -d "/tmp/${_prefix}-XXXXXX"
|
||||
}
|
||||
|
||||
gitea_rm_path() {
|
||||
rm -rf "$1" 2>/dev/null || true
|
||||
}
|
||||
|
||||
gitea_resolve_push_token() {
|
||||
if [ -n "${GITEA_ADMIN_TOKEN:-}" ]; then
|
||||
printf '%s' "$GITEA_ADMIN_TOKEN"
|
||||
@@ -103,23 +124,27 @@ gitea_migrate_mirror_api() {
|
||||
}
|
||||
EOF
|
||||
)
|
||||
_http="$(curl -sS -o /tmp/gitea-migrate-$$.json -w '%{http_code}' \
|
||||
_resp="$(mktemp /tmp/gitea-migrate-XXXXXX.json)"
|
||||
_http="$(curl -sS -o "$_resp" -w '%{http_code}' \
|
||||
-X POST "$_api/repos/migrate" \
|
||||
-H "Authorization: token $_token" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$_payload")"
|
||||
|
||||
if [ "$_http" = "201" ] || [ "$_http" = "200" ]; then
|
||||
gitea_rm_path "$_resp"
|
||||
return 0
|
||||
fi
|
||||
if [ "$_http" = "409" ] || [ "$_http" = "422" ]; then
|
||||
gitea_rm_path "$_resp"
|
||||
return 2
|
||||
fi
|
||||
if [ -r "/tmp/gitea-migrate-$$.json" ]; then
|
||||
if [ -r "$_resp" ]; then
|
||||
printf '[gitea-mirror] migrate HTTP %s: ' "$_http" >&2
|
||||
head -c 400 "/tmp/gitea-migrate-$$.json" >&2 || true
|
||||
head -c 400 "$_resp" >&2 || true
|
||||
printf '\n' >&2
|
||||
fi
|
||||
gitea_rm_path "$_resp"
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -131,15 +156,25 @@ gitea_mirror_push_git() {
|
||||
|
||||
command -v git >/dev/null 2>&1 || return 1
|
||||
_mirror="$_work_dir/${_repo}.mirror.git"
|
||||
rm -rf "$_mirror"
|
||||
git clone --mirror "$_clone_url" "$_mirror" || return 1
|
||||
_rc=1
|
||||
|
||||
gitea_rm_path "$_mirror"
|
||||
if ! git clone --mirror "$_clone_url" "$_mirror"; then
|
||||
gitea_rm_path "$_mirror"
|
||||
return 1
|
||||
fi
|
||||
|
||||
gitea_create_repo_cli "$_owner" "$_repo" "${GITEA_PRIVATE:-false}" || true
|
||||
_push_base="$(gitea_local_git_url_for "$_owner" "$_repo")"
|
||||
_token="$(gitea_resolve_push_token)" || return 1
|
||||
_auth_url="${_push_base#http://}"
|
||||
git -C "$_mirror" push --mirror "http://${_token}@${_auth_url}" || return 1
|
||||
rm -rf "$_mirror"
|
||||
return 0
|
||||
if _token="$(gitea_resolve_push_token)"; then
|
||||
_auth_url="${_push_base#http://}"
|
||||
if git -C "$_mirror" push --mirror "http://${_token}@${_auth_url}"; then
|
||||
_rc=0
|
||||
fi
|
||||
fi
|
||||
|
||||
gitea_rm_path "$_mirror"
|
||||
return "$_rc"
|
||||
}
|
||||
|
||||
gitea_repo_exists_api() {
|
||||
@@ -193,11 +228,13 @@ gitea_mirror_set_interval_api() {
|
||||
[ -n "$_token" ] || _token="$(gitea_resolve_push_token)" || return 1
|
||||
_api="$(gitea_api_base)"
|
||||
_payload="{\"mirror_interval\":\"$_interval\"}"
|
||||
_http="$(curl -sS -o /tmp/gitea-mirror-interval-$$.json -w '%{http_code}' \
|
||||
_resp="$(mktemp /tmp/gitea-mirror-interval-XXXXXX.json)"
|
||||
_http="$(curl -sS -o "$_resp" -w '%{http_code}' \
|
||||
-X PATCH "$_api/repos/$_owner/$_repo" \
|
||||
-H "Authorization: token $_token" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$_payload")"
|
||||
gitea_rm_path "$_resp"
|
||||
case "$_http" in
|
||||
200|204) return 0 ;;
|
||||
*) return 1 ;;
|
||||
@@ -220,7 +257,13 @@ gitea_mirror_pull_repo() {
|
||||
_repo="$2"
|
||||
_owner="${3:-$GITEA_OWNER}"
|
||||
_interval="${4:-${GITEA_MIRROR_INTERVAL:-10m}}"
|
||||
_work_dir="${5:-/tmp/gitea-mirror-$$}"
|
||||
_local_work=""
|
||||
if [ $# -ge 5 ] && [ -n "$5" ]; then
|
||||
_work_dir="$5"
|
||||
else
|
||||
_local_work="$(gitea_make_work_dir gitea-mirror)"
|
||||
_work_dir="$_local_work"
|
||||
fi
|
||||
|
||||
_rc=0
|
||||
gitea_migrate_mirror_api "$_owner" "$_repo" "$_clone_url" "$_interval" "${GITEA_PRIVATE:-false}" \
|
||||
@@ -237,5 +280,7 @@ gitea_mirror_pull_repo() {
|
||||
fi
|
||||
mkdir -p "$_work_dir"
|
||||
gitea_mirror_push_git "$_owner" "$_repo" "$_clone_url" "$_work_dir" || _rc=1
|
||||
gitea_rm_path "$_work_dir/${_repo}.mirror.git"
|
||||
[ -n "$_local_work" ] && gitea_rm_path "$_local_work"
|
||||
return "$_rc"
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ GITEA_OWNER="${GITEA_OWNER:-${GITEA_ORG:-AndroidCast}}"
|
||||
GITEA_MIRROR_INTERVAL="${GITEA_MIRROR_INTERVAL:-24h}"
|
||||
GITEA_PRIVATE="${GITEA_PRIVATE:-false}"
|
||||
GITEA_SUBMODULES_CONF="${GITEA_SUBMODULES_CONF:-$SCRIPT_DIR/submodules.defaults.conf}"
|
||||
WORK_DIR="${WORK_DIR:-/tmp/gitea-submodules-$$}"
|
||||
WORK_DIR="${WORK_DIR:-}"
|
||||
SNIPPET_OUT="${SNIPPET_OUT:-$WORK_DIR/gitmodules.gitea-snippet.ini}"
|
||||
|
||||
log() { printf '[gitea-submodules] %s\n' "$*"; }
|
||||
@@ -159,7 +159,13 @@ if ! gitea_owner_exists "$GITEA_OWNER"; then
|
||||
GITEA_OWNER="$_fb"
|
||||
fi
|
||||
|
||||
mkdir -p "$WORK_DIR"
|
||||
gitea_prune_stale_tmp
|
||||
if [ -n "$WORK_DIR" ]; then
|
||||
mkdir -p "$WORK_DIR"
|
||||
else
|
||||
WORK_DIR="$(gitea_make_work_dir gitea-submodules)"
|
||||
fi
|
||||
trap 'gitea_rm_path "$WORK_DIR"' EXIT INT HUP TERM
|
||||
: > "$WORK_DIR/entries.list"
|
||||
if ! load_submodule_entries "$_gitmodules_arg" | while IFS= read -r _line; do
|
||||
[ -n "$_line" ] || continue
|
||||
|
||||
@@ -53,19 +53,21 @@ gitea_org_create_api() {
|
||||
}
|
||||
EOF
|
||||
)
|
||||
_http="$(curl -sS -o /tmp/gitea-org-create-$$.json -w '%{http_code}' \
|
||||
_resp="$(mktemp /tmp/gitea-org-create-XXXXXX.json)"
|
||||
_http="$(curl -sS -o "$_resp" -w '%{http_code}' \
|
||||
-X POST "$_api/orgs" \
|
||||
-H "Authorization: token $_token" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$_payload")"
|
||||
_rc=1
|
||||
case "$_http" in
|
||||
201|200) return 0 ;;
|
||||
201|200) _rc=0 ;;
|
||||
409|422)
|
||||
gitea_org_exists "$_org" && return 0
|
||||
return 1
|
||||
gitea_org_exists "$_org" && _rc=0
|
||||
;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
gitea_rm_path "$_resp"
|
||||
return "$_rc"
|
||||
}
|
||||
|
||||
gitea_user_create_if_missing() {
|
||||
@@ -156,19 +158,21 @@ gitea_transfer_repo_api() {
|
||||
_token="$(gitea_api_token)" || return 1
|
||||
_api="$(gitea_api_base)"
|
||||
_payload="{\"new_owner\":\"$_to\",\"team_ids\":[]}"
|
||||
_http="$(curl -sS -o /tmp/gitea-transfer-$$.json -w '%{http_code}' \
|
||||
_resp="$(mktemp /tmp/gitea-transfer-XXXXXX.json)"
|
||||
_http="$(curl -sS -o "$_resp" -w '%{http_code}' \
|
||||
-X POST "$_api/repos/$_from/$_repo/transfer" \
|
||||
-H "Authorization: token $_token" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$_payload")"
|
||||
_rc=1
|
||||
case "$_http" in
|
||||
200|201|202) return 0 ;;
|
||||
200|201|202) _rc=0 ;;
|
||||
409|422)
|
||||
gitea_repo_exists_api "$_to" "$_repo" && return 0
|
||||
return 1
|
||||
gitea_repo_exists_api "$_to" "$_repo" && _rc=0
|
||||
;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
gitea_rm_path "$_resp"
|
||||
return "$_rc"
|
||||
}
|
||||
|
||||
# Move known project mirrors from GITEA_TRANSFER_FROM → org (no-op if absent).
|
||||
|
||||
Reference in New Issue
Block a user