美文网首页Android
搭建安卓源码服务器,repo+gerrit+git环境,代码审核

搭建安卓源码服务器,repo+gerrit+git环境,代码审核

作者: DD_Dog | 来源:发表于2018-08-04 10:22 被阅读158次

    安装ubuntu-14.04.5-server-amd64

    我司使用的是Dell服务器,做好启动U盘,使用工具rufus-usb。
    Dell服务器的界面与普通PC不同,不过基本原理是一样的,BIOS设置为UEFI。
    开机时按F11,进入BootManager,选择启动项,其中有启动U盘的启动项,确认后即可开始安装。
    为方便使用,安装的语言选择为中文。
    分区使用了整个磁盘,将原来的系统删除。

    安装gitolite服务器

    Gitolite介绍

    Gittolite是基于git搭建一个中央代码服务器,有以下特点:

    • 支持多个用户,多个仓库
    • 支持多个层次的权限控制,支持到仓库的branch和tag的权限访问
    • ssh安全访问协议
    • 不需要http服务器等其他依赖,更少的资源占用
    • 简单、灵活的管理

    Gitolite安装成功后会创建一个名为gitolite-admin的特殊仓库,这个仓库里面管理着Gitolite的配置文件,在这些配置文件中可以添加删除用户、仓库,也可以定义一些权限控制规则。

    认证与授权

    Gitolite不做认证(authentication),只做授权(authorisation)。

    • 认证(authentication)。由ssh服务来认证访问账号的合法性。
    • 授权(authorisation)。授予某个账号的访问权限。

    Gitolite安装和启动

    Gitolite是管理Git的仓库,所以必须要安装Git。

    安装Gitolite

    1. 切换到git用户账号:su – git
    2. 安装SSH,一般来说服务器上都已经安装SSH了
    3. 获取Gitolite代码,git clone git://github.com/sitaramc/gitolite
    4. 创建Gitolite安装目录。mkdir -p ~/bin
    5. 开始安装。gitolite/install -to ~/bin
    6. 添加管理员公钥。这个管理员公钥就是对应着拥有管理代码仓库的权限,非常重要。把自己的公钥admin.pub上传到服务器,添加到Gitolite中。gitolite setup -pk admin.pub

    管理Gitolite

    管理Gitolite也很简单,它是通过一个Git仓库来管理的。安装好Gitolite后,会默认生成一个gitolite-admin的仓库。管理员可以把这个仓库clone到本地:

    git clone git@host:gitolite-admin
    git clone git@host:gitolite-admin
    这个仓库有两个目录:
    keydir,存放用户认证的公钥文件目录
    conf,存放Gitolite配置的文件的目录
    gitolite.conf,gitolite配置文件
    

    用户

    添加用户本质是把该用户的公钥文件添加到gitolite-admin仓库中。比如想添加一个用户foo:
    把foo的公钥文件重命名为foo.pub
    把foo.pub文件放到gitolite-admin/keydir目录中,并提交到远程仓库
    删除用户也类似,只不过把该用户的的公钥文件移出gitolite-admin仓库。
    有时候一个用户有多个公钥文件。这种情况下,就需要把这些同名的公钥文件放到keydir不同的子目录下。比如foo用户的多个公钥文件如下放置:

    keydir/home/foo.pub
    keydir/laptop/foo.pub
    keydir/desktop/foo.pub
    

    只要这些公钥都是命名为foo.pub,在不同的目录下不冲突。

    仓库

    添加仓库
    添加一个仓库很简单,编辑gitolite-admin仓库里面的gitolite-admin/conf/gitolite.conf即可。我们可以看下初始的gitolite.conf文件内容:

    repo gitolite-admin
        RW+     =   admin
    
    repo testing
        RW+     =   @all
    
    repo gitolite-admin
        RW+     =   admin
     
    repo testing
        RW+     =   @all
    

    repo name,就是定义一个名为name的仓库。可以看到Gitolite里面有两个默认的仓库,gitolite-admin和testing。

    下面的RW+ = admin则便是这个仓库的权限控制规则,可以看到这个仓库只允许admin可读可写可管理。

    我们可以用以下代码添加一个新的bar仓库:

    repo bar
        RW+     =   foo
    
    repo bar
        RW+     =   foo
    

    我们在gitolite.conf文件中添加一个foo的仓库,实际存放在服务器上的仓库目录名是foo.git。这个新仓库只允许foo用户可读可写可管理。

    你可以把两个具有一样的访问权限的仓库定义成一行,如下:

    repo a b c
        RW+     =   foo
        R       =   admin
    
    repo a b c
        RW+     =   foo
        R       =   admin
    

    这样,a、b、c就是3个具有相同的访问权限的仓库了,foo用户可以读可写可管理,admin用户只能可读。

    删除、重名仓库

    删除仓库稍微麻烦一点:

    1. 从gitolite.conf删除仓库的定义
    2. 登陆到服务器,删除服务器上对应的仓库
      重命名仓库也是如此,修改gitolite.conf文件,然后修改服务器上对应仓库的名字。

    导入现有仓库

    直接把一个仓库放入Gitolite仓库目录是不行的,它有几个要求:

    • 仓库必须是bare仓库
    • 仓库目录名必须以.git结尾
    • 仓库里面所有的文件和目录的归属(ownded)和可写于Gitolite用户账号。
    • 运行gitolite setup

    用户组和仓库组

    你可以把用户或者仓库定义成一个组,对这个组赋予某种属性,就是对组内所有的成员都赋予同样的属性。这对批量的处理某些问题很有帮助。
    组名以@开头,如下定义一个3个成员的组:

    @developers = dilbert alice wally
    
    也可以累积分别定义,效果跟上面一样:
    
    
    @developers = dilbert
    @developers = alice
    @developers = wally
    
    你也可以把一个组放到另外一个组里面:
    @developers     =   dilbert alice
    @interns        =   ashok
    @staff          =   @interns @developers
    @developers     =   wally
    

    注意,后来添加到develpoers组的wally并不在staff组里面。

    如下是个使用组定义仓库和它用户的例子:

    @developers     =   dilbert alice wally//三个用户
    @foss-repos     =   git gitolite//两个仓库
    
    repo @foss-repos
        RW+         =   @developer
    
    @developers     =   dilbert alice wally
    @foss-repos     =   git gitolite
     
    repo @foss-repos
        RW+         =   @developer
    

    特殊组

    @all表示所有的仓库或者所有的用户。

    访问权限

    紧跟着一个仓库后面的就是这个仓库的访问权限规则,有以下几种权限:
    R,表示可读权限
    RW,表示fast-forward push分支,创建新分支和tag权限。不能回转、删除分支
    RW+,可以做任何事情
    '-'表示拒绝访问
    以下面的配置为例子:

    repo foo bar
    
        RW+                     =   alice @teamleads
        -   master              =   dilbert @devteam
        -   refs/tags/v[0-9]    =   dilbert @devteam
        RW+ dev/                =   dilbert @devteam
        RW                      =   dilbert @devteam
        R                       =   @managers
    
    • alice 和teamleads组可以做任何事情
    • dilbert @devteam权限
      • 可以对/dev分支做任何事情,不能写,删除master
      • 可以fast-forward push分支,创建新分支和tag权限
      • 除了以v开头tag,可以创建其他tags
    • managers只能读仓库

    你还可以创建一个仓库组,在同一个仓库组里面的仓库具有相同的权限,如下:

    repo @myrepos
        RW+     =   alice
    
    @myrepos    =   foo
    @myrepos    =   bar
    @myrepos    =   zzq
    

    这样,有3个仓库foo、bar、zzq都在myrepos同一个仓库组里面,具有相同的访问权限。

    gitolite.conf

    gitolite.conf有两个重要的作用:定义仓库名和定义仓库的访问权限。

    基本语法
    所有的东西都是用空格分隔
    可以使用#表示注释
    用户名和仓库名都是以字母开头,可以包含.、_、-。用户名还可以是电子邮件地址
    组名类似用户名,但不能是电子邮件地址
    仓库名可以包含/,用来表示目录结构

    include其他配置

    Gitolite允许你把配置放在另外的.conf文件里,然后在gitolite.conf把这些配置文件include进来就可以了。比如include “foo.conf”,就把foo.conf文件里面的配置包括进来了。

    gitolite配置参考链接

    完成和验证

    到打印出如下结果gitolite安装完成。

    初始化空的 Git 仓库于 /home/gitolite/repositories/gitolite-admin.git/
    初始化空的 Git 仓库于 /home/gitolite/repositories/testing.git
    

    这是创建了两个仓库,一个是管理仓库gitolite-admin.git,另一个是测试使用的testings.git.
    现在要做的是要从gitolite服务器中把gitolite-admin.git拉取下来进行project和权限的管理

    遇到的问题及其说明

    创建新用户并同时创建主目录--useradd -m xxxname
    设置密码--passwd xxxname,然后再输入密码

    gitolite 不在 sudoers 文件中。此事将被报告

    sudo命令可以让你以root身份执行命令,来完成一些我们这个帐号完成不了的任务。
    其实并非所有用户都能够执行sudo,因为有权限的用户都在/etc/sudoers中呢。
    我们可以通过编辑器来打开/etc/sudoers,或者直接使用命令visudo来搞定这件事情。
    打开sudoers后,像如下那样加上自己的帐号保存后就可以了。

    # User privilege specification
    root    ALL=(ALL:ALL) ALL
    gitolite ALL=(ALL:ALL) ALL
    

    sudoers的权限是0440,即只有root才能读。在你用root或sudo后强行保存(wq!)即可.
    测试通过后开始下面的安装

    repo环境配置

    概要

    repo是Android为了方便管理多个git库而开发的Python脚本。repo的出现,并非为了取代git,而是为了让Android开发者更为有效的利用git。
    Android源码包含数百个git库,仅仅是下载这么多git库就是一项繁重的任务,所以在下载源码时,Android就引入了repo。 Android官方推荐下载repo的方法是通过Linux curl命令,下载完后,为repo脚本添加可执行权限:

    $ git clone https://gerrit-googlesource.lug.ustc.edu.cn/git-repo  > ~/bin/repo
    $ chmod a+x ~/bin/repo
    $ cp repo/repo .    //在~bin目录下
    再将~/bin添加到环境变量,这样就可以使用repo命令了
    

    工作原理

    repo需要关注当前git库的数量、名称、路径等,有了这些基本信息,才能对这些git库进行操作。通过集中维护所有git库的清单,repo可以方便的从清单中获取git库的信息。 这份清单会随着版本演进升级而产生变化,同时也有一些本地的修改定制需求,所以,repo是通过一个git库来管理项目的清单文件的,这个git库名字叫manifest。

    当打开repo这个可执行的python脚本后,发现代码量并不大(不超过1000行),难道仅这一个脚本就完成了AOSP数百个git库的管理吗?并非如此。 repo是一系列脚本的集合,这些脚本也是通过git库来维护的,这个git库名字叫repo

    在客户端使用repo初始化一个项目时,就会从远程把manifests和repo这两个git库拷贝到本地,但这对于Android开发人员来说,又是近乎无形的(一般通过文件管理器,是无法看到这两个git库的)。 repo将自动化的管理信息都隐藏根目录的.repo子目录中。

    项目清单库(.repo/manifests)

    <?xml version="1.0" encoding="UTF-8"?>
    <manifest>
    <remote  name="origin" fetch=".." review="https://android-review.googlesource.com/" />
    <default revision="master" remote="origin"/>
    <project path="repo-test1" name="platform/repo-test1"/>
    <project path="repo-test2" name="platform/repo-test2"/>
    </manifest>
    

    注意project的path和name后面不要有/

    • <remote>:描述了远程仓库的基本信息。name描述的是一个远程仓库的名称,通常我们看到的命名是origin;fetch用作项目名称的前缘,在构造项目仓库远程地址时使用到;review描述的是用作code review的server地址

    • <default>:default标签的定义的属性,将作为<project>标签的默认属性,在<project>标签中,也可以重写这些属性。属性revision表示当前的版本,也就是我们俗称的分支;属性remote描述的是默认使用的远程仓库名称,即<remote>标签中name的属性值;属性sync-j表示在同步远程代码时,并发的任务数量,配置高的机器可以将这个值调大

    • <project>:每一个repo管理的git库,就是对应到一个<project>标签,path描述的是项目相对于远程仓库URL的路径,同时将作为对应的git库在本地代码的路径; name用于定义项目名称,命名方式采用的是整个项目URL的相对地址。 譬如,AOSP项目的URL为https://android.googlesource.com/,命名为platform/build的git库,访问的URL就是https://android.googlesource.com/platform/build
      如果需要新增或替换一些git库,可以通过修改default.xml来实现,repo会根据配置信息,自动化管理。但直接对default.xml的定制,可能会导致下一次更新项目清单时,与远程default.xml发生冲突。 因此,repo提供了一个种更为灵活的定制方式local_manifests:所有的定制是遵循default.xml规范的,文件名可以自定义,譬如local_manifest.xml, another_local_manifest.xml等, 将定制的XML放在新建的.repo/local_manifests子目录即可。repo会遍历.repo/local_manifests目录下的所有*.xml文件,最终与default.xml合并成一个总的项目清单文件manifest.xml。
      问题的疑难点在于manifest中的配置,manifest.git相对于它管理的仓库的路径关系在remote节点配置的

    在服务器创建仓库

    在创建好default.xml后,提交到服务器。
    然后在服务器端,利用default.xml生成src.txt,再写个脚本自动创建所有的git仓库。
    生成src.txt

    cat default.xml | cut -d '"'   -f 2 > src.txt
    命令解释:
    cat default.xml是输出文件内容
    | 是管道,文件内容被定向输出到管道
    cut 是针对行截取,-d是自定义分隔符为 "
    -f 2显示之前分隔开的第二个区域,比如行
       <project name="platform/build" path="build/" />
    按"截取后为 project  name=  platform/build   path=  build/
    下标从0开始,第二个区域为platform/build.
    >src.txt定向输出到文件src.txt
    

    cut详细参数:
    -b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
    -c :以字符为单位进行分割。
    -d :自定义分隔符,默认为制表符。
    -f :与-d一起使用,指定显示哪个区域。
    -n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的<br />范围之内,该字符将被写出;否则,该字符将被排除。
    cut详细用法
    生成src.txt后,去掉不必要的行,文件首尾有一些不需要的行。
    生成src.sh文件如下:

    #/bin/bash
    set -x
    set -e
    pwd=${PWD}
    
    cd /home/gitolite/repositories#此处要根据实际的repositories路径修改
    while read line; do
        if [ -z "$line" ]; then
            echo $work_dir not exist !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1>&2
            continue
        fi
            git init --bare $line.git    
    #初始化裸仓库,使用--bare选项时,不再生成.git目录,而是只生成.git目录下面的版本历史记录文件,这些版本历史记录文件也不再存放在.git目录下面,而是直接存放在版本库的根目录下面
            echo ==== $line
            pwd
    done
    

    运行此脚本,会在/home/gitolite/repositoires下面生成相关仓库
    如下:

    abi.git       build.git    developers.git   external.git    hardware.git         ndk.git    sdk.git       u-boot.git
    art.git       chipram.git  development.git  flyscale.git    kernel.git           packages   system.git    vendor.git
    bionic.git    cts.git      device.git       frameworks.git  libcore.git          pdk.git    tools.git
    bootable.git  dalvik.git   docs.git         gen.git         libnativehelper.git  prebuilts  u-boot64.git
    

    但是有一个问题,这样虽然初始化了裸仓库,但是由于没有在gitolite中进行添加和配置,客户端是不能提交成功能,所以所有的这些仓库必须都被 gitolite管理起来才可以。那如上方法就不可取了。

    使用脚本生成gitolite.conf

    因为要建立上百个仓库,不可能全部手动进行配置,我们需要使用脚本来生成gitolite.conf。
    脚本很简单:

    #/bin/bash
    
    set -x #追踪代码执行情况
    set -e #当脚本执行出现意料之外的情况时,立即退出,避免错误被忽略,导致最终结果不正确
    
    work_dir=$1 #传入的第一个参数
    
    pwd=${PWD}
    echo $pwd start create gitrepo...
    while read line; do
            echo repo $line >> gitolite.conf  #仓库名称
            echo     RW+     =   @user >> gitolite.conf  #权限配置
    done
    

    同样利用到了src.txt,执行命令cat src.txt | ./con-tools.sh
    这样就配置好了,再执行如下命令提交gitolite-admin

    git add -all
    git commit -m "更新gitolite.conf"
    git push origin master
    

    执行完之后 在/home/gitolite/repositories下面就生成了对应的所有仓库。

    客户端上传源码

    首先要准备一份没有建立git的源码。根据default.xml生成des.txt,生成的命令如下

    cat default.xml | cut -d ‘”’ -f 4 > des.txt
    //关于该命令的含义前面已经说过,
    

    使用如下脚本进行仓库的批量初始化和提交

    #/bin/bash
    
    set -x #追踪代码执行情况
    set -e #当脚本执行出现意料之外的情况时,立即退出,避免错误被忽略,导致最终结果不正确
    
    para1=
    work_dir=$1 #传入的第一个参数
    
    pwd=${PWD}
    echo $pwd start create gitrepo...
    while read line; do
        echo readline
        line1=${line%%/*}
        if [ -z "$line" ]; then
            echo $work_dir not exist !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1>&2
            continue
        fi
        if [ $(ls -A $pwd/$line | wc -l) -eq 0 ]; then
            echo $work_dir empty !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1>&2
            continue
        fi
        workdir=$pwd/$line
        echo ==== $workdir
        cd $workdir  #以下是提交流程
            rm -rf .git
            git init .  1>&2
            git add . -f 1>&2
            git commit -m "Initial commit" 1>&2
            git push --set-upstream gitolite@192.168.1.104:/platform/$line.git master --force
    done
    

    执行如下命令进行批量提交:
    cat des.txt | ./des.sh

    客户端下载代码

    1. 客户端需要首先下载git-repo仓库,并配置环境变量,这样才能使用repo命令
      git clone gitolite@192.168.1.104:git-repo.git
      然后把repo配置到环境变量中。
    2. repo init -u gitolite@192.168.1.104:/platform/manifest.git
    3. repo sync

    repo upload

    set -x
    set -e
    Shell脚本$的含义

    错误处理

    1. 执行repo init报错
      rror: manifest missing or unreadable -- please run init
    2. repo: no branches ready for upload
      https://blog.csdn.net/armwind/article/details/52488961

    参考链接:
    repo工作原理
    default.xml文件配置详解
    repo客户端安装
    修改/etc/profile出错后恢复

    搭建Gerrit代码审核服务器

    参考链接
    参考链接
    下载wget http://gerrit-releases.storage.googleapis.com/gerrit-2.8.1.war
    下载路径/usr/local/

    安装apache2报依赖错误的问题,只需要把依赖包安装指定版本的即可。
    解决依赖错误

    apache2启动失败,参考Log:/var/log/apache2/error.log

    登录mysql并修改用户

    启动gerrit服务
    ./gerrit.sh start

    登录mysql数据库
    格式:mysql -u[用户名] -p
    示例,用户名root:
    mysql -uroot -p
    show databases;//查看所有数据库

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | reviewdb           |
    +--------------------+
    4 rows in set (0.02 sec)
    

    information_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。详细information_schema
    reviewdb是gerrit使用的数据库
    use reviewdb;//使用reviewd数据库
    //确认使用的数据库

    mysql> select database();
    +------------+
    | database() |
    +------------+
    | reviewdb   |
    +------------+
    1 row in set (0.00 sec)
    

    //查看reviewdb中的所有表

    mysql> show tables;
    +-----------------------------+
    | Tables_in_reviewdb          |
    +-----------------------------+
    | account_group_by_id         |
    | account_group_by_id_aud     |
    | account_group_id            |
    | account_group_members       |
    | account_group_members_audit |
    | account_group_names         |
    | account_groups              |
    | account_id                  |
    | change_id                   |
    | change_messages             |
    | changes                     |
    | patch_comments              |
    | patch_set_approvals         |
    | patch_sets                  |
    | schema_version              |
    | system_config               |
    +-----------------------------+
    16 rows in set (0.01 sec)
    

    修改gerrit认证方式

    gerrit有多种身份验证方法,身份验证方法决定了如何登录Gerrit。

    1. OPENID,如果你想挂入某个现有的身份验证提供方(例如GoogleAccounts),那么可以使用OpenID。
    2. development_become_any_account,如果是用于测试和学习,可以选择最简单的development_become_any_account。
    3. HTTP认证也是可选的认证方式,此认证方式下需要配置Apache的反向代理,并在Apache中配置Web站点的口令认证,通过口令认证后gerrit在创建账号的过程中会询问用户的邮件地址并发送确认邮件。
    4. LDAP, LDAP全称Lightweight Directory Access Protocol,轻量目录访问协议。使用用户名和密码。
      在etc/gerrit.config下的
    [auth]
            type = LDAP
    

    使用HTTP认证需要使用反向代理

    我司使用的HTTP进行认证。
    反向代理:反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

    配置说明

    下面是我的配置,服务器地址192.168.1.104,代理端口9999,被代理端口10000。本机回环IP127.0.1.1

    1. 在/etc/apache2/下创建httpd.conf
    #add gerrit reverse proxy --bianjb
    <VirtualHost *:9999>    #代理端口9999
        ServerName 192.168.1.104
        ProxyPreserveHost On    #开启反向代理
        ProxyRequests Off
        <Proxy *>    #访问权限规则
            Order deny,allow  
            Allow from all  
        </Proxy>
        <Location /login/>  #登录成功转到登录界面
          AuthType Basic
          AuthName "Welcomme to Gerrit Code Review Site!"
          Require valid-user
          AuthBasicProvider file
          AuthUserFile /home/gerrit/review_site/etc/passwd    #用户验证使用的文件,需要自行创建
        </Location>
        ProxyPass / http://127.0.1.1:10000/    #被代理地下
    </VirtualHost>
    

    AuthUserFile /home/gerrit/review_site/etc/passwd,我放在了这个目录下,可以自行指定,创建方法如下:

    sudo touch /home/gerrit/review_site/etc/passwd  //创建文件
    sudo htpasswd -b home/gerrit/review_site/etc/passwd  username passwd
    //使用htpasswd帮助信息
    htpasswd -h
    

    后面登录的时候就可以使用useranme+passwd进行登录 了。

    1. 在/etc/apache2/apache2.conf中引入我们新建的httpd.conf
    Include httpd.conf
    
    1. 配置/etc/apache2/ports.conf
    Listen 80    #apache2默认监听的端口
    Listen 9999  #新添加监听9999端口作为代理
    
    1. 重启apache2服务
    sudo service apache2 restart
    

    现在就可以访问服务器了,如下图:


    image.png

    登录成功后如图:


    image.png

    配置Gerrit开机启动

    1. 安装gerrit的时候,会有一个安装目录,在它的下面有个 bin/gerrit.sh文件,把这个文件拷贝到/etc/init.d下 改名叫做 gerrit
    2. 然后用sysv-rc-conf工具,这个没有可以直接apt-get install进行安装
    3. 运行sysv-rc-conf
      image.png
      找到gerrit的那一行,把2~5都X上。

    搭建起来还是挺费劲的,欢迎各位交流指正!

    相关文章

      网友评论

        本文标题:搭建安卓源码服务器,repo+gerrit+git环境,代码审核

        本文链接:https://www.haomeiwen.com/subject/tawpvftx.html