14.2. Using a Git Cluster
Overview
Figure 14.1, “Git Cluster Architecture” shows an overview of the Fabric architecture when the fabric is configured to use a Git cluster.
Figure 14.1. 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 usually8181
, 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 the1.0
Git branch, which corresponds to version 1.0 of the Fabric profile data. There is also amaster
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
example-camel-twitter
profile:- Make sure that you are working in the correct branch (initially, this should be branch
1.0
):$ cd LocalGitRepo $ git checkout 1.0
- Edit the following Blueprint XML file in your local Git repository, to alter the Camel route:
LocalGitRepo/fabric/profiles/example/camel/twitter.profile/camel.xml
- Add and commit the changes locally, using Git commands:
$ git add -u $ git commit -m "Changed the route in example-camel-twitter"
- 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 theexample-camel-twitter
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 theexample-camel-twitter
profile from the Karaf console:- In the Karaf console, you can edit the Camel route from the
example-camel-twitter
profile by entering the following console command:fabric:profile-edit --resource camel.xml example-camel-twitter
- 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
- 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 Ensemble2GitURL
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:
- (Optional) Prepare the container for a cold start. Delete the following directories:
InstallDir/data InstallDir/instances
WarningPerforming 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. - Start up the container, by entering the following command:
./bin/fuse
- 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 forAdminPass
andZooPass
. 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. - 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]
ofsuccess
before proceeding. - Add the two child containers to the Fabric ensemble, so that the Fabric ensemble consists of three containers in all:
root
,ensemble
, andensemble2
. Enter the following console command:fabric:ensemble-add ensemble ensemble2
Wait until the ensemble containers have been successfully provisioned before proceeding. - 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 theroot
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 the1.0
branch. You should now be able to see the profile configuration files under thefabric/profiles
subdirectory.If theroot
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
- 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 theshutdown
command, as follows:JBossA-MQ:karaf@root> shutdown Confirm: shutdown instance root (yes/no): yes
- Now restart the root container, by entering the following command:
./bin/fuse
- 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.NoteIn 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. - One of the other Fabric servers (
ensemble
orensemble2
) 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
- You can now try pulling from one of the other Fabric servers. You can either pull from the
ensemble
container (pulling branch1.0
), as follows:$ git pull ensemble 1.0
Or from theensemble2
container (pulling branch1.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. - 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
).