Compare commits

..

3 commits

Author SHA1 Message Date
Max Kratz
2bbfd2b2a7 Snapshot: further conversion prograss
This commit also adds lots of TODOs
2024-01-20 17:00:46 +01:00
Max Kratz
cf3042725c Snapshot: starts the conversion to gitea source instance 2024-01-04 19:02:29 +01:00
Max Kratz
f8ab644cd5 Duplicates the mirroring script 2024-01-04 18:51:29 +01:00
2 changed files with 251 additions and 7 deletions

View file

@ -9,13 +9,6 @@
## Usage
To use this script you need to install `jq` package on your system.
On Ubuntu 22 it can be done using this command:
```
sudo apt install jq
```
Currently, there are two scripts in this repository.
One is able to create mirrors for various GitHub entities and the other is capable of deleting an entire Gitea organization with all of its repositories.

251
gitea2gitea-mirror Executable file
View file

@ -0,0 +1,251 @@
#!/bin/bash
#
# Script to mirror Gitea repos to another Gitea instance.
#
# Modes:
# - Mirror a public/private repo
# - Mirror all public/private repos of a user
# - Mirror all public/private repos of an organization
#
# Heavily inspired by:
# https://github.com/juergenhoetzel/github2gitea-mirror
#
# ENVs:
# ACCESS_TOKEN_SRC = Gitea token of the source instance
# GITERA_URL_SRC = Gitea URL of the source instance
# ACCESS_TOKEN_TRG = Gitea token of the target instance
# GITEA_URL_TRG = Gitea URL of the target instance
# Displays the given input including "=> " on the console.
log () {
echo "=> $1"
}
CURL="curl -f -S -s"
# Check for correctly set ENVs
# TODO: GITEA_URL_SRC is also necessary
# ACCESS_TOKEN_TRG and GITEA_URL_TRG are always necessary
if [[ -z "${ACCESS_TOKEN_TRG}" || -z "${GITEA_URL_TRG}" ]]; then
echo -e "Please set the Gitea access token and URL in environment:\nexport ACCESS_TOKEN_TRG=abc\nexport GITEA_URL_TRG=http://gitea:3000\n" >&2
echo -e "Don't use a trailing slash in URL!"
exit 1
fi
# Parse input arguments
if [[ -z "$1" ]]; then
log "No parameter(s) given. Exit."
exit 1
fi
while [[ "$#" -gt 0 ]]; do
case $1 in
-m|--mode) mode="$2"; shift ;;
-o|--org) gitea_organization="$2"; shift ;;
-u|--user) gitea_user="$2"; shift ;;
-v|--visibility) visibility="$2"; shift ;;
-r|--repo) repo="$2"; shift ;;
*) log "Unknown parameter passed: $1"; exit 1 ;;
esac
shift
done
# Prints a message on how to use the script with exit 1
fail_print_usage () {
echo -e "Usage: $0"
echo -e " -m, --mode {org,repo,user} Mode to use; either mirror an organization or an user."
echo -e " -o, --org \$organization Gitea organization to mirror and/or the target organization in Gitea."
echo -e " -u, --user \$gitea_user Gitea user to gather the repositories from."
echo -e " -v, --visibility {public,private} Visibility for the created Gitea organization."
echo -e " -r, --repo \$repo_url Gitea URL of a single repo to create a mirror for."
echo "" >&2
exit 1;
}
# Check if mode is set
if [[ -z "${mode}" ]]; then
fail_print_usage
fi
# Check required parameters per mode
if [ "${mode}" == "org" ]; then
if [[ -z "${gitea_organization}" ]]; then
echo -e "Organization not set."
fail_print_usage
fi
if [[ -z "${visibility}" ]]; then
echo -e "Visibility not set."
fail_print_usage
fi
elif [ "${mode}" == "repo" ]; then
if [[ -z "${repo}" || -z "${gitea_user}" ]]; then
echo -e "Repo URL or Gitea user not set."
fail_print_usage
fi
elif [ "${mode}" == "user" ]; then
if [[ -z "${gitea_user}" ]]; then
echo -e "Gitea user not set."
fail_print_usage
fi
else
echo -e "Mode not found."
fail_print_usage
fi
# TODO:
#set -euo pipefail
set -eu pipefail
header_options_trg=(-H "Authorization: Bearer ${ACCESS_TOKEN_TRG}" -H "accept: application/json" -H "Content-Type: application/json")
header_options_src=(-H "Authorization: Bearer ${ACCESS_TOKEN_SRC}" -H "accept: application/json" -H "Content-Type: application/json")
jsonoutput=$(mktemp -d -t gitea-repos-XXXXXXXX)
#trap "rm -rf ${jsonoutput}" EXIT
# TODO
# Sets the uid to the specified Gitea organization
set_uid() {
uid=$($CURL "${header_options_trg[@]}" $GITEA_URL_TRG/api/v1/orgs/${gitea_organization} | jq .id)
}
# Sets the uid to the specified Gitea user
set_uid_user() {
uid=$($CURL "${header_options_trg[@]}" $GITEA_URL_TRG/api/v1/users/${gitea_user} | jq .id)
}
# Fetches all public/private repos of the given Gitea organization to JSON files
fetch_orga_repos() {
# TODO
log "Fetch organization repos."
i=1
# GitHub API just returns empty arrays instead of 404
while $CURL "https://api.github.com/orgs/${gitea_organization}/repos?page=${i}&per_page=100" -u "username:${GITHUB_TOKEN}" >${jsonoutput}/${i}.json \
&& (( $(jq <${jsonoutput}/${i}.json '. | length') > 0 )) ; do
(( i++ ))
done
}
# Fetches all public/private repos of the given Gitea user to JSON files
fetch_user_repos() {
# TODO
log "Fetch user repos."
# i=1
# GitHub API just returns empty arrays instead of 404
# while $CURL "https://api.github.com/user/repos?affiliation=owner&page=${i}&per_page=100" -u "${github_user}:${GITHUB_TOKEN}" >${jsonoutput}/${i}.json \
# && (( $(jq <${jsonoutput}/${i}.json '. | length') > 0 )) ; do
# (( i++ ))
# done
# $CURL -w "%{http_code}\n" "${header_options_src[@]}" -d @- -X GET $GITEA_URL_SRC/api/v1/user/repos
mkdir -p $jsonoutput
# touch $jsonoutput/1.json
$CURL "${header_options_src[@]}" -X GET $GITEA_URL_SRC/api/v1/user/repos >$jsonoutput/1.json
# TODO
# exit 1
}
# Fetches one public/private Gitea repo to a JSON file
fetch_one_repo() {
# TODO
log "Fetch one repo."
# Remove URL prefix
repo=$(echo $repo | sed "s/https:\/\/github.com\///g" | sed "s/.git//g")
$CURL "https://api.github.com/repos/$repo" -u "username:${GITHUB_TOKEN}" >${jsonoutput}/1.json
}
# Creates a specific migration repo on Gitea
create_migration_repo() {
log "Create migration repo."
if ! $CURL -w "%{http_code}\n" "${header_options_trg[@]}" -d @- -X POST $GITEA_URL_TRG/api/v1/repos/migrate > ${jsonoutput}/result.txt 2>${jsonoutput}/stderr.txt; then
local code=$(<${jsonoutput}/result.txt)
if (( code != 409 ));then # 409 == repo already exits
cat ${jsonoutput}/stderr.txt >&2
fi
fi
}
# Creates a specific public/private organization on Gitea
create_migration_orga() {
visibility="${1:-}"
log "Create migration orga with name: ${gitea_organization}"
if ! $CURL -X POST $GITEA_URL_TRG/api/v1/orgs "${header_options_trg[@]}" --data '{"username": "'"${gitea_organization}"'", "visibility": "'"${visibility}"'"}' > ${jsonoutput}/result.txt 2>${jsonoutput}/stderr.txt; then
local code=$(<${jsonoutput}/result.txt)
if (( code != 422 ));then # 422 == orga already exits
cat ${jsonoutput}/stderr.txt >&2
fi
fi
}
# Creates a migration repo on Gitea for each Gitea repo in the JSON files
repos_to_migration() {
# TODO
log "Repos to migration started."
# for f in ${jsonoutput}/*.json; do
# n=$(jq '. | length'<$f)
# if [[ "${n}" -gt "0" ]]; then
# (( n-- )) # last element
# else
# continue;
# fi
# for i in $(seq 0 $n); do
# mig_data=$(jq ".[$i] | .uid=${uid} | \
# if(.visibility==\"private\") then .private=true else .private=false end |\
# if(.visibility==\"private\") then .auth_username=\"${github_user}\" else . end | \
# if(.visibility==\"private\") then .auth_password=\"${GITHUB_TOKEN}\" else . end | \
# .mirror=true | \
# .clone_addr=.clone_url | \
# .description=.description[0:255] | \
# .repo_name=.name | \
# {uid,repo_name,clone_addr,description,mirror,private,auth_username,auth_password}" <$f)
# echo "Migrating repo" $(jq ".[$i] | .uid=${uid} | .name" <$f)
# echo $mig_data | create_migration_repo
# done
# done
}
# Creates one migration repo on Gitea for the one Gitea repo in '1.json'
one_repo_to_migration() {
# TODO
log "One repo to migration started."
# There should only be one JSON file
for f in ${jsonoutput}/*.json; do
mig_data=$(jq ".repo_owner=\"${gitea_user}\" | \
if(.visibility==\"private\") then .private=true else .private=false end |\
if(.visibility==\"private\") then .auth_username=\"${gitea_user}\" else . end | \
if(.visibility==\"private\") then .auth_password=\"${GITEA_TOKEN_SRC}\" else . end | \
.mirror=true | \
.clone_addr=.clone_url | \
.description=.description[0:255] | \
.repo_name=.name | \
{repo_owner,repo_name,clone_addr,description,mirror,private,auth_username,auth_password}" <$f)
echo "Migrating repo" $(jq ".name" <$f)
echo $mig_data | create_migration_repo
done
}
# Actual run the script
if [ "${mode}" == "org" ]; then
log "Mode = organization"
fetch_orga_repos
create_migration_orga ${visibility}
set_uid
repos_to_migration
elif [ "${mode}" == "repo" ]; then
log "Mode = single repo"
fetch_one_repo
one_repo_to_migration
elif [ "${mode}" == "user" ]; then
log "Mode = user"
# set_uid_user
fetch_user_repos
exit 1
# TODO
repos_to_migration
fi
log "Finished."