James Moger
2012-03-21 12c31ef28e1396f652f6f80f84480c0833182150
docs/02_federation.mkd
@@ -2,12 +2,22 @@
*SINCE 0.6.0*
A Gitblit federation is a mechanism to clone repositories and keep them in sync from one Gitblit instance to another.  Federation can be used for automated backup of your repositories or may be used to initially clone groups of repositories to developer workstations.  If you are/were a Subversion user you might think of this as [svn-sync](http://svnbook.red-bean.com/en/1.5/svn.ref.svnsync.html), but better.
A Gitblit federation is a mechanism to clone repositories and keep them in sync from one Gitblit instance to another.  Federation can be used to maintain a mirror of your Gitblit instance, to aggregate repositories from developer workstations, or to initially clone groups of repositories to developer workstations.  If you are/were a Subversion user you might think of this as [svn-sync](http://svnbook.red-bean.com/en/1.5/svn.ref.svnsync.html), but better.
If your Gitblit instance allows federation and it is properly registered with another Gitblit instance, each of the *non-excluded* repositories of your Gitblit instance can be mirrored, in their entirety, to the pulling Gitblit instance.  You may optionally allow pulling of user accounts and backup of server settings.
The federation feature should be considered a security backdoor and enabled or disabled as appropriate for your installation.<br/>
Please review all the documentation to understand how it works and its limitations.
![block diagram](fed_aggregation.png "Gitblit Federation Aggregation")
### Important Changes to Note
The *Gitblit 0.8.0* federation protocol adds retrieval of teams and referenced push scripts.  Older clients will not know to request team or push script information.
The *Gitblit 0.7.0* federation protocol is incompatible with the 0.6.0 federation protocol because of a change in the way timestamps are formatted.
Gitblit 0.6.0 uses the default [google-gson](http://google-gson.googlecode.com) timestamp serializer which generates locally formatted timestamps.  Unfortunately, this creates problems for distributed repositories and distributed developers.  Gitblit 0.7.0 corrects this error by serializing dates to the [iso8601](http://en.wikipedia.org/wiki/ISO_8601) standard.  As a result 0.7.0 is not compatible with 0.6.0.  A partial backwards-compatibility fallback was considered but it would only work one direction and since the federation mechanism is bidirectional it was not implemented.
### Origin Gitblit Instance Requirements
@@ -25,7 +35,7 @@
The federation feature is completely disabled if your passphrase value is empty.
**NOTE**:<br/>
**NOTE**:
Changing your *federation.passphrase* will break any registrations you have established with other Gitblit instances.
### Pulling Gitblit Instance Requirements
@@ -37,34 +47,36 @@
If you want your repositories (and optionally users accounts and settings) to be pulled by another Gitblit instance, you need to register your origin Gitblit instance with a pulling Gitblit instance by providing the url of your Gitblit instance and a federation token.
Gitblit generates the following federation tokens:
Gitblit generates the following standard federation tokens:
%BEGINCODE%
String allToken = SHA1(passphrase + "-ALL");
String usersAndRepositoriesToken = SHA1(passphrase + "-USERS_AND_REPOSITORIES");
String repositoriesToken = SHA1(passphrase + "-REPOSITORIES");
%ENDCODE%
    
The *ALL* token allows another Gitblit instance to pull all your repositories, user accounts, and server settings.<br/>
The *USERS_AND_REPOSITORIES* token allows another Gitblit instance to pull all your repositories and  user accounts.<br/>
The *ALL* token allows another Gitblit instance to pull all your repositories, user accounts, server settings, and referenced push scripts.
The *USERS_AND_REPOSITORIES* token allows another Gitblit instance to pull all your repositories and  user accounts.
The *REPOSITORIES* token only allows pulling of the repositories.
Individual Gitblit repository configurations such as *description* and *accessRestriction* are always mirrored.
If *federation.passphrase* has a non-empty value, the federation tokens are displayed in the log file and are visible, to administrators, in the web ui.
The three standard tokens grant access to ALL your non-excluded repositories.  However, if you only want to specify different groups of repositories to be federated then you need to define *federation sets*.
#### Federation Sets
Federation Sets (*federation.sets*) are named groups of repositories.  The Federation Sets are defined in `gitblit.properties` and are available for selection in the repository settings page.  You can assign a repository to one or more sets and then distribute the token for the set.  This allows you to grant federation pull access to a subset of your available repositories.  Tokens for federation sets only grant pull access for the member repositories.
Federation Sets (*federation.sets*) are named groups of repositories.  The Federation Sets are defined in `gitblit.properties` and are available for selection in the repository settings page.  You can assign a repository to one or more sets and then distribute the federation token for the set.  This allows you to grant federation pull access to a subset of your available repositories.  Tokens for federation sets only grant pull access for the member repositories.
### Federation Proposals (Origin Gitblit Instance)
Once you have properly setup your passphrase and can see your federation tokens, you are ready to share them with a pulling Gitblit instance.
 
The registration process can be partially automated by sending a *federation proposal* to the pulling Gitblit instance.<br/>
The registration process can be partially automated by sending a *federation proposal* to the pulling Gitblit instance.
To send a proposal:
1. Login to your Gitblit instance as an administrator
2. Select and click the *propose* link for the appropriate token at the bottom of the repositories page
2. Select and click the *propose* link for the appropriate token on the *federation* page
3. Confirm the publicly accessible url of your (origin) Gitblit instance
4. Enter the url of the pulling Gitblit instance you want to federate with
5. Optionally enter a message for the administrators
@@ -80,7 +92,7 @@
2. the federation token you selected and its type
3. the list of your *non-excluded* repositories, and their configuration details, that you propose to share
Submitting a proposal does not automatically register your server with the pulling Gitblit instance.<br/>
Submitting a proposal does not automatically register your server with the pulling Gitblit instance.
Registration is a manual process for an administrator.
### Federation Proposals (Pulling Gitblit Instance)
@@ -91,7 +103,7 @@
### Excluding Repositories (Origin Gitblit Instance)
You may exclude a repository from being pulled by a federated Gitblit instance by setting its *federation strategy* to EXCLUDE in the repository's settings page.
You may exclude a repository from being pulled by any federated Gitblit instance by setting its *federation strategy* to EXCLUDE in the repository's settings page.
### Excluding Repositories (Pulling Gitblit Instance)
@@ -138,19 +150,19 @@
#### Origin Verification
During a federated pull operation, Gitblit does check that the *origin* of the local repository starts with the url of the federation registration.<br/>
During a federated pull operation, Gitblit does check that the *origin* of the local repository starts with the url of the federation registration.
If they do not match, the repository is skipped and this is indicated in the log.
#### User Accounts
#### User Accounts & Teams
By default all user accounts except the *admin* account are automatically pulled when using the *ALL* token or the *USERS_AND_REPOSITORIES* token.  You may exclude a user account from being pulled by a federated Gitblit instance by checking *exclude from federation* in the edit user page.
By default all user accounts and teams (except the *admin* account) are automatically pulled when using the *ALL* token or the *USERS_AND_REPOSITORIES* token.  You may exclude a user account from being pulled by a federated Gitblit instance by checking *exclude from federation* in the edit user page.
The pulling Gitblit instance will store a registration-specific `users.properties` file for the pulled user accounts and their repository permissions. This file is stored in the *federation.N.folder* folder.
The pulling Gitblit instance will store a registration-specific `users.conf` file for the pulled user accounts and their repository permissions. This file is stored in the *federation.N.folder* folder.
If you specify *federation.N.mergeAccounts=true*, then the user accounts from the origin Gitblit instance will be integrated into the `users.properties` file of your Gitblit instance and allow sign-on of those users.
If you specify *federation.N.mergeAccounts=true*, then the user accounts and team definitions from the origin Gitblit instance will be integrated into the `users.conf` file of your Gitblit instance and allow sign-on of those users.
**NOTE:**<br/>
Upgrades from older Gitblit versions will not have the *#notfederated* role assigned to the *admin* account.  Without that role, your admin account WILL be transferred with an *ALL* or *USERS_AND_REPOSITORIES* token.<br/>
**NOTE:**
Upgrades from older Gitblit versions will not have the *#notfederated* role assigned to the *admin* account.  Without that role, your admin account WILL be transferred with an *ALL* or *USERS_AND_REPOSITORIES* token.
Please consider adding the *#notfederated* role to your admin account!
#### Server Settings 
@@ -161,9 +173,17 @@
These settings are unused by the pulling Gitblit instance.
#### Push Scripts
Your Groovy push scripts are only pulled when using the *ALL* token.
The pulling Gitblit instance will retrieve any referenced (i.e. used) push script and store it locally as *registration_scriptName.groovy* in the *federation.N.folder* folder.
These scripts are unused by the pulling Gitblit instance.
### Collisions and Conflict Resolution
Gitblit does **not** detect conflict and it does **not** offer conflict resolution of repositories, users, or settings.
Gitblit does **not** detect conflict and it does **not** offer conflict resolution of repositories, users, teams, or settings.
If an object exists locally that has the same name as the remote object, it is assumed they are the same and the contents of the remote object are merged into the local object.  If you can not guarantee that this is the case, then you should not store any federated repositories directly in *git.repositoriesFolder* and you should not enable *mergeAccounts*.
@@ -171,15 +191,15 @@
## Federation Pull Registration Keys
<table class="text">
<table class="table">
<tr><th>federation.N.url</th>
<td>string</td>
<td>the url of the origin Gitblit instance *(required)*</td>
<td>the url of the origin Gitblit instance <em>(required)</em></td>
</tr>
<tr><th>federation.N.token</th>
<td>string</td>
<td>the token provided by the origin Gitblit instance *(required)*</td>
<td>the token provided by the origin Gitblit instance <em>(required)</em></td>
</tr>
<tr><th>federation.N.frequency</th>
@@ -189,42 +209,42 @@
<tr><th>federation.N.folder</th>
<td>string</td>
<td>the destination folder, relative to *git.repositoriesFolder*, for these repositories.<br/>default is *git.repositoriesFolder*</td>
<td>the destination folder, relative to <em>git.repositoriesFolder</em>, for these repositories.<br/>default is <em>git.repositoriesFolder</em></td>
</tr>
<tr><th>federation.N.bare</th>
<td>boolean</td>
<td>if **true** *(default)*, each repository is cloned as a bare repository (i.e. no working folder).</td>
<td>if <b>true</b> <em>(default)</em>, each repository is cloned as a bare repository (i.e. no working folder).</td>
</tr>
<tr><th>federation.N.mirror</th>
<td>boolean</td>
<td>if **true** *(default)*, each repository HEAD is reset to *origin/master* after each pull.  The repository is flagged *isFrozen* after the initial clone.<p>If **false**, each repository HEAD will point to the FETCH_HEAD of the initial clone from the origin until pushed to or otherwise manipulated.</td>
<td>if <b>true</b> <em>(default)</em>, each repository HEAD is reset to <em>origin/master</em> after each pull.  The repository is flagged <em>isFrozen</em> after the initial clone.<br/><br/>If <b>false</b>, each repository HEAD will point to the FETCH_HEAD of the initial clone from the origin until pushed to or otherwise manipulated.</td>
</tr>
<tr><th>federation.N.mergeAccounts</th>
<td>boolean</td>
<td>if **true**, merge the retrieved accounts into the `users.properties` of **this** Gitblit instance.<br/>*default is false*</td>
<td>if <b>true</b>, merge the retrieved accounts into the <code>users.conf</code> of <b>this</b> Gitblit instance.<br/><em>default is false</em></td>
</tr>
<tr><th>federation.N.sendStatus</th>
<td>boolean</td>
<td>if **true**, send the status of the federated pull to the origin Gitblit instance.<br/>*default is false*</td>
<td>if <b>true</b>, send the status of the federated pull to the origin Gitblit instance.<br/><em>default is false</em></td>
</tr>
<tr><th>federation.N.include</th>
<td>string array<br/>(space-delimited)</td>
<td>list of included repositories *(wildcard and fuzzy matching supported)*</td>
<td>list of included repositories <em>(wildcard and fuzzy matching supported)</em></td>
</tr>
<tr><th>federation.N.exclude</th>
<td>string array<br/>(space-delimited)</td>
<td>list of excluded repositories *(wildcard and fuzzy matching supported)*</td>
<td>list of excluded repositories <em>(wildcard and fuzzy matching supported)</em></td>
</tr>
<tr><th>federation.N.notifyOnError</th>
<td>boolean</td>
<td>if **true**, send an email to the administrators on an error.<br/>*default is false*</td>
<td>if <b>true</b>, send an email to the administrators on an error.<br/><em>default is false</em></td>
</tr>
</table>
@@ -234,11 +254,13 @@
#### (Nearly) Perfect Mirror Example
![block diagram](fed_mirror.png "Gitblit Mirror")
This assumes that the *token* is the *ALL* token from the origin gitblit instance.
The repositories, example1_users.properties, and example1_gitblit.properties will be put in *git.repositoriesFolder* and the origin user accounts will be merged into the local user accounts, including passwords and all roles.  The Gitblit instance will also send a status acknowledgment to the origin Gitblit instance at the end of the pull operation.  The status report will include the state of each repository pull (EXCLUDED, SKIPPED, NOCHANGE, PULLED, MIRRORED).  This way the origin Gitblit instance can monitor the health of its mirrors.
The repositories, example1_users.conf, example1_gitblit.propertiesn and all example1_scripts.groovy will be put in *git.repositoriesFolder* and the origin user accounts will be merged into the local user accounts, including passwords and all roles.  The Gitblit instance will also send a status acknowledgment to the origin Gitblit instance at the end of the pull operation.  The status report will include the state of each repository pull (EXCLUDED, SKIPPED, NOCHANGE, PULLED, MIRRORED).  This way the origin Gitblit instance can monitor the health of its mirrors.
This example is considered *nearly* perfect because while the origin Gitblit's server settings are pulled and saved locally, they are not merged with your server settings so its not a true mirror, but its likely the mirror you'd want to configure.
This example is considered *nearly* perfect because while the origin Gitblit's server settings & push scripts are pulled and saved locally, they are not merged with your server settings so its not a true mirror.
    federation.example1.url = https://go.gitblit.com
    federation.example1.token = 6f3b8a24bf970f17289b234284c94f43eb42f0e4
@@ -251,7 +273,7 @@
    
#### Just Repositories Example
This assumes that the *token* is the *REPOSITORIES* token from the origin gitblit instance.<br/>
This assumes that the *token* is the *REPOSITORIES* token from the origin gitblit instance.
The repositories will be put in *git.repositoriesFolder*/example2.
    federation.example2.url = https://tomcat.gitblit.com/gitblit
@@ -263,7 +285,7 @@
    
#### All-but-One Repository Example
This assumes that the *token* is the *REPOSITORIES* token from the origin gitblit instance.<br/>
This assumes that the *token* is the *REPOSITORIES* token from the origin gitblit instance.
The repositories will be put in *git.repositoriesFolder*/example3.
    federation.example3.url = https://tomcat.gitblit.com/gitblit
@@ -276,7 +298,7 @@
    
#### Just One Repository Example
This assumes that the *token* is the *REPOSITORIES* token from the origin gitblit instance.<br/>
This assumes that the *token* is the *REPOSITORIES* token from the origin gitblit instance.
The repositories will be put in *git.repositoriesFolder*/example4.
    federation.example4.url = https://tomcat.gitblit.com/gitblit
@@ -286,4 +308,25 @@
    federation.example4.bare = true
    federation.example4.mirror = true
    federation.example4.exclude = *
    federation.example4.include = somerepo.git
    federation.example4.include = somerepo.git
## Federation Client
Instead of setting up a full-blown pulling Gitblit instance, you can also use the [federation client](http://code.google.com/p/gitblit/downloads/detail?name=%FEDCLIENT%) command-line utility.  This is a packaged subset of the federation feature in a smaller, simpler command-line only tool.
The *federation client* relies on many of the same dependencies as Gitblit and will download them on first execution.
### federation.properties
You may use the `federation.properties` file to configure one or more Gitblit instances that you want to pull from.  This file is a subset of the standard `gitblit.properties` file.
By default this tool does not daemonize itself; it executes and then quits.  This allows you to use the native scheduling feature of your OS.  Of course, if you'd rather use Gitblit's scheduler you may use that by specifying the `--daemon` parameter.
### Command-Line Parameters
Instead of using `federation.properties` you may directly specify a Gitblit instance to pull from with command-line parameters.
    java -jar fedclient.jar --url https://go.gitblit.com --mirror --bare --token 123456789
         --repositoriesFolder c:/mymirror
    java -jar fedclient.jar --url https://go.gitblit.com --mirror --bare --token 123456789
         --repositoriesFolder c:/mymirror --daemon --frequency "24 hours"