需求

  假如现在想对使用到的一些Github上的开源组件进行备份,采用自建Gitlab服务器的方式进行备份保存,并且组件需定时保持与Github更新。

总体步骤

组件备份- 整体步骤如下:
    a.搭建gitlab服务器,参考CentOS7 搭建gitlab服务器 
    b.登录账户,创建一个group,如kdv-opensource(方便统一管理,不创建也一样)
    c.在kdv-opensource组里需创建相应的repo(名字与Github上repo的名字一致)
    d.脚本执行git clone & git pull,拉取相应的项目
    e.修改对应的repo的配置文件,.git/config,增加push url(gitlab repo地址)
        git@ip:opensource/{}.git
    f.推送到gitlab服务器上
        git push -u origin --all
        git push -u origin --tags
    g.python脚本加入crontab定期执行即可

搭建Gitlab服务器

  如前所述,略。

创建group

  登录账户,菜单栏选择Groups,右侧New group,填写组名即描述信息即可。如创建一个kdv-opensource组:

创建项目repo

   需要在kdv-opensource组内创建好所有要备份组件项目,且名字需与Github上开源项目名字保持一致(为了方便)如下:

脚本功能

   我们使用python实现一个脚本从Github上克隆(git clone)相应的项目和拉取更新(git pull)。

   python可以直接调用系统命令,使用os.system(command),即可执行相应的命令。当然,操作系统需预先安装git及一些软件才能使用。

修改配置文件

   前面一步的git clone & git pull下载好相应的github repo,需导入到我们自建的Gitlab服务器中,这样就需要修改推送的git 地址,即pushurl,仅需修改git项目下相应的配置文件。

# cat .git/config 
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true

[remote "origin"]
url = https://github.com/openssl/openssl.git
fetch = +refs/heads/*:refs/remotes/origin/*
pushurl = git@ip:kdv-opensource/openssl.git     # 增加此行,通过脚本自动增加

[branch "master"]
    remote = origin
    merge = refs/heads/master

  ip为gitlab服务的相应ip地址。

推送到gitlab服务器上

  我们知道,如果要进行push操作是需要进行鉴权的,也即需要输入账户密码,而在脚本执行过程中无法一一手工输入密码。有两种方法可以解决这个问题:

方法一

  在pushurl地址中指定username:password,如下:

pushurl = 'http://username:password@ip:port/kdv-opensource/{repo}.git'

方法二

  通过SSH登录,更为方便和安全,也是现在比较流行的方式。

   导入本机生成的ssh公钥即可,公钥可通过ssh-keygen生成(默认即可),因此需要先安装SSH。

  这样,在脚本执行过程中就能自动地向gitlab服务器上推送repo内容。

定期更新

   在linux下可将脚本加入到crontab列表,使之定期自动执行即可。

实现脚本 

组件列表sample

  文件以“项目名,github地址”的格式填入list.txt文件即可。

haproxy,https://github.com/haproxy/haproxy.git
libevent,https://github.com/libevent/libevent.git
openresty,https://github.com/openresty/openresty.git

python脚本

#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import os
from configparser import ConfigParser

dicts = {}
failed = []
#giturl = 'http://username:password@ip:port/kdv-opensource/{}.git'      # giturl需指定自建的gitlab服务器ip:port
giturl = 'git@ip:kdv-opensource/{}.git'


def read_conf(name):
    config = ConfigParser()
    config.read('.git/config')
    print(config.sections())                            # 查看有哪些sections
    value = config.get('remote "origin"', 'url')        # 读取相应的字段
    print(value)
    pushurl = giturl.format(name)
    print(pushurl)
    config.set('remote "origin"', 'pushurl', pushurl)
    config.write(open('.git/config', 'w'))


def add_pushurl(name):
    print('handle pushurl....')
    read_conf(name)
    command1 = 'git push -u origin --all'       # 推送所有文件
    command2 = 'git push -u origin --tags'      # 推送tags
    try:
        os.system(command1)
    except:
        failed.append('push all exception')

    try:
        os.system(command2)
    except:
        failed.append('push tags exception')


if __name__ == '__main__':
    # 读取列表
    # 处理成name,url的形式,加入到dicts中
    with open('./list.txt', 'r') as fr:
        for line in fr:
            if line.strip():
                line = line.strip()
                name, url = line.split(',')            # 逗号分隔的组件名和组件URL
                dicts[name.strip()] = url.strip()

    num = len(dicts)
    path = os.getcwd()                    # 获取当前路径
    print(path)
    files = os.listdir(path)              # 获取当前路径下的所有文件
    print(files)
    index = 0
    for name, url in dicts.items():            # 组件名字&github repo的url地址
        index += 1
        msg = '[{}/{}] - {}'.format(index, num, name)
        print(msg)
        files_l = [line.lower() for line in files]
        if name.lower() in files_l:                    # 如果是已有的repo,git pull更新即可
            os.chdir(name)
            try:
                print('-----------------------------------')
                command = 'git pull'
                print(command)
                msg = os.system(command)
                print('\n')
            except:
                failed.append(name)
                continue
            add_pushurl(name)
            os.chdir('..')
        else:                                    # 如果是新加入的组件,需要先git clone下来
            try:
                command = 'git clone {}'.format(url)
                print(command)
                print('-----------------------------------')
                msg = os.system(command)
                os.chdir(name)
                add_pushurl(name)                
                os.chdir('..')
                print('\n')
            except:
                failed.append(name)
                continue

    if len(failed) == 0:
        print("All succeed!")
    else:
        msg = "There are {} failed:{}".format(len(failed), failed)
    pass

效果图

  再补两张效果图吧,如备份的组件zookeeper,项目文件 ==> 

    提交记录 ==> 

Question  

  在push过程中,如果有文件出现错误:"zeroPaddedFilemode: contains zero-padded file modes",可参考如下文章。

  Pushing fails if local repo has problems with zero-padded file modes

  Zero-padded file modes in repository

  remote: fatal: fsck error in packed object when pushing oh-my-zsh repo to new remote

  不过好像对我不起作用,什么.git/config和~/.gitconfig文件都改烂了,还是不行。难受...

  方法:修改配置文件

# vim  /etc/gitlab/gitlab.rb
...
omnibus_gitconfig['system'] = {
  'fsck' => ['zeroPaddedFilemode = ignore'],     # 这个是上面某个链接里说的方法,但不起作用,于是试了下-下面那行
  "receive" => ["fsckObjects = false"],
}
重新配置:
  gitlab-ctl reconfigure
重启服务:
  gitlab-ctl restart

  不知道是不是人品问题啊... 就这样!

转载于:https://www.cnblogs.com/Hi-blog/p/How-To-Backup-Github-Repo-And-Update.html

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