如何實現Git服務間同步

很久沒寫博客了,雖然也沒寫幾篇^_^...露個臉,表示還活躍在互聯網行業中...不說沒用的了,分享一下如何實現Git服務間的同步。
Git服務咱們通常多會使用gitlab-rake工具定時作備份,當出現問題時利用備份恢復,那是否有一種需求是另一個環境也須要部署一套Git服務,且須要和前一套Git服務去同步的,即便作冷備,既省去了恢復時間,也達到了定時作恢復演練的目的。
目前咱們另一個環境就遇到了這樣的需求,固然能夠研究學習Git API去實現,但因爲目前需求對同步實時性要求不高,因而我準備用一個直接簡單粗暴的方式來實現,其實就是拿Git備份去另一套環境作自動恢復,交互問題咱們交給expect工具來解決。
下面分別分享下Python和Shell腳本做爲參考學習,同步時間則能夠調整定時備份的時間及恢復時間便可,內容大同小異,思路基本一致:python

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import pexpect
import paramiko

# 備份服務器的IP地址、用戶名
git_src_host = "xxx.xxx.xxx.xxx"
git_src_user = "xxx"
git_src_port = "22"
# 地址自行根據環境變動
private_key  = paramiko.RSAKey.from_private_key_file('/xxx/xxx/xxx/.ssh/id_rsa')

git_bak_dir  = "/var/opt/gitlab/backups"

# Copy backup to xxx.xxx.xxx.xxx(查找備份服務器一天之內的備份傳到恢復服務器所在備份目錄)

try:
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(
        hostname=git_src_host,
        username=git_src_user,
        port=git_src_port,
        password=private_key)

    cmd=("find " + git_bak_dir + " -type f -ctime -1")
    stdin, stdout, stderr = ssh.exec_command(cmd)

    for item in stdout.readlines():
        chown_cmd="chown git:git " + git_bak_dir + "/*;chmod 700 " + git_bak_dir
        rsync_cmd=('rsync -avzP '
                    + git_src_user + '@'
                    + git_src_host + ':'
                    + item.strip('\n') + ' '
                    + git_bak_dir)

        #print(rsync_cmd)
        os.system(rsync_cmd)
        os.system(chown_cmd)

    ssh.close()
except Exception, e:
    print e

# Restore backup

ls_cmd="ls -t " + git_bak_dir + " | \
        head -n 1 | \
        sed -r 's/^([0-9]+_[0-9]+_[0-9]+_[0-9]+_.*)_gitlab_backup.tar/\\1/g'"

rs=os.popen(ls_cmd)
restore_file=rs.read()
# print(restore_file)

os.system("gitlab-ctl stop unicorn;gitlab-ctl stop sidekiq")

expectations=["Do you want to continue (yes/no)?","Do you want to continue (yes/no)?",]
child = pexpect.spawn('gitlab-rake gitlab:backup:restore BACKUP=' + restore_file,timeout=1800)
child.logfile = sys.stdout
while True:
    try:
        i = child.expect(expectations)
        if i == 0:
            child.sendline('yes')
        elif i == 1:
            child.sendline('yes')
    except pexpect.EOF:
        print('Exiting fexpect for EOF.')
        break

os.system("gitlab-ctl restart")
#!/bin/bash
#

git_src_host="xxx.xxx.xxx.xxx"
git_src_user="xxx"

git_bak_dir="/var/opt/gitlab/backups"
git_bak_file=`ssh ${git_src_user}@${git_src_host} "find ${git_bak_dir} -type f -ctime -1"`

# Copy backup to xxx.xxx.xxx.xxx

for bakfiles in $git_bak_file ; do

    echo "------------------------------------"
    rsync -avzP ${git_src_user}@${git_src_host}:${bakfiles} ${git_bak_dir}
    echo $bakfiles
    echo "------------------------------------"

done

chown git:root $git_bak_dir
chmod 700 $git_bak_dir

# Restore backup

restore_file=`ls -t $git_bak_dir | head -n 1 | sed -r 's/^([0-9]+_[0-9]+_[0-9]+_[0-9]+_.*)_gitlab_backup.tar/\1/g'`

gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq

/bin/expect <<EOF
set time 30
spawn gitlab-rake gitlab:backup:restore BACKUP=$restore_file
expect "Do you want to continue (yes/no)?" { 
    send "yes\r";
}
expect "Do you want to continue (yes/no)?" { 
    send "yes\r";
}
expect "Do you want to continue (yes/no)?" { 
    send "yes\r";
}
expect "Do you want to continue (yes/no)?" { 
    send "yes\r";
}
expect "Do you want to continue (yes/no)?" { 
    send "yes\r";
}
expect eof
EOF

#gitlab-ctl reconfigure
gitlab-ctl restart
相關文章
相關標籤/搜索