3968|0

854

帖子

0

TA的资源

五彩晶圆(中级)

楼主
 

构建自己的Android代码托管服务器 [复制链接]

研究android源码的都知道,在下载源码时,都是用repo init ,repo sync等命令去下载源码,repo内部是使用git进行版本控制的,之前没有仔细的了解,只知道跟着source.android.com的教程,当个打字员,然后编译,之后rom就出来了。让我进行这方面的研究的一个trigger是我现在进行的项目,需要对android的framework进行改动,我需要对音频模块进行修改,然后我小弟需要对另外一个模块进行修改,考虑到长久的代码管理及代码备份整合,有必要进行代码托管。之前我一直习惯使用svn,但是android那么庞大的数据量,用svn,再怎么多的硬盘也不够。先前就对git有所耳闻,但一直感觉它是个谜,没有勇气去触碰,趁着这个机会,也想好好学一学。

本文的目的是构建自己的android源码仓库,为此构建了一条龙的教程,进行了一系列服务端的安装配置,如repo,git,,gerrit,ssh rsa认证,并在此基础上从github上迁移Cyanogenmod仓库,达到最终的目的。

1、repo原理分析

        由于设备的原因,我现在代码都是从Cyanogenmod 上拉取的。根据官方的教程,是从http://github.com/Cyanogenmod/android.git 下载下来的,我之前以为它的代码全都是在那,用浏览器打开下,居然只有两个文件:README.mkdn和default.xml,仔细的看了下它的内容,尤其是default.xml,发现了端倪.

http://github.com/Cyanogenmod/android.git内容:

default.xml:

        看着default.xml,仔细的跟源码进行对照,发现了其中的奥秘,也终于见识了git的分布式功能:git是个分布式的版本控制软件,它可以让你把代码分布在各个仓库,然后从各个仓库把各个项目取出来,这些仓库可以是你自己的,也可以是别人的。而repo正是对这些仓库进行统一的控制管理的工具。从default.xml,可以看到有标签,表示一个git源,而是从那些源取出来的项目,在可以使用remote指定源,如果没有指定,就从使用定义的源里的path表示下载到android source的目录,name表示从源处获取的项目git仓库位置,revision表示分支版本。如上图,我们可以看到,该版本,从aosp的android-4.0.4_r1.2分支取出device/common项目,放置在android源码根目录的device/common目录下。

        repo会从指定的版本仓库里下载里面的default.xml文件,进行解析,然后根据不同的的配置,把项目从分布服务端下载下来,从而形成android的源码,强大吧!

        因此,我们可以修改里面的default.xml,更改部分的成自己的版本仓库,便可进行分布式的开发了。自己可以github.com上构建个自己的仓库,进行开发。

repo在管理的时候,会使用gerrit进行Code Review,这个稍后再讲,不过《Git权威指南》的作者有一篇《脱离 Gerrit 审核服务器,使用 repo》,据称可以脱离Gerrit,很惭愧,按照他的教程我没有成功,也不想去深究了,求各路大牛指教。

        repo的命令详见:http://source.android.com/source/using-repo.html

2、git服务端架设

        具体git的命令不详细描述了,有几个个人认为好的资源分享下:

        《Pro Git》

        《看日记学Git

        《Git权威指南》   --- 未读,听说口碑很好

        Git的架设通常需要openssh server, Git, Gitosis, Apache2,我的服务端是ubuntu,这里用了两台机器:


  • Server:表示我的Git服务端
  • Client: 表示我的Git客户端
        2.1、Server上安装Git服务[html] view plaincopy


  • sudo apt-get install git-core   



        2.2、Server上安装Gitosis        Gitosis是一个工具程序,可以帮助我们进行Git仓库的访问控制和远程管理。
[html] view plaincopy




[html] view plaincopy


  • cd gitosis  
  • sudo python setup.py install  

        PS:需先安装python:  sudo apt-get install python-setuptools


        2.3、为Gitosis创建系统用户        由于是私人团队使用,我个人喜欢用以下方法创建:
[html] view plaincopy


  • sudo adduser git  
  • sudo passwd git  

        把gitweb的项目设置为/homg/git


        2.4、安装远程管理客户端

        安装远程管理客户端,允许Client能通过ssh对Git进行管理。在Client的~/.ssh上执行:
[html] view plaincopy


  • ssh-keygen -t rsa  

         该命令会产生一对公私钥,然后将公钥复制到Server服务端


[html] view plaincopy


  • scp ~/.ssh/id_rsa.pub git@Server:/home/git  
  • sudo -H -u git gitosis-init < /home/git/id_rsa.pub  

         然后,会在/home/git/repositories创建仓库目录,并且里面创建了一个管理员仓库,叫gitosis-admin,并且会把id_rsa.pub复制到keydir目录下

        修改一个文件的权限(= =具体为啥修改,没具体深究)
