安装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
- 切换到git用户账号:su – git
- 安装SSH,一般来说服务器上都已经安装SSH了
- 获取Gitolite代码,git clone git://github.com/sitaramc/gitolite
- 创建Gitolite安装目录。mkdir -p ~/bin
- 开始安装。gitolite/install -to ~/bin
- 添加管理员公钥。这个管理员公钥就是对应着拥有管理代码仓库的权限,非常重要。把自己的公钥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用户只能可读。
删除、重名仓库
删除仓库稍微麻烦一点:
- 从gitolite.conf删除仓库的定义
- 登陆到服务器,删除服务器上对应的仓库
重命名仓库也是如此,修改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安装完成。
初始化空的 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后,里面会有一些不必要的行,文件首尾有一些不需要的行,如下:
1.0 //去掉
<manifest> //去掉
origin //去掉
origin //去掉
android/platform/9820e/build
core/root.mk //去掉
</project> //去掉
#/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
客户端下载代码
- 客户端需要首先下载git-repo仓库,并配置环境变量,这样才能使用repo命令
git clone gitolite@192.168.1.104:git-repo.git
然后把repo配置到环境变量中。 repo init -u gitolite@192.168.1.104:/platform/manifest.git
repo sync
repo upload
错误处理
- 执行repo init报错
rror: manifest missing or unreadable -- please run init - 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。
- OPENID,如果你想挂入某个现有的身份验证提供方(例如GoogleAccounts),那么可以使用OpenID。
- development_become_any_account,如果是用于测试和学习,可以选择最简单的development_become_any_account。
- HTTP认证也是可选的认证方式,此认证方式下需要配置Apache的反向代理,并在Apache中配置Web站点的口令认证,通过口令认证后gerrit在创建账号的过程中会询问用户的邮件地址并发送确认邮件。
- 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
- 在/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进行登录 了。
- 在/etc/apache2/apache2.conf中引入我们新建的httpd.conf
Include httpd.conf
- 配置/etc/apache2/ports.conf
Listen 80 #apache2默认监听的端口
Listen 9999 #新添加监听9999端口作为代理
- 重启apache2服务
sudo service apache2 restart
现在就可以访问服务器了,如下图:
登录成功后如图:
配置Gerrit开机启动
- 安装gerrit的时候,会有一个安装目录,在它的下面有个 bin/gerrit.sh文件,把这个文件拷贝到/etc/init.d下 改名叫做 gerrit
- 然后用sysv-rc-conf工具,这个没有可以直接apt-get install进行安装
- 运行
sysv-rc-conf
找到gerrit的那一行,把2~5都X上。
搭建起来还是挺费劲的,欢迎各位交流指正!