草庐IT

gerrit系统如何配置访问控制

aosp 2023-03-28 原文

.
版本:v0.3
作者:河东西望
日期:2022-7-13
.



gerrit系统的上手使用有两个难点:

  1. 部署repo仓库。
  2. 配置访问控制。

想要上手使用gerrit的同仁们,搭建部署好gerrit系统之后,会发现gerrit的权限配置不知道从哪里下手。而默认的权限配置非常简单而且开放,不符合企业各种开发管理的需求场景。

gerrit系统上的官方帮助文档很全面,各种概念都讲解得很细致。但是使用gerrit的方式,每个人可能都有不同的方式。只要研发团队用起来上手简单,操作流畅,每种方式都是可行的。

在AOSP的项目开发中,gerrit的使用方式有多种:

  1. 仅仅作为代码仓库系统使用,可以跟gitlab一样作为纯git仓库,也可以是大型repo仓库。
  2. 仅仅作为代码评审系统使用。一般较多的使用方式是gitlab+gerrit组合。这种方式不少公司在使用。
  3. 作为完整的代码仓库系统+代码评审系统使用。

本文档不讲解gerrit的概念和原理,主要介绍项目实践中访问控制是如何配置使用的。repo仓库的部署搭建可以参看我的其他博文。

1 关键概念

使用gerrit之前,我们还是要了解几个关键概念:群组Group,仓库Repository,引用Refernece,权限Permission。

群组Group
gerrit的权限所授予的对象主要是群组Group(虽然也可以针对个人,但它不是常态的权限配置方式)。每个人总是属于一个或者多个群组。

仓库Repository
gerrit中的仓库有多种:正常的代码仓库,权限仓库,项目清单仓库,repo工具仓库等等。

gerrit的访问控制是通过权限仓库来完成的,默认的两个权限仓库是all-projects和all-users(all-users仓库我个人基本没有用到)。权限仓库对普通用户是只读的。

所有的仓库都是通过继承all-projects来配置权限的。我们要配置权限,就是创建子仓库,然后配置这个子仓库的权限,提供给代码仓库继承来实现的。

引用Reference
就是git仓库的各种引用,包括分支,标签,meta属性等。

权限Permission
权限,也就是访问控制Access Control,它的作用对象是仓库的引用reference。

可以归纳一句话来理解:仓库的访问控制就是把其引用Reference的权限授予给群组。(也不好理解?!往下看)

2 需求场景

作为企业的开发团队来说,一般的需求场景是这样的:

  • 有多个不同的部门,每个部门不能互相看到其他部门的代码。
  • 所有部门有如下几种角色:开发者developer、评审者reviewer,项目owner。
  • 不同部门的项目代码仓库的分支策略可能不一样,但是一般有这几个分支:develop、test、product。
  • 开发组developer只能操作develop分支:clone,push权限,review+1权限,其他分支只可clone,不能push。
  • 评审组reviewer只能操作developer分支:除了developer权限之外,还有review+2,submit权限。
  • 项目组owner可以操作所有分支,权限还包括merge,增删分支、增删标签等。

我们可以看一下部门矩阵图:

部门
├── DEV01
│   ├── 项目组
│   ├── 评审组
│   └── 开发组
├── DEV02
│   ├── 项目组
│   ├── 评审组
│   └── 开发组
└── DEV03
    ├── 项目组
    ├── 评审组
    └── 开发组

还有仓库分支图:

仓库分支
├── develop
├── test
└── product

3 配置策略

根据上述的需求场景,我们可以采取如下权限管理策略:

  1. 原始的all-projects仓库不要动,创建自己的权限仓库all-projectx。所有的仓库继承这个权限仓库。
  2. 在all-projectx上修改权限配置。
  3. 如果还想要继续创建更多的权限配置,就继承这个all-projectx。
  4. 在子仓库继承的引用权限中,可以通过Exclusive选项来确认是否需要继承父系权限。

我这里对应创建三个群组:

  • developers
  • reviewers
  • leaders

在每个仓库中,我们只需要配置如下几个引用,其他以后逐步细化配置:

  • refs/for/* : 源代码
  • refs/head/XXX: XXX分支
  • refs/tag/*: 标签

而在权限配置中,我们只需要配置如下几个基本权限:

权限 作用于
Abandon git abandon
Create Reference git branch/git tag
Delete Reference git branch
Forge Committer Identity git push origin HEAD:refs/for/xxx
Push git push --all
Add Patch Set git apply
Push Merge Commits git merge
Create Annotated Tag git tag -a
Create Signed Tag git tag -s
Read git clone/pull/fetch
Rebase git rebase
Revert git revert
Submit web页面的submit权限

实际上,gerrit权限配置之所以上手比较复杂,就在这两个点上: 一个是reference,一个是permission。弄清他们的意义,以及跟git引用的对应关系,是需要时间的。官网上概念虽然很详细,但是具体怎么用,还是一头雾水。这里就化繁为简,采取简单方式,配置出基本的权限控制策略。

all-projectx仓库的Access控制操作,由管理员在页面上进行,操作步骤:

  • Add Reference (refs/for/, refs/tags/, refs/head/develop, refs/head/product ...)
  • Add Permission (Abandon, Create Reference, ...... Submit)
  • Add Group (developers, reviewers, leaders)
  • 配置控制 (Allow, Deny, Block)。需要给谁什么权限就配置Allow。

下面是配置文件Project.config模板:

[access]
	inheritFrom = All-Projects
[submit]
	action = inherit
[access "refs/head/develop"]
	abandon = group developers
	abandon = group leaders
	abandon = group reviewers
	addPatchSet = group developers
	addPatchSet = group leaders
	addPatchSet = group reviewers
	create = deny group developers
	create = group leaders
	create = group reviewers
	createTag = deny group developers
	createTag = group leaders
	createTag = group reviewers
	delete = deny group developers
	delete = deny group reviewers
	delete = group leaders
	forgeCommitter = group developers
	forgeCommitter = group leaders
	forgeCommitter = group reviewers
	push = group developers
	push = +force group leaders
	push = group reviewers
	pushMerge = group developers
	pushMerge = group leaders
	pushMerge = group reviewers
	read = group developers
	read = group leaders
	read = group reviewers
	rebase = group developers
	rebase = group leaders
	rebase = group reviewers
	revert = group developers
	revert = group leaders
	revert = group reviewers
	submit = deny group developers
	submit = group leaders
	submit = group reviewers
[access "refs/head/product"]
	abandon = deny group developers
	abandon = group leaders
	abandon = group reviewers
	addPatchSet = deny group developers
	addPatchSet = group leaders
	addPatchSet = group reviewers
	create = group leaders
	createTag = deny group developers
	createTag = group leaders
	createTag = group reviewers
	delete = deny group developers
	delete = group reviewers
	forgeCommitter = deny group developers
	forgeCommitter = group leaders
	forgeCommitter = group reviewers
	push = deny group developers
	push = +force group leaders
	push = group reviewers
	pushMerge = deny group developers
	pushMerge = group leaders
	pushMerge = group reviewers
	read = group developers
	read = group leaders
	read = group reviewers
	submit = deny group developers
	submit = group leaders
	submit = group reviewers
[access "refs/for/*"]
	push = group developers
	push = +force group leaders
	push = group reviewers
	read = group developers
	read = group leaders
	read = group reviewersFILE

有关gerrit系统如何配置访问控制的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  5. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  6. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