[html] view plaincopy


  • sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update  


        之后我们便可以再Client端对Git Server进行控制

[html] view plaincopy


  • git clone git@Server:repositories/gitosis-admin.git   

         可以通过修改gitosis-admin/gitosis.conf文件来管理Server上的仓库

[html] view plaincopy


  • [group gitosis-admin]   
  • members =emos@emos.com   
  • writable = gitosis-admin   

         该文件可以创建不同的分组[group],分组有的members 设置不同的成员,然后通知对不同仓库的管理权限,在这里对gitosis-admin有写的权限。


        2.5、添加新用户        当有新用户添加时,可以把他的公钥放在keydir下,并修改gitosis.conf即可,用户名是去掉.pub后缀后的名称。如:我的公钥名称是emos@emos.com.pub,那么我的用户名就是 emos@emos.com

        2.6、创建新项目        我们想要创建个Git仓库的话,可以在/home/git下创建即可。[html] view plaincopy


  • cd ~  
  • mkdir sample.git  
  • git --bare init  


        之后可以再gitosis.conf,修改配置文件,配置权限[html] view plaincopy


  • [group sample]   
  • members = emos@emos.com  
  • writable = sample  

        members为用户,表示这些用户能够对sample进行写入。

        可以通过http://your-server-ip/cgi-bin/gitweb.cgi,查看你当前的Git仓库。

        2.7、ssh rsa认证

        我们在Client端执行git clone的时候,经常会提示你输入密码,我在使用github的时候,并不需要密码,网上查了下,原来是github的ssh采用rsa认证的原因,无需输入密码,采用公私钥即可进行操作。出于个人喜好,我自己想在Client端通过rsa认证的方式访问Server。
        修改/etc/ssh/sshd_config[html] view plaincopy


  • RSAAuthentication yes  
  • PubkeyAuthentication yes  
  • AuthorizedKeysFile    %h/.ssh/authorized_keys  

        把Client上传的id_rsa.pub拷贝到 /home/git/.ssh/authorized_keys[html] view plaincopy


  • cd /home/git  
  • cp /home/git/id_rsa.pub .ssh/authorized_keys  

        重启ssh服务即可,如果有新的客户端想通过该方式访问Server,把它的rsa公钥拷贝添加到authorized_keys即可。之后我们用ssh登陆或者git clone就无需输入密码进行验证了。Git Server配置完毕。


References: http://blog.csdn.net/sheismylife/article/details/7204345
                        http://blog.csdn.net/wirror800/article/details/5189564

3、Gerrit服务端配置        到最头疼的地方了,吐槽下历史:起初压根不知道Gerrit的存在,我在创建自己的仓库管理的时候,拷贝Cyanogenmod,把它的default.xml里Cyanogenmod的review去掉,然后在使用repo upload的时候就报错了,表示木有review,木有Gerrit,代码不让上传,so,repo貌似泡汤了。。
Gerrit是咩东西呢?它是代码审核工具,包括了一套权限系统,我们在使用Git的时候,如果使用git push,是直接提交到到Git仓库的,为了保证代码的质量,Gerrit出现了(= =我YY的),使用Gerrit后,我们代码的提交流程大致如下:我们用git push把代码提交上去之后,要先经过Gerrit的审核,审核通过后才会提交到主线的代码。详细的流程,如下图:


        3.1、gerrit安装

        Gerrit安装在Server端,从http://code.google.com/p/gerrit/ 下载Gerrit,最新版的是2.4,它运行时需要用到数据库,有H2,Mysql,PostgreSQL等,为了方便我就是用H2。由于只是搭建个小型服务器,Authentication method是用http,其它都是默认。
        要初始化Gerrit,运行 java -ar gerrit.war init -d /path/to/location会在/path/to/gerrit指定路径上安装Gerrit运行时。然后会弹出一大堆的交互信息,我就只有Authentication method选择http,其它默认。安装完后会弹出浏览器弹出错误界面,提示http请求未带授权头。

        3.2、安装配置apache2[html] view plaincopy


  • sudo apt-get install apache2  

        激活代理模块

[html] view plaincopy


  • ln -s /etc/apache2/mods-available/proxy.conf /etc/apache2/mods-enable/proxy.conf     
  •    
  • ln -s /etc/apache2/mods-available/proxy.load /etc/apache2/mods-enable/proxy.load     
  •    
  • ln -s /etc/apache2/mods-available/proxy_http.load /etc/apache2/mods-enable/proxy_http.load   

         然后再/etc/apache2/httpd.conf中加入下面的内容(该文件初始为空),为了不跟之前的gitweb冲突,把该端口设置成8088
