如何使用 Ansible 同步 GitHub 和 GitLab

经过使用 Ansible 镜像 Git 存储库,保护对重要项目的访问。html

开源无处不在。它在家里的计算机上、在工做场所的计算机上、在互联网上,而且不少都由 Git 管理。因为 Git 是分布式的,所以许多人也将其视为一种众包的备份解决方案。从理论上讲,每当有人将 Git 存储库克隆到其本地计算机时,他们就建立了该项目源代码的备份。若是有 100 我的这样作,则存储库就有 100 个备份副本。linux

从理论上讲,这能够缓解“灾难”的影响,例如当项目维护者忽然决定删除存储库莫名其妙地阻止全部流量,致使开发人员们无头苍蝇般地寻找谁拥有主分支的最新版本。相似的,整个代码托管站点也会消失。没有人会想到 Google Code、Microsoft CodePlex 或 Gitorious 会在鼎盛时期将被关闭。git

简而言之,若是在过去的几十年中互联网教给了咱们一些东西,那就是依靠互联网神奇地建立备份并非冗余的最可靠途径。github

此外,对于许多人来讲,不少开源项目都托管在 GitHub 上是个问题 —— GitHub 并非开放平台。许多开发人员和用户都但愿支持诸如 GitLab 之类的堆栈并与之交互,它具备开源社区版本。shell

使用 Ansible 管理 Git

Git 的去中心方式对于解决这个问题颇有用。使用纯 Git,你可使用一个 push 命令轻松地将其推到两个或多个存储库。可是,为了使其在发生意外故障时有用,你必须常常与 Git 存储库进行交互(特别是推送)。此外,即便你可能永远不会本身推送或拉出代码,也可能有一些要备份的存储库。安全

可是,使用 Ansible,你能够自动执行项目主分支(或其余任何分支)的 Git 拉取,而后自动进行存储库到“异地”镜像的 Git 推送。换句话说,你可让你的计算机按期从 GitHub 拉取并推送到 GitLab 或 Gitolite 或 Gitea(或你喜欢的任何 Git 托管主机)。ruby

Ansible 模块

若是不是因其出色的模块集合,那么 Ansible 就没那么出色。像 Python 的第三方库或 Linux 的应用程序同样,这个技术引擎的一个有用而使人惊讶的简单技巧是,Ansible 以其余人贡献的组件而闻名。由于本文正在研究如何有效和可靠地备份 Git 存储库,因此这里使用的模块是 Git 模块ini_file 模块。bash

首先,建立一个名为 mirror.yaml 的文件做为剧本playbook。你能够像一般使用 Ansible 同样,从 nametask 条目开始。本示例将 localhost 添加到 hosts 列表中,以便在控制器计算机(你如今坐在前面的计算机)上运行动做play,可是在现实生活中,你可能会在特定的主机或一组网络上的主机上运行它。服务器

---
- name: "Mirror a Git repo with Ansible"
  hosts: localhost
  tasks:
复制代码

Git 拉取和克隆

若是要进行备份,则须要最新代码的副本。明显,在 Git 仓库中实现这一目标的方法是执行 git pull。 可是,pull 会假定克隆已经存在,而写得很好的 Ansible 动做(Ansible 脚本)则尽量少的假定。最好告诉 Ansible 先克隆存储库。网络

将你的第一个任务添加到剧本:

---
- name: "Mirror a Git repo with Ansible"
  hosts: localhost
  vars:
    git_dir: /tmp/soso.git
  tasks:

  - name: "Clone the git repo"
    git:
       repo: 'https://github.com/ozkl/soso.git'
       dest: '{{ git_dir }}'
       clone: yes
       update: yes
复制代码

这个例子使用了开源的、相似于 Unix 的操做系统 soso 做为我要镜像的存储库。这是一个彻底任意的选择,毫不意味着我对该存储库的将来缺少信心。它还使用变量来引用目标文件夹 /tmp/soso.git,这很方便,而且若是之后你但愿将它扩展为一个通用的镜像脚本也会受益。在现实生活中,你的工做机上可能会比 /tmp 具备更永久的位置,例如 /home/gitmirrors/soso.git/opt/gitmirrors/soso.git

运行你的剧本:

$ ansible-playbook mirror.yaml
复制代码

首次运行该剧本时,Ansible 会正确检测到 Git 存储库在本地尚不存在,所以将其克隆。

PLAY [Ansible Git mirror] ********

TASK [Gathering Facts] ***********
ok: [localhost]

TASK [Clone git repo] ************
changed: [localhost]

PLAY RECAP ***********************
localhost: ok=2 changed=1 failed=0 [...]
复制代码

若是你再次运行该剧本,Ansible 会正确检测到自上次运行以来没有任何更改,而且会报告未执行任何操做:

localhost: ok=2 changed=0 failed=0 [...]
复制代码

接下来,必须指示 Ansible 将存储库推送到另外一个 Git 服务器。

Git 推送

Ansible 中的 Git 模块不提供 push 功能,所以该过程的一部分是手动的。可是,在将存储库推送到备用镜像以前,你必须具备一个镜像,而且必须将镜像配置为备用远程服务器remote

首先,必须将备用的远程服务器添加到 Git 配置。由于 Git 配置文件是 INI 样式的配置,因此你可使用 ini_file Ansible 模块轻松地添加所需的信息。将此添加到你的剧本:

- name: "Add alternate remote"
    ini_file: dest={{ git_dir }}/.git/config section='remote \"mirrored\"' option=url value='git@gitlab.com:example/soso-mirror.git'
    tags: configuration
复制代码

为此,你必须在目标服务器上有一个空的存储库(在本例中为 GitLab.com)。若是须要在剧本中建立目标存储库,能够按照 Steve Ovens 的出色文章《如何使用 Ansible 经过 SSH 设置 Git 服务器》来完成。

最后,直接使用 Git 将 HEAD 推送到备用远程服务器:

- name: "Push the repo to alternate remote"
    shell: 'git --verbose --git-dir={{ git_dir }}/.git push mirrored HEAD'
复制代码

像往常同样运行该剧本,而后使该过程自动化,这样你就没必要再次直接运行它了。你可使用变量和特定的 Git 命令来调整脚本以适应你的需求,可是经过常规的拉取和推送操做,能够确保驻留在一台服务器上的重要项目能够安全地镜像到另外一台服务器上。

这是完整的剧本,供参考:

---
- name: "Mirror a Git repository with Ansible"
  hosts: localhost
  vars:
    git_dir: /tmp/soso.git

  tasks:

  - name: "Clone the Git repo"
    git:
       repo: 'https://github.com/ozkl/soso.git'
       dest: '{{ git_dir }}'
       clone: yes
       update: yes

  - name: "Add alternate remote"
    ini_file: dest={{ git_dir }}/.git/config section='remote \"mirrored\"' option=url value='git@gitlab.com:example/soso-mirror.git'
    tags: configuration
 
  - name: "Push the repo to alternate remote"
    shell: 'git --verbose --git-dir={{ git_dir }}/.git push mirrored HEAD'
复制代码

via: opensource.com/article/19/…

做者:Seth Kenlon 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关文章
相关标签/搜索