Two way git mirror

From Arianne
Revision as of 02:08, 28 December 2015 by imported>Hendrik Brummermann (Created page with "== Motivation == == Setup == == Mirror == We use the following script to do the actually mirroring. It can be invoked with the name of a known repository as parameter or wi...")
Jump to navigation Jump to search

Motivation

Setup

Mirror

We use the following script to do the actually mirroring. It can be invoked with the name of a known repository as parameter or with the "--all" flag.

<source lang="bash">

  1. !/bin/bash

function sync_repo {

   cd /srv/gitsync
   cd $1
   echo $1
   # fetch all known remotes
   git fetch --all -p
   # push branches from sourceforge to github and via versa.
   git push github "refs/remotes/sourceforge/*:refs/heads/*"
   git push sourceforge "refs/remotes/github/*:refs/heads/*"

}

cd /srv/gitsync if [ "$1" == "" ]; then

   # no command line parameters, print help message
   echo "gitsync [report]|--all"

elif [ "$1" == "--all" ]; then

   # "--all": for all known repositories
   for D in *; do
      if [ -d "${D}" ]; then
            sync_repo $D
            cd /srv/gitsync
      fi
   done

elif [ -d "$1" ]; then

   # sync only the specified repository
   sync_repo $1

else echo "gitsync [report]|--all" fi </source>

In function sync_repo the branches from remotes named github and sourceforge are pushed to each other. You can more mappings here.


As discussed in the previous section, we use webhooks to initiate a mirroring run on every push. This is achieved by the following php script:

<source lang="php"> if ($_SERVER['REQUEST_METHOD'] !== 'POST') { die('POST required'); }

if (!isset($_REQUEST['repository'])) { die('repository not specified'); }

// validate repository name to prevent injection and traversing attacks $repo = $_REQUEST['repository']; if (!preg_match('/^[a-zA-Z0-9]$/', $repo)) { die('invalid repository name'); }

header('HTTP/1.0 204 Found'); system('sudo -Hu gitsync /usr/local/bin/gitsync '.$repo); </source>


Security

  • It is important to validate the repository name in order to prevent shell command injection, git parameter injection and directory traversing
  • We use sudo to execute gitsync as user gitsync. Thus the webserver process does not require write access to the repositories
  • Both Sourceforge and Github support a secret to authorize webhook invocations. In the above example this is not verified, so anyone can trigger a sync.

Deleting branches