[html] view plaincopy


  •      
  •   ServerName localhost     
  •   ProxyRequests Off     
  •   ProxyVia Off     
  •   ProxyPreserveHost On     
  •    
  •        
  •         Order deny,allow     
  •         Allow from all     
  •        
  •       
  •        
  •      AuthType Basic     
  •      AuthName "Gerrit Code Review"   
  •      AuthBasicProvider file     
  •      AuthUserFile /path/to/gerrit/etc/passwords     
  •      Require valid-user     
  •        
  •    
  •   ProxyPass / http://127.0.0.1:8080/     
  •    

        在/etc/apache2/ports.conf添加
[html] view plaincopy


  • NameVirtualHost *:8088  
  • Listen 8088  




        这里需要注意2个地方,第一个是/path/to/gerrit/passwords 是用来保存gerrit的用户资料文件,可通过以下命令生成,该命令用来创建gerrit的用户[html] view plaincopy


  • htpasswd -c /path/to/gerrit/etc/passwords "gerrit_fisrt_username"  (第一次时要加-c,之后就不用了)  

        这里的gerrit_first_username就是用来登陆的用户名。

        第二个是ProxyPass / http://127.0.0.1:8080/,这里的配置要和/path/to/gerrit/etc/gerrit_config里面的[html] view plaincopy



        匹配。

        配置好后,可以通过浏览器访问http://127.0.0.1:8088,之后会提示用户名密码,输入gerrit_first_username和密码登陆,就会自动转到http://127.0.0.1:8080,。点击页面右上方的Setting,然后左侧栏点击profile,可以看到当前登录名,然后点击Contact information,在fullname随便输入名字即可。 第一个登陆的账户是管理员账户。
        在Client端执行命令[html] view plaincopy


  • ssh -p 29418 gerrit_fisrt_username@your-server-ip  

        会提示Permission denied(publickey),把刚才Client端上传的id_rsa.pub内容添加到gerrit中。注意这里要拷贝id_rsa.pub的全部内容。再次执行命令就是看到Welcome信息了。


        3.3、修正邮件地址        刚注册的用户无法进行邮件的注册,在repo upload的时候会出现提示:[html] view plaincopy


  • remote: ERROR:  You have not registered any email addresses.   

        我们可以停止Gerrit,进行手工的注册:

