gerrit權限控制
背景
在公司中使用到了Gerrit作為技術管理,在配置的時候發現一些問題;轉載了這篇文章作為學習。
正文開始
原文鏈接:https://blog.csdn.net/chenjh213/article/details/50571190
Access controls in Gerrit are group based. Every user account is a member of one or more groups, and access and privileges are granted to those groups. Access rights cannot be granted to individual users.
在gerrit中權限控制是基於群組的. 每個用戶有一個或者多個群組, 訪問權限被賦予這些群組.訪問權限不能賦予個人用戶.
System Groups
在Gerrit系統
自帶下面的群組
- Anonymous Users
- Change Owner
- Project Owners
- Registered Users
Anonymous Users
所有用戶都是匿名用戶
成員, 所有用戶都能繼承Anonymous Users
所有訪問權限.
當前只有Read access
權限值得賦予給Anonymous Users
群組, 因為其他權限都需要認證.
Project Owners
Project Owners
的訪問權限在Project
范圍內有效
Change Owner
Change Owner
的訪問權限在Change
范圍內有效
Registered Users
所有在頁面上登錄成功的用戶都會自動注冊為gerrit用戶,屬於Registered Users
群組
Registered Users
群組通常被賦予Code-Review -1..+1
權限, 允許給需要審查代碼投票, 但不會引起審查被批准和拒絕
Predefined Groups
system groups
在Gerrit系統內部就定義好了, 而普通群組信息被保存在ACCOUNT_GROUPS
表中,Predefined groups
群組信息也保存在ACCOUNT_GROUPS
表中. Predefined groups
群組在Gerrit初始化時創建並且擁有唯一的UUID
值
All-Projects -> meta/config -> groups
文件內容
# UUID Group Name
#
5210215f92225c45a5ad123016c8706336f55a7d Administrators
df9b717d413c614cb51e39525619b311f077ec15 Non-Interactive Users
global:Anonymous-Users Anonymous Users
global:Project-Owners Project Owners
global:Registered-Users Registered Users1234567
Gerrit
自帶兩個predefined groups
:
- Administrators
- Non-Interactive Users
Administrators
Administrators
是Gerrit root
角色, 在Gerrit初始化時Administrate Server
權限被賦予給這個Predefined Groups
群組.
在Administrators
組的成員可以管理所有項目, 但是不意味着任何其他權限. Administrators
組不會自動獲得代碼審查批准和提交權限.
Non-Interactive Users
Interactive Users
比如在web頁面上審查代碼, 在提交/獲取代碼的用戶
Non-Interactive Users
是可以通過Gerrit接口進行操作的組, 在Gerrit初始化時Priority BATCH
和Stream Events
權限被賦予給這個Predefined Groups
組.
Non-Interactive Users
和Interactive Users
使用不同的線程池, 防止交互式用戶搶占線程. 當系統資源緊張時確保了交互式的用戶可以繼續工作.
Project Access Control Lists
All Projects
在All Projects
項目中的訪問權限會自動被其他項目繼承, 只有Administrate Server capability
能夠編輯All-Projects
權限.
Per-Project
先計算子項目的訪問權限, 再計算All Projects
的訪問權限, 允許一些權限可以被覆蓋.
對一個群組賦予DENY
限制時, 通常只對READ
權限有效.
Special and magic references
refs/heads/*
和refs/tags/*
是Git常用的引用命名空間, 一個用來存儲分支一個用來標簽
在refs/*
命名空間下的引用都是有效的,Gerrit在refs/*
有一些特殊用處的命名空間和引用
Special references
這些特殊的引用的內容由Gerrit生成或者包含重要的項目配置信息
refs/changes/* #用於存儲審查的補丁
#獲取某個補丁集需要審查序號和補丁集序號
#'refs/changes/'<last two digits of change number>/ <change number>/ <patch set number>
refs/meta/config #項目配置的分支
refs/meta/dashboards/* #
refs/notes/review #保存代碼審查信息的分支123456
Magic references
refs/for/<branch ref> #進行代碼審查時需要提交代碼到這個命名空間
refs/publish/* #和refs/for/*命名空間作用一樣
refs/drafts/* #用於草案代碼審查,和refs/for/*的區別在於只有部分人可見123
添加新的補丁
#審查者對代碼進行修改, 審查的代碼是修改后的補丁
git fetch ssh://admin@localhost:29418/gerrit_ci refs/changes/03/3/1
git branch fix_xxx FETCH_HEAD && git checkout fix_xxx
vi README
git add README
git commit --amend
git push origin HEAD:refs/for/master1234567
查看遠程引用
git ls-remote ssh://admin@localhost:29418/gerrit_ci
61fd289472707d79f73289216a4c5f0ca4cee4e1 HEAD
eeaef9da4ea27d7c23bfb5f9a2ed1b5357ebbba8 refs/changes/01/1/1
5f8ed98b0f88787c22e705595e2818db62874f56 refs/changes/02/2/1
bfdb700f4aab3afc32ec79a29b0e25f8be758f8f refs/changes/03/3/1
effa7b004eec0b85e722fe10be6468e4ed9b78d3 refs/changes/03/3/2
61fd289472707d79f73289216a4c5f0ca4cee4e1 refs/heads/master
9f282c08d5108c6817dd1504e8bec0e94ba59d47 refs/meta/config
405030285eed7406b1ac7cfa6a5211331165b8e2 refs/notes/review123456789
修改項目配置文件
git clone ssh://admin@localhost:29418/All-Projects && scp -p -P 29418 admin@localhost:hooks/commit-msg All-Projects/.git/hooks/
#refs/meta/config 是All-Projects的引用
git fetch origin refs/meta/config:refs/remotes/origin/meta/config
git checkout meta/config
#現在目錄下有groups project.config兩個文件
#提交修改
git add .
git commit -m "modify config"
git push origin meta/config:meta/config12345678910
Access Categories
Abandon
代碼審查時允許用戶丟棄這個審查。如果對change
有push
權限,同時具有push
,abandon
,restore
權限
Create Reference
用戶可以創建新的references
, branches or tags
, 創建時引用必須不存在,不能刪除已經創建的引用
如果僅僅推送標簽,給refs/tags/*
賦予Create Reference
權限
這個權限通常用在創建某個命名空間下的分支, 如:某個部門自由創建分支權限refs/heads/hello/*
給某用戶自由創建分支權限, 給refs/heads/sandbox/${username}/*
賦予Create Reference
權限
如果你這樣賦予Create Reference
權限,記得同時賦予push force
權限, 這樣擁有清理
Forge Author && Forge Committer && Forge Server
查看提交中Author
和Committer
git log --format=full
commit 2dfae738781a3ba641ee06c913fd51162335a941
Author: admin <c2290910211@163.com>
Commit: gerrit_test <c2290910211@aliyun.com>
admin gerrit_test
Change-Id: I0830cf061306101e977f9adf55270c9b3a3f59c412345678
Author
一般表示誰創建了這個提交,也可以用git commit --amend --reset-author
等命令修改
Committer
一般表示誰修改了這個提交,在使用git commit --amend
等命令時修改
通常Gerrit需要在Author
和提交的Committer
認證信息中至少一個,與uploading user
注冊過的郵箱地址匹配,Forge Author
和Forge Committer
允許用戶繞過提交時的身份驗證
Forge Author
允許提交中Author
信息不經過驗證, 這個權限在下面場景非常有效,通過郵件接收第三方補丁,cherry-pick
其他人的分支提交,審查合並前修改其他人的一些次要問題.
默認在All-Projects
賦予Registered Users
組Forge Author
權限.
Forge Committer
允許提交中Committer
信息不經過驗證和不驗證匿名標簽對象,通常在需要其他服務器自動提交時有用
Forge Server
允許在提交中Committer
信息使用Server
的用戶名和郵箱. 這個權限在強制推送git filter-branch
修改過信息的提交和由這個Gerrit Code Review server
創建的合並提交時有用.
在etc/gerrit.config
可以配置Server
的用戶名和郵箱,user.name
默認值Gerrit Code Review
, user.email
默認值在啟動時生成gerrit@hostname
Owner
允許修改項目以下配置:
- 改變項目描述
- 通過SSH創建新的分支
- 通過Web界面創建和刪除分支
- 賦予和撤銷任何訪問權限,包括
Owner
權限
子命名空間的所有權可以通過命名空間格式來委派. 要委派以qa/
開始的所有分支權限給QA群組,給refs/heads/qa/*
添加Owner
權限。 QA小組的成員可以進一步細分訪問權限,但只能對refs/heads/qa/
開始的分支有效.
Push
這類分支控制用戶如何上傳提交到Gerrit. 根據命名空間賦予的Push
權限, 可以允許繞過代碼審查直接推送到分支, 也可以允許創建新的change
進行代碼審查.
Direct Push
在Direct Push
權限下,任何已經存在的分支都接收fast-forward
提交,創建新的分支需要Create Reference
權限. 刪除已經存在的分支會被拒絕,因為在這個最安全的模式下, 提交不會被丟棄.
Force選項
允許分支被刪除. 由於force push
實際上刪除分支后會創建這個分支,但是這是個原子操作並且會被記錄,也允許force push
更新分支. 帶有force
選項會導致項目歷史中的提交被丟棄.
force
選項對只想使用Gerrit訪問權限功能而不需要代碼審查的項目有效, 對於需要進行代碼審查的項目不應該分配這個權限.
Upload To Code Review
Upload To Code Review
權限授權在refs/for/refs/heads/BRANCH
命名空間上,允許用戶上傳non-merge
提交到refs/for/BRANCH
命名空間,創建新的change
進行代碼審查.
用戶在自己環境下提交代碼需要clone/fetch
項目代碼,所以必須賦予Read
權限
對於開源公開的Gerrit安裝方式,All-Projects
中refs/for/refs/heads/*
通常給Registered Users
賦予Read
和Push
權限. 很多私有安裝, 通常refs/for/refs/heads/*
通常給all users
簡單的賦予Read
和Push
權限.
force
選項賦予refs/for/refs/heads/*
命名空間沒有作用.
Push Merge Commits
Push Merge Commits
權限允許用戶上傳merge commits
.這是Push
附加的訪問權限,所以只賦予Push Merge Commits
權限是不夠的. 一些項目希望只能由Gerrit自動合並提交, 可以通過只賦予Push
權限而不賦予Push Merge Commit
權限.
賦予Push Merge Commit
權限通常必須以refs/for/
為前綴,例如refs/for/refs/heads/BRANCH
. refs/heads/BRANCH
作為補充, 賦予Read
權限后允許直接推送non-merge
提交,賦予Push Merge Commit
權限后也允許直接提交一個merge
提交.
Push Annotated Tag
允許推送帶注釋的標簽
到遠程倉庫, 標簽必須帶有注釋
.
#創建帶注釋的標簽
git tag -a <tagname> -m <comment>
#提交標簽到遠程倉庫
git push origin --tags
#獲取標簽
git fetch --tags123456
標簽的email
一定會與提交者的郵箱進行驗證,如果推送其他人的標簽需要同時賦予Push Annotated Tag
和Forge Committer Identity
權限.
git show v1.0
tag v1.0
Tagger: username <email>123
如果需要推送輕量級標簽
(不帶注釋
), 給refs/tags/*
命名空間賦予Create Reference
權限, 輕量級標簽就像Git中的分支一樣.
如果需要刪除或者重寫標簽, 給refs/tags/*
命名空間賦予帶force選項的Push
權限,刪除標簽需要和刪除分支一樣的權限.
Push Signed Tag
允許推送PGP簽證
的標簽到遠程倉庫
git tag -u "gpg-key-id" -m "tag comment" <tagname>1
Read
Read
權限控制查看項目的change
,comment
,code diff
和通過SSH或者HTTP協議訪問倉庫的權限
這個權限非常特殊, 先計算項目中的Read
權限, 再計算all-projects
的Read
權限.
如果項目中賦予DENY Read
權限,all-projects
項目不管是否賦予ALLOW READ
都將無效.這個權限對於隱藏一些項目非常有用.
Rebase
允許用戶在web頁面上進行rebase changes
, change
作者和提交者可以通過頁面進行rebase changes
(盡管沒有賦予Rebase
權限)
Remove Reviewer
允許用戶從審查者列表中移除其他用戶.
Change owners
能夠移除那些審查分數為0或者負數的審查者.(盡管沒有賦予Remove Reviewer
權限)
Project owners
和site administrators
能夠移除任何審查者(盡管沒有賦予Remove Reviewer
權限)
其他用戶只能將他們自己從審查者列表中移除.
Review Labels
在項目中配置label My-Name
,label My-Name
和定義好的范圍分數相關聯. 同時也關聯labelAs-My-Name
權限, 可以允許編輯用戶定義的label
.
Gerrit帶有配置好的Code-Review
標簽
[access "refs/heads/*"]
label-Code-Review = -2..+2 group Administrators
label-Code-Review = -2..+2 group Project Owners
label-Code-Review = -1..+1 group Registered Users
[label "Code-Review"]
function = MaxWithBlock
defaultValue = 0
copyMinScore = true
copyAllScoresOnTrivialRebase = true
value = -2 This shall not be merged
value = -1 I would prefer this is not merged as is
value = 0 No score
value = +1 Looks good to me, but someone else must approve
value = +2 Looks good to me, approved1234567891011121314
Submit
允許用戶提交審查通過的提交. 提交審查代碼后會合並到對應的分支上.
The label that the reviewer selects determines what can happen next. The +1 and -1 level are just an opinion where as the +2 and -2 levels are allowing or blocking the change. In order for a change to be accepted it must have at least one +2 and no -2 votes. Although these are numeric values, they in no way accumulate; two +1s do not equate to a +2.
Code-Review
標簽+2
是通過,-2
是否定, -1~+1
只是代表意見並不會影響投票, 審查被通過至少需要一個+2
投票並且沒有-2
投票. 兩個+1
並不會等於+2
[access "refs/heads/*"]
submit = group Administrators
submit = group Project Owners123
View Drafts
允許用戶查看其他人提交的draft changes
.
draft changes
作者和添加為審查者都能看見draft changes
(盡管沒有賦予View Drafts
權限)
Publish Drafts
允許用戶公開其他人提交的draft changes
.
draft changes
作者可以公開draft changes
(盡管沒有賦予Publish Drafts
權限)
Delete Drafts
允許用戶刪除其他人提交的draft changes
.
draft changes
作者可以刪除draft changes
(盡管沒有賦予Delete Drafts
權限)
Edit Topic Name
允許修改change
的主題topic
change owner, branch owners, project owners, and site administrators
可以修改主題(盡管沒有賦予Edit Topic Name
權限)
Enforcing site wide access policies
通過賦予一個群組Owner
訪問權限在refs/*
命名空間, Gerrit管理員可以委派這個項目的訪問控制權限給這個群組.
如果需要沒有一個人能更新或者刪除標簽, 連項目owners
都沒有權限. ALLOW
和DENY
規則並不能達到這樣的目的, 因為項目owners
可以賦予任何他們自己想要的訪問權限. 覆蓋任何從All-Projects
或者其他父項目繼承的權限是非常有效的方法.
在父項目中BLOCK
權限, 使得就算是子項目owners
也不能設置block
權限為ALLOW
. 盡管這樣, 也應該保留owners
所有non-blocked
權限.
- Gerrit管理員能夠集中精力管理
site wide
策略並且提供有意義的默認訪問權限. - 在不違反
site wide
策略的情況下, 項目owners
可以管理他們自己項目的訪問權限.
‘BLOCK’ access rule
BLOCK
規則是全局范圍的權限. 子項目不能重載繼承的BLOCK
規則. 從父項目鏈表中搜索BLOCK
規則, 忽略在訪問區域中的獨占(Exclusive
)標志.
push
權限賦予BLOCK
規則, push
和force push
等推送都將被阻塞. force push
權限賦予BLOCK
規則只有force push
被阻塞, 但是如果push
權限具有ALLOW
規則的話可以進行non-forced
提交.
BLOCK
也可以賦予label
投票范圍. 下面的配置可以阻塞group X
投+2
和-2
票,仍然可以投-1 ~ +1
的票.
[access "refs/heads/*"]
label-Code-Review = block -2..+2 group X12
在這個阻塞規則min..max
范圍的目的是: 阻塞-INFINITE..min
和max..INFINITE
投票,也意味着-1..+1
投票范圍不受阻塞影響.
BLOCK’ and ‘ALLOW’ rules in the same access section
當相同訪問區域同時包含BLOCK
和ALLOW
規則, ALLOW
規則會重載BLOCK
規則.
[access "refs/heads/*"]
push = block group X
push = group Y123
如果群組X
和群組Y
都包含了同一個用戶, 這個用戶依然能夠push
到refs/heads/*
命名空間.
在同一個項目的同一個訪問區域,ALLOW規則才會重載
BLOCK規則.在同一個項目不同訪問區域和子項目的同一個訪問區域, ALLOW
規則不會重載BLOCK
規則.
BLOCK
規則示例
確保沒有人能夠更新或者刪除tag
在All-Projects
中阻塞Anonymous Users
組的push
權限
[access "refs/tags/*"]
push = block group Anonymous Users12
由於所有人都是Anonymous Users
組成員, 所以可以阻塞所有人.
可能項目owner
需要創建tag
權限
[access "refs/tags/*"]
push = block group Anonymous Users
pushTag = group Project Owners
pushSignedTag = group Project Owners1234
某個命名空間只讓一個特殊的群組投票
假設提交到發布分支Release-Process
需要更為嚴格的過程, 假設我們需要確信只有Release Engineers
群組可以投票,就算是項目owner
權限也不可以投票. 在All-Projects
我們定義下面的規則.
[access "refs/heads/stable*"]
label-Release-Process = block -1..+1 group Anonymous Users
label-Release-Process = -1..+1 group Release Engineers123
Global Capabilities
Access Database
允許用戶通過gsql
命令訪問數據庫, 以及包含代碼審查信息的分支refs/notes/review
Administrate Server
影響Gerrit中owner
和administrator
角色. 賦予administrateServer
能力能夠賦予任何群組訪問權限.
Priority
Gerrit中有兩類線程池用來給INTERACTIVE Users
和Non-Interactive Users
使用,防止搶占線程.
允許其他用戶使用Non-Interactive Users
的保留線程池.
- 默認配置, 用戶默認使用
INTERACTIVE
線程池 - BATCH, 賦予這個群組的用戶使用獨立的
Non-Interactive
線程池 - INTERACTIVE, 除非用戶賦予了
BATCH
選項,否則使用INTERACTIVE
線程池
Stream Events 允許執行Gerrit觸發的事件流.
獲取All-Projects
中refs/meta/config
分支並修改權限配置
git clone ssh://admin@localhost:29418/All-Projects && scp -p -P 29418 admin@localhost:hooks/commit-msg All-Projects/.git/hooks/
#refs/meta/config 是All-Projects的引用
git fetch origin refs/meta/config:refs/remotes/origin/meta/config
git checkout meta/config
#現在目錄下有groups project.config兩個文件
#groups文件包含project.config中需要的用戶組和對應的UUID
#提交修改
git add .
git commit -m "modify config"
git push origin meta/config:meta/config123456789101112
在公司文檔看到大神寫的很不錯的一小段話
code review的目的是團隊成員在一起共同學習,而不是相互”挑錯”.將code review稱為
代碼回顧
好一些, 如果大家放棄”挑錯”來共同學習,那么代碼回顧中學習什么呢?
代碼回顧的學習重點是團隊成員共同識別模式,這里的模式是指程序員編寫代碼的習慣,包括”好模式”和”反模式”. 像富有表達力的命名, 單一職責的方法, 良好的格式縮進等,都是”好模式”. 團隊成員通過閱讀最近編寫的測試代碼和生產代碼來識別”好模式”和”反模式”.既是團隊成員之間相互學習的過程, 也是團隊整體達成整潔代碼共識的過程.