Created
May 24, 2024 21:58
-
-
Save boricj/909d3df166af8c5c2fe9fa66bdce8b72 to your computer and use it in GitHub Desktop.
git-proxy-cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
# | |
# Git read-only remote cache for SSH. | |
# | |
# This script is to be used as a shell for a dedicated Git user. Each time a | |
# clone/pull is attempted on the cache, it will either: | |
# * fetch everything from the remote if it has already been cloned, or | |
# * attempt to clone the remote. | |
# | |
# The local repository will then be used as a source to satisfy the request. | |
# The end-result is a local cache for remote Git repositories which will most | |
# of the time fetch almost nothing from the remote even if the client makes a | |
# full clone. | |
# | |
ROOT_PATH='/var/lib/git' | |
BANNER='Git proxy cache server.' | |
>&2 echo "mirror: $BANNER" | |
# Expand command line arguments and eat extra quotes | |
set -- $(echo "$@" | sed -e "s/'//g") | |
# Eat -c | |
if [ "$1" == '-c' ] | |
then | |
shift 1 | |
fi | |
if [[ "$1" == 'git-upload-archive' || "$1" == 'git-upload-pack' ]] | |
then | |
REPO_URL="${@: -1}" | |
>&2 echo "mirror: Processing download request of '$REPO_URL'." | |
# Sanity check the URL. | |
if [[ "$REPO_URL" =~ \.\. ]] | |
then | |
>&2 echo "mirror: error: invalid request $REPO_URL" | |
exit 1 | |
fi | |
# Remove leading slash. | |
if [[ "$REPO_URL" =~ ^/ ]] | |
then | |
REPO_URL="${REPO_URL:1}" | |
fi | |
# Grab on-disk path by stripping out protocol and username. | |
REPO_PATH="$ROOT_PATH/$(echo "$REPO_URL" | cut -f3- -d'/' | cut -f2- -d'@' | tr A-Z a-z)" | |
LOCK_PATH="$(dirname "$REPO_PATH")/.lock.$(basename "$REPO_PATH")" | |
mkdir -p "$(dirname "$REPO_PATH")" | |
# Clone or fetch to update the local repository. | |
if [ ! -d "$REPO_PATH/objects" ] | |
then | |
>&2 echo "mirror: Cloning from remote $REPO_URL" | |
flock "$LOCK_PATH" git clone --progress --mirror "$REPO_URL" "$REPO_PATH" | |
>&2 echo "mirror: Cloning done." | |
else | |
>&2 echo "mirror: Fetching from remote $(cd "$REPO_PATH" && git remote get-url origin)" | |
(cd "$REPO_PATH" && flock "$LOCK_PATH" git fetch --append) >/dev/null | |
>&2 echo "mirror: Fetching done." | |
fi | |
# Local repository is up to date, serve request from it. | |
>&2 echo "mirror: Running command: $1 $REPO_PATH" | |
exec "$1" "$REPO_PATH" | |
elif [ "$1" == git-receive-pack ] | |
then | |
>&2 echo "mirror: error: This is a read-only Git cache, upload request denied." | |
else | |
>&2 echo "mirror: error: Unknown command '$1'." | |
fi | |
# If we get here then we failed. | |
exit 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment