aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-01-18 18:01:13 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-01-18 18:01:13 +0200
commitf697b300cc0b421b196193c090df54a121b1d398 (patch)
treea9fe24da2f1a4fec4f6d6df50cc46a1c60d316b1 /server
parentc74e6e00cf4125731e6f9d6a5472989be1c6d1d0 (diff)
Add script for mirroring, update creation script to support
Diffstat (limited to 'server')
-rwxr-xr-xserver/mkrepo (renamed from server/mkrepo.sh)24
-rwxr-xr-xserver/mrrepo149
2 files changed, 166 insertions, 7 deletions
diff --git a/server/mkrepo.sh b/server/mkrepo
index adf48fa..f372d2e 100755
--- a/server/mkrepo.sh
+++ b/server/mkrepo
@@ -1,13 +1,16 @@
#! /usr/bin/env bash
-# Create remote git repository (on the server). You must run this script
-# from the directory where you want the repository to be created.
+# Create remote git repository (on the server). You must run this script from
+# the "repositories root" (e.g., /var/scm) where you want the repository to be
+# created. If the repository is public, also add it to the manifest file (used
+# for mirroring).
#
-# Usage: mkrepo.sh [<options>] <name>
+# Usage: mkrepo [<options>] <name>
#
-# --private make the repository private
+# --private
+# make the repository private
#
-# Note: <name> if without the .git suffix.
+# Note: <name> is without the .git suffix.
#
trap 'exit 1' ERR
@@ -39,9 +42,12 @@ if [ "$1" = "" ]; then
exit 1
fi
-r=$1.git
+r=$1
+if [ `basename $1` = `basename --suffix=.git $1` ]; then
+ r="$r.git"
+fi
-mkdir $r
+mkdir -p $r
chgrp scm $r
git --bare init --shared=all $r
error "Enter project description (one line; or edit $r/descrition later)"
@@ -61,3 +67,7 @@ else
fi
mv $r/hooks/post-update.sample $r/hooks/post-update
+
+if [ "$public" = "y" ]; then
+ echo "$r" >>manifest
+fi
diff --git a/server/mrrepo b/server/mrrepo
new file mode 100755
index 0000000..1210725
--- /dev/null
+++ b/server/mrrepo
@@ -0,0 +1,149 @@
+#! /usr/bin/env bash
+
+# Mirror repositories. For example:
+#
+# mrrepo -s git.example.org /var/scm
+#
+# Will first download (via http or https if -s specified) the manifest file
+# from git.example.org which should list all publicly available repositories.
+# It will then mirror each repository in /var/scm using the git protocol.
+#
+# -v
+# Run verbose.
+#
+# -s
+# Use https rather than http to download the manifest (git protocol is still
+# used for mirroring).
+#
+# Notes:
+# - needs curl
+# - run from cron as user scm (which belongs to the group scm).
+#
+usage="usage: $0 [-v] [-s] <host> <path>"
+
+owd=`pwd`
+trap "{ cd $owd; exit 1; }" ERR
+set -o errtrace # Trap in functions.
+
+function info () { echo "$*" 1>&2; }
+function error () { info "$*"; exit 1; }
+
+prot=http
+host=
+path=
+verb=0
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ -v)
+ verb=1
+ shift
+ ;;
+ -s)
+ prot=https
+ shift
+ ;;
+ *)
+ if [ -z "$host" ]; then
+ host=$1
+ elif [ -z "$path" ]; then
+ path=$1
+ else
+ error "$usage"
+ fi
+ shift
+ ;;
+ esac
+done
+
+if [ -z "$host" -o -z "$path" ]; then
+ error "$usage"
+fi
+
+if [ ! -d "$path" ]; then
+ error "$path is not a directory"
+fi
+
+cd $path
+
+curl_ops="-f" # Fail on HTTP errors.
+curl_ops+=" --max-time 10" # Finish in 10 seconds.
+
+if [ $verb -ge 1 ]; then
+ curl_ops+=" --progress-bar"
+else
+ curl_ops+=" -s -S" # Silent but show errors.
+fi
+
+function fetch () # <url> [<curl-options>]
+{
+ local u=$1; shift
+
+ if [ $verb -ge 1 ]; then
+ info "curl $curl_ops $* $u"
+ fi
+
+ curl $curl_ops $* $u
+}
+
+fetch $prot://$host/manifest -z manifest -o manifest
+
+new=()
+while read r || [ -n "$r" ]; do
+ new+=("$r")
+done <manifest
+
+# Find all existing repositories (directories that end with .git).
+#
+old=(`find . -type d -name '*.git' -print -prune | sed -e 's%^./%%' -`)
+
+git_ops=
+if [ $verb -eq 0 ]; then
+ git_ops+="-q"
+fi
+
+for r in ${new[@]}; do
+ if [ -d $r ]; then
+ if [ -z "$(ls -A $r)" ]; then
+ rm -r $r
+ fi
+ fi
+ if [ ! -d $r ]; then
+ if [ $verb -ge 1 ]; then
+ info "new repository $r in manifest, cloning"
+ info "git clone $git_ops --mirror git://$host/$r $r"
+ fi
+ mkdir -p $r
+ git clone $git_ops --mirror git://$host/$r $r
+
+ # Also copy the description file.
+ #
+ fetch $prot://$host/$r/description -o $r/description
+ else
+ if [ $verb -ge 1 ]; then
+ info "existing repository $r, fetching"
+ info "git -C $r fetch $git_ops --tags"
+ fi
+ git -C $r fetch $git_ops --tags
+ fi
+done
+
+# Remove old repositories.
+#
+for o in ${old[@]}; do
+ for n in ${new[@]}; do
+ if [ $o = $n ]; then
+ o=
+ break
+ fi
+ done
+
+ if [ -n "$o" ]; then
+ if [ $verb -ge 1 ]; then
+ info "repository $o is no longer in manifest, removing"
+ fi
+ rm -rf $o
+ fi
+done
+
+cd $owd