1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 04:57:40 +03:00

gitea-related

This commit is contained in:
Anton Afanasyeu
2026-06-10 21:43:04 +02:00
parent f7d86e3bb2
commit bc6b7cc17b
3 changed files with 382 additions and 0 deletions

View File

@@ -0,0 +1,171 @@
#!/bin/ash
# Shared pull-mirror helpers for Gitea BE scripts.
# shellcheck shell=sh
# Requires: . "$SCRIPT_DIR/gitea_ini.sh" && gitea_load_config
gitea_public_repo_url_for() {
_owner="$1"
_repo="$2"
_root="$GITEA_ROOT_URL"
case "$_root" in
*/) _root="${_root%/}" ;;
esac
printf '%s/%s/%s.git' "$_root" "$_owner" "$_repo"
}
gitea_local_git_url_for() {
printf 'http://127.0.0.1:%s/%s/%s.git' "${GITEA_HTTP_PORT:-3000}" "$1" "$2"
}
gitea_api_base() {
printf '%s' "${GITEA_LOCAL_API:-http://127.0.0.1:3000/api/v1}"
}
gitea_resolve_push_token() {
if [ -n "${GITEA_ADMIN_TOKEN:-}" ]; then
printf '%s' "$GITEA_ADMIN_TOKEN"
return 0
fi
_token=""
_token="$(gitea_cli "admin" "user" "generate-access-token" \
"--username" "$GITEA_OWNER" \
"--token-name" "mirror-$$" \
"--scopes" "all" \
"--raw" 2>/dev/null)" && [ -n "$_token" ] && printf '%s' "$_token" && return 0
_admin="$(gitea_pick_owner_username)"
if [ -n "$_admin" ] && [ "$_admin" != "$GITEA_OWNER" ]; then
_token="$(gitea_cli "admin" "user" "generate-access-token" \
"--username" "$_admin" \
"--token-name" "mirror-$$" \
"--scopes" "all" \
"--raw" 2>/dev/null)" && [ -n "$_token" ] && printf '%s' "$_token" && return 0
fi
return 1
}
gitea_owner_uid_for() {
_owner="$1"
command -v curl >/dev/null 2>&1 || return 1
_token="${GITEA_ADMIN_TOKEN:-}"
[ -n "$_token" ] || _token="$(gitea_resolve_push_token)" || return 1
_api="$(gitea_api_base)"
_uid="$(curl -sS "$_api/users/$_owner" \
-H "Authorization: token $_token" \
| awk -F'"' '/"id"/ { print $4; exit }')"
[ -n "$_uid" ] || return 1
printf '%s' "$_uid"
}
gitea_create_repo_cli() {
_owner="$1"
_repo="$2"
_private="${3:-false}"
if gitea_cli "admin" "user" "create-repo" \
"--username" "$_owner" \
"--name" "$_repo" \
"--private=$_private" 2>/dev/null; then
return 0
fi
gitea_cli "admin" "create-repository" \
"--owner" "$_owner" \
"--name" "$_repo" \
"--private=$_private" 2>/dev/null
}
gitea_migrate_mirror_api() {
_owner="$1"
_repo="$2"
_clone_url="$3"
_interval="${4:-10m}"
_private="${5:-false}"
_desc="${6:-Pull mirror of $_clone_url}"
command -v curl >/dev/null 2>&1 || return 1
_token="${GITEA_ADMIN_TOKEN:-}"
[ -n "$_token" ] || _token="$(gitea_resolve_push_token)" || return 1
_uid="$(gitea_owner_uid_for "$_owner")" || return 1
_api="$(gitea_api_base)"
_payload=$(cat <<EOF
{
"clone_addr": "$_clone_url",
"repo_name": "$_repo",
"uid": $_uid,
"mirror": true,
"mirror_interval": "$_interval",
"private": $_private,
"wiki": false,
"issues": false,
"milestones": false,
"labels": false,
"releases": true,
"description": "$_desc"
}
EOF
)
_http="$(curl -sS -o /tmp/gitea-migrate-$$.json -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
return 0
fi
if [ "$_http" = "409" ] || [ "$_http" = "422" ]; then
return 2
fi
return 1
}
gitea_mirror_push_git() {
_owner="$1"
_repo="$2"
_clone_url="$3"
_work_dir="$4"
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
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
}
gitea_sync_mirror_api() {
_owner="$1"
_repo="$2"
command -v curl >/dev/null 2>&1 || return 1
_token="${GITEA_ADMIN_TOKEN:-}"
[ -n "$_token" ] || _token="$(gitea_resolve_push_token)" || return 1
_api="$(gitea_api_base)"
curl -sS -o /dev/null -w '%{http_code}' \
-X POST "$_api/repos/$_owner/$_repo/mirror-sync" \
-H "Authorization: token $_token" | grep -q '^20'
}
# Mirror one upstream into Gitea (API migrate, else git push). Returns 0 on success.
gitea_mirror_pull_repo() {
_clone_url="$1"
_repo="$2"
_owner="${3:-$GITEA_OWNER}"
_interval="${4:-${GITEA_MIRROR_INTERVAL:-10m}}"
_work_dir="${5:-/tmp/gitea-mirror-$$}"
_rc=0
gitea_migrate_mirror_api "$_owner" "$_repo" "$_clone_url" "$_interval" "${GITEA_PRIVATE:-false}" \
&& return 0
_api_rc=$?
if [ "$_api_rc" -eq 2 ]; then
gitea_sync_mirror_api "$_owner" "$_repo" && return 0
return 0
fi
mkdir -p "$_work_dir"
gitea_mirror_push_git "$_owner" "$_repo" "$_clone_url" "$_work_dir" || _rc=1
return "$_rc"
}

View File

@@ -0,0 +1,200 @@
#!/bin/ash
#
# Mirror android_cast git submodules into Gitea as pull mirrors, then print a
# .gitmodules snippet pointing at Gitea URLs (commit that on canonical git).
#
# Usage (on Alpine BE as root or GITEA RUN_USER):
# sudo ./gitea_mirror_submodules.sh
# sudo ./gitea_mirror_submodules.sh /path/to/android_cast/.gitmodules
# GITEA_SUBMODULES_CONF=./extra.list sudo ./gitea_mirror_submodules.sh
#
# Requires [migrations] allowlist in app.ini for upstream hosts, e.g.:
# ALLOW_LOCALNETWORKS = true
# ALLOWED_DOMAINS = *,github.com,*.github.com,chromium.googlesource.com,git.zx2c4.com
#
set -eu
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=gitea_ini.sh
. "$SCRIPT_DIR/gitea_ini.sh"
# shellcheck source=gitea_mirror_lib.sh
. "$SCRIPT_DIR/gitea_mirror_lib.sh"
GITEA_OWNER="${GITEA_OWNER:-admin}"
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-$$}"
SNIPPET_OUT="${SNIPPET_OUT:-$WORK_DIR/gitmodules.gitea-snippet.ini}"
log() { printf '[gitea-submodules] %s\n' "$*"; }
warn() { printf '[gitea-submodules] WARN: %s\n' "$*" >&2; }
die() { printf '[gitea-submodules] ERROR: %s\n' "$*" >&2; exit 1; }
# Parse .gitmodules -> repo|url|path|branch lines (repo = basename of path).
parse_gitmodules_file() {
_file="$1"
[ -r "$_file" ] || return 1
awk '
function trim(s) {
sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s)
return s
}
/^[ \t]*path[ \t]*=/ {
p = $0; sub(/^[^=]*=/, "", p); path = trim(p)
n = path; sub(".*/", "", n)
next
}
/^[ \t]*url[ \t]*=/ {
u = $0; sub(/^[^=]*=/, "", u); url = trim(u)
next
}
/^[ \t]*branch[ \t]*=/ {
b = $0; sub(/^[^=]*=/, "", b); branch = trim(b)
next
}
/^\[/ {
if (path != "" && url != "" && n != "") {
if (branch != "") print n "|" url "|" path "|" branch
else print n "|" url "|" path
}
path = ""; url = ""; branch = ""; n = ""
}
END {
if (path != "" && url != "" && n != "") {
if (branch != "") print n "|" url "|" path "|" branch
else print n "|" url "|" path
}
}
' "$_file"
}
load_submodule_entries() {
_gitmodules="${1:-}"
if [ -n "$_gitmodules" ] && [ -r "$_gitmodules" ]; then
log "reading submodules from $_gitmodules"
parse_gitmodules_file "$_gitmodules"
return 0
fi
if [ -r "$GITEA_SUBMODULES_CONF" ]; then
log "reading submodules from $GITEA_SUBMODULES_CONF"
grep -v '^[[:space:]]*#' "$GITEA_SUBMODULES_CONF" | grep -v '^[[:space:]]*$'
return 0
fi
return 1
}
write_gitmodules_snippet() {
_out="$1"
mkdir -p "$(dirname "$_out")"
: > "$_out"
while read -r line; do
[ -n "$line" ] || continue
_repo="${line%%|*}"
_rest="${line#*|}"
_url="${_rest%%|*}"
_rest2="${_rest#*|}"
_path="${_rest2%%|*}"
_branch="${_rest2#*|}"
case "$_branch" in
"$_path") _branch="" ;;
esac
_gitea_url="$(gitea_public_repo_url_for "$GITEA_OWNER" "$_repo")"
{
printf '[submodule "%s"]\n' "$_path"
printf '\tpath = %s\n' "$_path"
printf '\turl = %s\n' "$_gitea_url"
[ -n "$_branch" ] && printf '\tbranch = %s\n' "$_branch"
printf '\n'
} >> "$_out"
done <<EOF
$(cat "$WORK_DIR/entries.list")
EOF
}
# --- main ---
gitea_load_config || exit 1
gitea_ensure_cli_access || exit 1
_gitmodules_arg=""
if [ $# -ge 1 ] && [ -n "$1" ]; then
case "$1" in
-h|--help)
sed -n '2,18p' "$0"
exit 0
;;
*)
_gitmodules_arg="$1"
;;
esac
fi
if ! gitea_user_exists "$GITEA_OWNER"; then
_fb="$(gitea_pick_owner_username)"
[ -n "$_fb" ] || die "no Gitea user; set GITEA_OWNER=admin (or create admin in UI)"
warn "GITEA_OWNER=$GITEA_OWNER not found; using $_fb"
GITEA_OWNER="$_fb"
fi
mkdir -p "$WORK_DIR"
load_submodule_entries "$_gitmodules_arg" > "$WORK_DIR/entries.list" \
|| die "no submodule list (pass .gitmodules path or use $GITEA_SUBMODULES_CONF)"
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
log "owner=$GITEA_OWNER interval=$GITEA_MIRROR_INTERVAL ini=$GITEA_APP_INI"
_ok=0
_fail=0
while IFS= read -r line; do
[ -n "$line" ] || continue
_repo="${line%%|*}"
_rest="${line#*|}"
_upstream="${_rest%%|*}"
_path="${_rest#*|}"
_path="${_path%%|*}"
log "mirror $_repo <- $_upstream"
if git ls-remote "$_upstream" HEAD >/dev/null 2>&1; then
log " upstream reachable"
else
warn " upstream not reachable from BE (mirror may still fail)"
fi
if gitea_mirror_pull_repo "$_upstream" "$_repo" "$GITEA_OWNER" "$GITEA_MIRROR_INTERVAL" "$WORK_DIR"; then
log " OK -> $(gitea_public_repo_url_for "$GITEA_OWNER" "$_repo")"
_ok=$((_ok + 1))
else
warn " FAILED $_repo"
_fail=$((_fail + 1))
fi
done < "$WORK_DIR/entries.list"
write_gitmodules_snippet "$SNIPPET_OUT"
log "mirrors ok=$_ok failed=$_fail"
log "Wrote .gitmodules snippet: $SNIPPET_OUT"
printf '\n'
cat "$SNIPPET_OUT"
printf '\n'
_main_repo_url="$(gitea_public_repo_url_for "$GITEA_OWNER" "android_cast")"
cat <<EOF
Next steps (canonical git at git://10.7.0.10/android_cast — NOT the Gitea mirror):
1. Replace submodule url= lines in .gitmodules with the snippet above (keep paths/branches).
2. git add .gitmodules && git commit -m "submodules: point URLs at Gitea mirrors"
3. Push to canonical remote; android_cast pull mirror on Gitea picks it up on next sync.
Clone with submodules from Gitea:
git clone --recurse-submodules $_main_repo_url
Periodic sync all mirrors:
sudo -u $GITEA_RUN_USER gitea -c $GITEA_APP_INI admin repo-sync-mirrors
EOF
[ "$_fail" -eq 0 ] || exit 1

View File

@@ -0,0 +1,11 @@
# Gitea pull mirrors for android_cast git submodules.
# Format: repo_name|upstream_clone_url|submodule_path[|branch]
# Lines starting with # are ignored. Add local git:// entries at the bottom.
libvpx|https://chromium.googlesource.com/webm/libvpx|third-party/libvpx|main
opus|https://github.com/xiph/opus|third-party/opus
speex|https://github.com/xiph/speex/|third-party/speex
wireguard-android|https://git.zx2c4.com/wireguard-android|third-party/wireguard-android
# Example local submodule (uncomment and set your git daemon URL):
# mylib|git://10.7.0.10/mylib|third-party/mylib