add a first version of a README
authorRalf Jung <post@ralfj.de>
Sun, 19 Jul 2015 09:39:13 +0000 (11:39 +0200)
committerRalf Jung <post@ralfj.de>
Sun, 19 Jul 2015 09:39:13 +0000 (11:39 +0200)
.gitignore
LICENSE-BSD [new file with mode: 0644]
README.rst [new file with mode: 0644]
webhook.py

index 4baa187a1b145c2c1002431c4387cc53bf367316..ece32d51524ab6bd499ec921fa1918d45fef7fbf 100644 (file)
@@ -1,2 +1,3 @@
 __pycache__
 git-mirror.conf*
 __pycache__
 git-mirror.conf*
+README.html
diff --git a/LICENSE-BSD b/LICENSE-BSD
new file mode 100644 (file)
index 0000000..7ef1730
--- /dev/null
@@ -0,0 +1,23 @@
+Copyright (c) 2014, Ralf Jung <post@ralfj.de>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer. 
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/README.rst b/README.rst
new file mode 100644 (file)
index 0000000..940a744
--- /dev/null
@@ -0,0 +1,145 @@
+git-mirror - Sync your git repositories
+=======================================
+
+Introduction
+------------
+
+git-mirror_ is a tool to keep multiple git repositories of the same project in 
+sync. Whenever something is pushed to any repository, the commits will 
+immediately be forwarded to all the others. The tool assumes to run on a server 
+hosting one of these repositories - so there has to be at least one you can 
+control. A typical use-case would be your own gitolite_ installation, that you 
+want to keep in sync with GitHub_.
+
+.. _git-mirror: https://www.ralfj.de/projects/git-mirror
+.. _gitolite: http://gitolite.com/gitolite/index.html
+.. _GitHub: https://github.com/
+
+Setup (gitolite)
+----------------
+
+This describes how you set up git-mirror on a server running gitolite. For other 
+git hosting software, please consult the respective documentation on adding git 
+hooks. I will assume that gitolite is installed to ``/home/git/gitolite``, that 
+the repositories are sitting in ``/home/git/repositories``, and that git-mirror 
+has been cloned to ``/home/git/git-mirror``.
+
+First of all, you need to create a file called ``git-mirror.conf`` in the 
+``git-mirror`` directory. For now, it only needs to contain a single line::
+
+  mail-sender = git@example.com
+
+We will also need to add hooks to the git repositories you want to sync. The 
+easiest way to manage these hooks is to put them into your ``gitolite-admin`` 
+repository, so enable the following line in ``/home/git/.gitolite.rc``::
+
+  LOCAL_CODE                =>  "$rc{GL_ADMIN_BASE}/local",
+
+Make sure you read the `security note 
+<http://gitolite.com/gitolite/non-core.html#pushcode>`_ concerning this 
+configuration.
+
+Now add a file called ``local/hooks/repo-specific/git-mirror`` to your 
+``gitolite-admin`` repository, make ii executable, and give it the following 
+content::
+
+  #!/bin/sh
+  exec ~/git-mirror/githook.py
+
+For every repository you want to be synced, you can enable the hook by adding 
+the following line to its configuration in ``conf/gitolite.conf``::
+
+  option hook.post-receive = git-mirror
+
+(If you need multiple hooks here, you can separate them by spaces.)
+
+Finally, you need to tell git-mirror where to sync incoming changes to this 
+repository to. Add a block like the following to ``git-mirror.conf``::
+
+  [repo-name]                                                                                                                                                                                                                                     
+  owner = post@ralfj.de                                                                                                                                                                                                                        
+  local = /home/git/repositories/repo-name.git                                                                                                                                                                                                    
+  deploy-key = ssh-key                                                                                                                                                                                                               
+  mirror-a = git@server2.example.com:repo-name.git
+  mirror-b = git@server2.example.org:the-repo.git
+
+Here, ``local`` has to be set to the path where the repository is stored 
+locally. ``deploy-key`` is the name of the SSH key used for pushing the changes 
+to other repositories. ``owner`` is the e-mail-address that error messages 
+occurring during synchronization are sent to. And finally, the URLs to push to 
+are given by ``mirror-<something>``. If these other servers also run gitolite 
+and have a symmetric setup, then no matter where a change is pushed, git-mirror 
+will forward it to all the other repositories.
+
+Setup (GitHub)
+--------------
+
+This explains how to configure a GitHub repository that should be part of a 
+synchronized set. I will assume that one of the copies of the repository lives 
+on a gitolite server you control.
+
+Since you cannot install a normal git hook on GitHub, syncing changes that are 
+sent to GitHub has to be done with a webhook. First of all, you will have to 
+configure your webserver to run ``webhook.py`` as CGI script. Consult the 
+webserver documentation for more details.
+
+Secondly, ``webhook.py`` needs to be able to find the main git-mirror scripts, 
+and it needs to be able to execute them as the ``git`` user. For the first 
+point, open ``webhook.py`` and change ``webhook_core`` to point to the file 
+``webhook-core.py`` in your git-mirror clone. If your installation matches the 
+paths I used above, that should already be the case. For the second point, 
+``webhook.py`` is using ``sudo`` to elevate its privileges. You need to tell 
+``sudo`` that this is all right, by creating a file 
+``/etc/sudoers.d/git-mirror`` with content::
+
+  www-data        ALL=(git) NOPASSWD: /home/git/git-mirror/webhook-core.py
+
+Now, if you visit ``https://example.com/git-mirror/webhook.py`` (replace with 
+your URL), the script should run and tell you ``Repository missing or not 
+found.``.
+
+The next step is to add this as a webhook to the GitHub repository you want to 
+sync with, to create a fresh SSH key and configure it as deployment key for the 
+repository, and to configure git-mirror accordingly. For additional security, 
+one shouldalso configure a shared HMAC secret, such that the webhook can verify 
+that the data indeed comes from GitHub.
+
+To make your job easier, there is a script ``github-add-hooks.py`` that can do 
+all this for you. It assumes that the repository exists on the GitHub side, but 
+has not yet been configure for git-mirror, neither locally nor remotely.
+
+To give the script access to your repositories, you need to create an access 
+token for it. Go to "Personal Access Tokens" in your GitHub configuration, and 
+create a new token with the permissions ``admin:repo_hook`` and ``public_repo``. 
+Add the token and the webhook URL to the top part of ``git-mirror.conf`` (right 
+below ``mail-sender``)::
+
+  github-token = pastethetokenhere
+  webhook-url = https://example.com/git-mirror/webhook.py
+
+Now you can call the automatic setup script as follows::
+
+  ./github-add-hooks.py -o UserName -e email@ddress.com -l ~/repositories/repo-name.git/ -n github-repo-name
+
+Notice that the username is case-sensitive! This will do all the setup on the 
+GitHub side, and it will add an appropriate configuration block to your local 
+``git-mirror.conf``. You will still have to manually add the local git hook to 
+gitolite.
+
+Source, License
+---------------
+
+You can find the sources in the `git repository`_ (also available `on GitHub`_). 
+They are provided under a `2-clause BSD license`_. See the file ``LICENSE-BSD`` 
+for more details.
+
+.. _git repository: http://www.ralfj.de/git/git-mirror.git
+.. _on GitHub: https://github.com/RalfJung/git-mirror
+.. _2-clause BSD license: http://opensource.org/licenses/bsd-license.php
+
+Contact
+-------
+
+If you found a bug, or want to leave a comment, please
+`send me a mail <mailto:post-AT-ralfj-DOT-de>`_. I'm also happy about pull
+requests :)
index 6630c0df4bfc389125bd039432c44de6e55fee8e..0b3f11faa0330b2a3a3893b36743d47e6e5a18b2 100755 (executable)
@@ -26,7 +26,8 @@
 # This is the CGI script receiving GitHub webhooks.
 # You may have to change the location of the "main" webhook script:
 webhook_core = "/home/git/git-mirror/webhook-core.py"
 # This is the CGI script receiving GitHub webhooks.
 # You may have to change the location of the "main" webhook script:
 webhook_core = "/home/git/git-mirror/webhook-core.py"
-#
+
+# Do NOT change anything below here
 import urllib.request, urllib.parse, json, os, sys
 
 # get repository from query string
 import urllib.request, urllib.parse, json, os, sys
 
 # get repository from query string