如何使用 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中國 榮譽推出

相關文章
相關標籤/搜索