[html] view plaincopy


  • $ bin/gerrit.sh stop  
  • $ java -jar bin/gerrit.war gsql  
  • Welcome to Gerrit Code Review 2.1.6.1  
  • (H2 1.2.134 (2010-04-23))  
  •   
  • Type '\h' for help.  Type '\r' to clear the buffer.  
  •   
  • gerrit> select * from ACCOUNT_EXTERNAL_IDS;  
  • ACCOUNT_ID | EMAIL_ADDRESS          | PASSWORD | EXTERNAL_ID  
  • -----------+------------------------+----------+------------------------------------------  
  • 1000000    | NULL                   | NULL     | uuid:ac1b8a08-2dd1-4aa1-8449-8b2994dffaed  
  • 1000000    | NULL                   | NULL     | username:demo  
  • (2 rows; 23 ms)  
  • gerrit> update ACCOUNT_EXTERNAL_IDS set EMAIL_ADDRESS='alex.blewitt@example.com' where ACCOUNT_ID=1000000;  
  • UPDATE 2; 5 ms  
  • gerrit> select * from ACCOUNT_EXTERNAL_IDS;  
  • ACCOUNT_ID | EMAIL_ADDRESS          | PASSWORD | EXTERNAL_ID  
  • -----------+------------------------+----------+------------------------------------------  
  • 1000000    | alex.blewitt@example.com | NULL     | uuid:ac1b8a08-2dd1-4aa1-8449-8b2994dffaed  
  • 1000000    | alex.blewitt@example.com | NULL     | username:demo  
  • (2 rows; 23 ms)  
  • gerrit> \q  
  • Bye  
  • $ bin/gerrit.sh start  

         (此表来自于http://www.infoq.com/cn/articles/Gerrit-jenkins-hudson


        3.4、Gerrit创建项目        可以在web上进行项目的创建,也可以通过命令行创建[html] view plaincopy


  • ssh -p 29418 git@your-server-ip gerrit create-project --name example.git  

        上述命令创建一个名为example的项目,在之前指定的Git目录里初始化一个空的代码库。如果已经有一个代码库了,Gerrit不允许创建同名代码库——但你可以先对它进行临时重命名,随后再把名字改回来。我们在Client端创建个克隆:

[html] view plaincopy


  • $ git clone ssh://git@your-server-ip:29418/example.git  

        我们可以向代码库进行提交和推送,就和其他Git系统一样:

[html] view plaincopy


  • $ cd example  
  • $ echo hello > world  
  • $ git add world  
  • $ git commit -m "The World"  
  • [master (root-commit) 06bf85e] The World  
  • 1 files changed, 1 insertions(+), 0 deletions(-)  
  • create mode 100644 world  
  • $ git push  
  • No refs in common and none specified; doing nothing.  
  • Perhaps you should specify a branch such as 'master'.  
  • $ git push origin master  
  • Counting objects: 3, done.  
  • Writing objects: 100% (3/3), 217 bytes, done.  
  • Total 3 (delta 0), reused 0 (delta 0)  
  • To ssh://me@localhost:29418/example.git  
  • ! [remote rejected] master -> master (prohibited by Gerrit)  
  • error: failed to push some refs to 'ssh://demo@localhost:29418/example.git'  


        原因是Gerrit不希望我们直接覆写Git代码库中的任何分支,而是将变更推送到另一个refspec中,这让Gerrit有机会在代码审查中修改代码。。客户机必须先push到远程仓库的refs/for/*分支上,等待审核。这也是为什么我们需要使用gerrit的原因。gerrit本身就是个代码审核工具。最简单的方法是为推送配置一个默认的refspec:
[html] view plaincopy


  • $ git config remote.origin.push refs/heads/*:refs/for/*  
  • $ git push origin  
  • Counting objects: 3, done.  
  • Writing objects: 100% (3/3), 217 bytes, done.  
  • Total 3 (delta 0), reused 0 (delta 0)  
  • To ssh://demo@localhost:29418/example.git  
  • * [new branch]      master -> refs/for/master  

        即可push成功。之后会在Gerrit上显示。

        值得注意的是,安装默认完,只能进行初步的代码审核,没办法成功push,我也是到几个小时前才发现了,安装完Gerrit不会用,这是很蛋疼的事情。查看Project里Access设置的-2,-1,+1,+2,一头雾水。后来试了下,+2表示,能够立即push到Git仓库去。为了使用该功能我们需要首先需要为用户配置权限信息,在admin--》projects--》All-Projects--》access中点击edit,然后设置权限,+2表示能够立即push到Git仓库中,其它功能位置。说来话长了。主要是要为refs/heads/*添加,
        Label Code-Review
        Label Verified
        Submit
        +1和+2权限,并为每个权限添加用户组。 权限配置好以后, 点击某个commitid,在点击review,然后点击pulish或者submit, 顺序是先审核,再验证,再提交。


        3.5、Gerrit创建分支        只有上一步通过审核提交完之后,才允许Gerrit在上面进行分支的创建,个人认为是因为Gerrit上为空,没有一个commit-id,所以分支无法指向具体的版本。在上一步完成后,可以在project中进行创建,然后在本地提交上去:
[html] view plaincopy


  • $ git checkout -b gingerbead  
  • $ git push origin gingerbread  







References:http://fatalove.iteye.com/blog/1332881
                        http://www.infoq.com/cn/articles/Gerrit-jenkins-hudson
4、构建android仓库
        为了构建android的仓库,供内部使用,我打算在Server见一个repo server,把cyanogenmod上的gingerbread分支的代码下载到Server上,然后进行内部的研究及使用。
        4.1、制作android服务器镜像[html] view plaincopy



        在github中,如果不使用 -b,会出错。


        4.2、建立版本库[html] view plaincopy


  • $ mkdir  /home/git/android/gingerbread  
  • $ cd  /home/git/android/gingerbread  
  •    
  • $ repo init -u git@your-server-ip:mirror/CyanogenMod/android.git --mirror  -b gingerbread  




        修改.repo/manifest.xml

[html] view plaincopy


  • -           fetch="git://android.git.kernel.org/"   
  • +           fetch=".."   
  •    
  • $ repo sync   


        即可。构建完毕,之后就可以在Client使用repo -init -u git@your-server-ip:android/gingerbread/CyanogenMod/android.git -b ginerbread进行源码下载。
References: http://xxw8393.blog.163.com/blog/static/372568342011112111028926/



5、总结        总的来讲,构建过程还是比较顺利的,遇到问题查看网上的信息进行各种分析,比较蛋疼的是那android源码的下载,在ubuntu上搭建的过程很简洁,很适合俺这种新手。不过在构建过程中,没有对Git有一定的了解碰到问题是比较郁闷的,比如那个Gerrit的上传及创建分支的问题,没有对它深入的理解,对那些命令估计也只是抄来抄去的,不能理解它的原理,我就属于这种,接下来要好好研究下。



版权所有,转载请注明出处 http://blog.csdn.net/billpig/article/details/7604828

此帖出自Linux开发论坛
点赞 关注
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表