16.2. Using a Git Cluster

Overview

Figure 16.1, “Git Cluster Architecture” shows an overview of the Fabric architecture when the fabric is configured to use a Git cluster.

Figure 16.1. Git Cluster Architecture

Git Cluster Architecture

Clone the Git repository

When a fabric is configured with a Git cluster, the current master behaves as a Git server. This means that you can clone the Git repository directly from the Fabric server that is the master.
Clone the Git repository using a command like the following:
$ git clone -b 1.0 http://Hostname:Port/git/fabric
Where Hostname and Port are the hostname and IP port of the master Fabric server. Note the following points:
  • The port number, Port, is usually 8181, by default. But if you deploy multiple Fabric containers on the same host, their HTTP ports are automatically incremented, 8182, 8183, (or whichever is the next available port number at the time the container is created).
  • The -b option is used to check out the 1.0 Git branch, which corresponds to version 1.0 of the Fabric profile data. There is also a master branch, but it is normally not used by the Fabric servers.
  • You can also see a sample clone command in the Fuse Management Console, if you navigate to the Container: page for the relevant container, click on the URLs tag, and go to the Git: field. Note, however, that if you try to clone from a slave instance, you will get an error (the Fuse Management Console currently does not indicate whether the container is a slave or a master).
Important
Do not attempt to clone your repository directly from the InstallDir/data/git/local/fabric directory (which holds the container's local Git repository). This approach does not work. When you push and pull to the container's HTTP port, it automatically triggers synchronization events within the Git cluster. These necessary synchronizations would be bypassed, if you cloned from a directory.

Authentication

The Git server exposed by the Fabric is deployed into the container's Jetty container and shares the same security configuration as other default HTTP services. In particular, the HTTP port is configured to request credentials through the HTTP BASIC authentication protocol, and these credentials are then authenticated in the container using the standard JAAS authentication infrastructure. In practice, this means you can use any of the JAAS credentials configured in the fabric to log on to the Git server.
You can use one of the following alternatives to specify the credentials for Git:
  • Let Git prompt you for credentials—this is the default, if you use a Git URL of the form, http://Hostname:Port/git/fabric.
  • Embed credentials in the Git URL—you can embed the credentials directly in the Git URL, using the following syntax:
    http://User:Pass@Hostname:Port/git/fabric

Basic tasks with Git

You can now use standard Git commands to perform basic configuration tasks in Fabric:
  • Push to the Fabric Git server—you can use your local Git repository to edit profile configurations and push the changes up to the fabric. For example, to edit the Camel route in the quickstarts-beginner-camel.log.wiki profile:
    1. Make sure that you are working in the correct branch (initially, this should be branch 1.0):
      $ cd LocalGitRepo
      $ git checkout 1.0
    2. Edit the following Blueprint XML file in your local Git repository, to alter the Camel route:
      LocalGitRepo/fabric/profiles/quickstarts/beginner/camel.log.wiki.profile/camel-log.xml
    3. Add and commit the changes locally, using Git commands:
      $ git add -u
      $ git commit -m "Changed the route in camel.log.wiki"
    4. Push the changes to the fabric:
      $ git push
      This updates the configuration in all of the Fabric servers in the Git cluster. If any of the containers in your fabric have deployed the quickstarts-beginner-camel.log.wiki profile, they will immediately be updated with the changes.
  • Pull from the Fabric Git server—if you change the profile configuration using commands in the Karaf console, you can synchronize those changes with your local Git repository by doing a git pull. For example, to edit the Camel route in the quickstarts-beginner-camel.log.wiki profile from the Karaf console:
    1. In the Karaf console, you can edit the Camel route from the quickstarts-beginner-camel.log.wiki profile by entering the following console command:
      fabric:profile-edit --resource camel-log.xml quickstarts-beginner-camel.log.wiki
    2. You can now synchronize your local Git repository to these changes. Open a command prompt, and enter the following commands:
      $ cd LocalGitRepo
      $ git checkout 1.0
    3. Pull the changes from the fabric:
      $ git pull

What happens after a failover?

So far, we have been assuming that the master instance remains unchanged, so that the master instance is synonymous with the origin upstream repository. But what happens if there is a failover? For example, if the Fabric server that is the master instance is stopped and restarted. If your ensemble consists of only one Fabric server, this makes no difference, because there is no other server to fail over to. But if there are three (or five) servers in your ensemble, one of the other Fabric servers will automatically be elected as the new master.
The consequence for your local Git repository is that the origin repository is no longer the master instance. Hence, if you try to do a git push or a git pull after failover, you will get the following error:
$ git pull
fatal: repository 'http://Hostname:8181/git/fabric/' not found

Adding multiple upstream repositories

Currently, there is no mechanism in Git for failing over automatically to an alternative Git server. But what you can do in Git is to add multiple upstream repositories. It then becomes possible to push to and pull from alternative Git repositories, as long as you name them explicitly in the command line.
For example, consider the case where there are two additional Fabric servers in a Git cluster (making three in total). You can add the two additional servers as upstream repositories, using the following Git commands:
$ git remote add ensemble2 Ensemble2GitURL
$ git remote add ensemble3 Ensemble3GitURL
You can then push to either of these repositories explicitly, using a command of the form:
$ git push UpstreamName BranchName
For example, to push to branch 1.0 of the ensemble2 Git server:
$ git push ensemble2 1.0
Only one of the repositories, origin, ensemble2, ensemble3, is accessible at one time, however (whichever is the master).

Git cluster tutorial

The following tutorial explains how to create a fabric, which demonstrates a master-slave cluster of Git repositories:
  1. (Optional) Prepare the container for a cold start. Delete the following directories:
    InstallDir/data
    InstallDir/instances
    Important
    Performing a cold start completely wipes the current state of the root container, including all of the deployed bundles, and features, and most of the stored data. Do not perform this operation on a production system.
  2. Start up the container, by entering the following command:
    ./bin/fuse
  3. Create a new fabric. At the container prompt, enter the following console command:
    fabric:create --new-user admin --new-user-password AdminPass --new-user-role Administrator \
      --zookeeper-password ZooPass --global-resolver manualip \
      --resolver manualip --manual-ip 127.0.0.1 --wait-for-provisioning
    You need to substitute your own values for AdminPass and ZooPass. This sample command uses the --manual-ip option to assign the loopback address, 127.0.0.1, to the root container. If your host has a static IP address and hostname assigned to it, however, it would be better to use the assigned hostname here instead.
    You need to wait a minute or two for this command to complete.
  4. Create two new child containers in the fabric, by entering the following console command:
    fabric:container-create-child --profile fabric root ensemble 2
    This command returns quickly, with the following message:
    The following containers have been created successfully:
    	Container: ensemble.
    	Container: ensemble2.
    But it takes a couple of more minutes for the new child containers to be completely provisioned. Check the status of the child containers, by entering the following command:
    fabric:container-list
    Wait until the child containers have a [provision status] of success before proceeding.
  5. Add the two child containers to the Fabric ensemble, so that the Fabric ensemble consists of three containers in all: root, ensemble, and ensemble2. Enter the following console command:
    fabric:ensemble-add ensemble ensemble2
    Wait until the ensemble containers have been successfully provisioned before proceeding.
  6. Clone the Git repository. The three containers in the Fabric ensemble now constitute a Git cluster. Initially, the root container is the master instance of the cluster, so you should attempt to clone the Git repository from the HTTP port exposed by the root container.
    Open a new command prompt and, at a convenient location in the file system, enter the following command:
    git clone -b 1.0 http://127.0.0.1:8181/git/fabric
    This command clones the Fabric Git repository and checks out the 1.0 branch. You should now be able to see the profile configuration files under the fabric/profiles subdirectory.
    If the root container is not the current master, you can expect to see an error message like the following when you attempt to clone:
    Cloning into 'fabric'...
    fatal: repository 'http://127.0.0.1:8181/git/fabric/' not found
  7. In the next few steps, we explore the failover behaviour of the Git cluster. First of all, we stop the root container (the current Git master), in order to force a failover. In the root container console, enter the shutdown command, as follows:
    JBossFuse:karaf@root> shutdown
    Confirm: shutdown instance root (yes/no): yes
  8. Now restart the root container, by entering the following command:
    ./bin/fuse
  9. Return to the command prompt where you cloned the Git repository and try to do a git pull, as follows:
    cd fabric
    git pull
    You will get an error like the following:
    $ git pull
    fatal: repository 'http://127.0.0.1:8181/git/fabric/' not found
    Because the root container (listening on IP port 8181) is no longer the master.
    Note
    In this example, because all of the ensemble containers are running on the same host, the ensemble containers are distinguished by having different IP port numbers (8181, 8182, and 8183). If you created the other ensemble containers on separate hosts, however, they would all have the same port number (8181), but different host names.
  10. One of the other Fabric servers (ensemble or ensemble2) is now the master. To gain access to the master, try adding both of the alternative Git URLs as upstream repositories. From a directory in the cloned Git repository, enter the following commands:
    $ git remote add ensemble http://127.0.0.1:8182/git/fabric
    $ git remote add ensemble2 http://127.0.0.1:8183/git/fabric
  11. You can now try pulling from one of the other Fabric servers. You can either pull from the ensemble container (pulling branch 1.0), as follows:
    $ git pull ensemble 1.0
    Or from the ensemble2 container (pulling branch 1.0), as follows:
    $ git pull ensemble2 1.0
    Only one of these alternatives can succeed (pulling from the master). Pulling from the slave instance returns an error.
  12. After you have identified the current master, you can proceed to push and pull using the long form of the git commands (for example, git pull RemoteName BranchName).