Open supply is in all places. It’s in your pc at house, it is in your pc at work, it is on the web, and quite a lot of it’s managed with Git. Because Git is decentralized, many individuals additionally consider it as a form of crowdsourced backup resolution. The principle is that every time somebody clones a Git repository to their native pc, they’re making a backup of the mission’s supply code. If 100 individuals do this, then there are 100 backup copies of a repository.
This, in principle, mitigates “disasters” corresponding to a mission maintainer suddenly deciding to remove a repository or inexplicably blocking all traffic and leaving builders scrambling to determine who has the most recent model of the grasp department. Similarly, complete code-hosting websites have disappeared up to now. Nobody anticipated the closure of Google Code, Microsoft CodePlex, or Gitorious once they had been at their peak.
In quick, if the web has taught us something over the previous few a long time, it is that relying on the web to magically create backups is not essentially the most dependable highway to redundancy.
Besides, it is an issue for lots of people that many open supply tasks are hosted on GitHub, which isn’t an open platform. Many builders and customers would like to help and work together with a stack corresponding to GitLab, which has an open supply neighborhood version.
Using Ansible for Git
Git’s decentralization is beneficial in fixing this downside. Using pure Git, you possibly can simply push to 2 or extra repositories with a single push command. However, for that to be helpful towards sudden failure, you should be interacting (and pushing, particularly) with a Git repository regularly. Furthermore, there could also be repositories on the market that you simply need to again up, though you could by no means push or pull the code your self.
But utilizing Ansible, you possibly can automate Git pulls of a mission’s grasp department (or every other department, for that matter) after which automate Git pushes of the repository to an “offsite” mirror. In different phrases, you possibly can have your pc commonly pull from GitHub and push to GitLab or Gitolite or Gitea (or no matter Git host you favor).
Ansible modules
There would not be a lot to Ansible if it weren’t for its wonderful assortment of modules. Like third-party libraries for Python or functions for Linux, the technical driver of the helpful and surprisingly simple methods Ansible is known for are the components that different individuals have already discovered for you. Because this text is tackling learn how to successfully and reliably backup a Git repository, the modules used listed here are the Git module and the ini_file module.
To start, create a file known as mirror.yaml to function the playbook. You can begin largely as you often do with Ansible, with identify and job entries. This instance provides localhost to the hosts record in order that the play runs on the controller machine (the pc you are sitting at proper now), however in actual life, you’d in all probability run this on a particular host or group of hosts in your community.
---
- identify: "Mirror a Git repo with Ansible"
hosts: localhost
duties:
Git pull and clone
If you are going to make a backup, then you definately want a replica of the most recent code. The apparent option to make that occur with a Git repository is to carry out a git pull. However, pull assumes clone already exists, and a well-written Ansible play (an Ansible script) assumes as little as attainable. It’s higher to inform Ansible to clone a repository first.
Add your first job to your playbook:
---
- identify: "Mirror a Git repo with Ansible"
hosts: localhost
vars:
git_dir: /tmp/soso.git
duties:
- identify: "Clone the git repo"
git:
repo: 'https://github.com/ozkl/soso.git'
dest: ''
clone: sure
replace: sure
This instance makes use of the open supply, Unix-like working system soso because the repository I need to mirror. This is a totally arbitrary alternative and on no account implies a insecurity on this repository’s future. It additionally makes use of a variable to seek advice from the vacation spot folder, /tmp/soso.git, which is handy now and likewise helpful later must you need to scale this out to be a generic mirroring script. In actual life, you’d in all probability have a extra everlasting location than /tmp, corresponding to /house/gitmirrors/soso.git or /decide/gitmirrors/soso.git, in your employee machine.
Run your playbook:
$ ansible-playbook mirror.yaml
The first time you run the playbook, Ansible appropriately detects that the Git repository doesn’t but exist regionally, so it clones it.
PLAY [Ansible Git mirror] ********TASK [Gathering Facts] ***********
okay: [localhost]TASK [Clone git repo] ************
modified: [localhost]PLAY RECAP ***********************
localhost: okay=2 modified=1 failed=zero [...]
Should you run the playbook once more, Ansible appropriately detects that there have been no modifications for the reason that final time it was run and it experiences that no actions had been carried out:
localhost: okay=2 modified=zero failed=zero [...]
Next, Ansible should be instructed to push the repository to a different Git server.
Git push
The Git module in Ansible does not present a push operate, in order that a part of the method is handbook. However, earlier than you possibly can push the repo to an alternate mirror, it’s a must to have a mirror, and it’s a must to configure the mirror as an alternate distant.
First, you need to add an alternate distant to your Git configuration. Because the Git config file is an INI-style configuration, you should utilize the ini_file Ansible module to append the required info simply. Add this to your playbook:
- identify: "Add alternate remote"
ini_file: dest=/.git/config part='distant "mirrored"' possibility=url worth='[email protected]:instance/soso-mirror.git'
tags: configuration
For this to work, you need to have an empty repository in your vacation spot server (on this case, GitLab.com). If you could create vacation spot repositories in your playbook, you are able to do that by following Steve Ovens’ wonderful article “How to use Ansible to set up a Git server over SSH.”
Finally, use Git on to push HEAD to your alternate distant:
- identify: "Push the repo to alternate remote"
shell: 'git --verbose --git-dir=/.git push mirrored HEAD'
Run the playbook as traditional, after which automate the method so that you simply by no means must run it immediately once more. You can regulate the script with variables and particular Git instructions to fit your wants, however with common pulls and pushes, you possibly can make sure that an vital mission that lives on one server is safely mirrored on one other.
Here is the complete playbook for reference:
---
- identify: "Mirror a Git repository with Ansible"
hosts: localhost
vars:
git_dir: /tmp/soso.git
duties:
- identify: "Clone the Git repo"
git:
repo: 'https://github.com/ozkl/soso.git'
dest: ''
clone: sure
replace: sure
- identify: "Add alternate remote"
ini_file: dest=/.git/config part='distant "mirrored"' possibility=url worth='[email protected]:instance/soso-mirror.git'
tags: configuration
- identify: "Push the repo to alternate remote"
shell: 'git --verbose --git-dir=/.git push mirrored HEAD'