Android下的配置管理之道之gerrit自動備份分支ref-protection插件

最近研究了一個gerrit自動備份分支的插件。

Ref protection 直譯過來就是 引用保護.也就是保護 git下面 refs 的一個插件

Ref protection plugin.

Protects against commits being lost by creating backups of deleted refs (or non-fast-forward commits) under the refs/backups/ namespace.

Branch deletion protection can be disabled by setting plugin.ref-protection.protectDeleted false in gerrit.config. Similarly, non-fast-forward update protection can be disabled with plugin.ref-protection.protectFastForward false.

Branches under refs/heads/ that are deleted or rewritten are backed up as refs/backups/heads/branch-name-YYYYMMDD-HHmmss by default, or as sequentially increasing numbers under refs/backups/heads/branch-name/# by setting plugin.ref-protection.useTimestamp false.

Tags under refs/tags/ that are deleted are backed up (as branches) as refs/backups/tags/tag-name-YYYYMMDD-HHmmss or as sequentially increasing numbers under refs/backups/tags/branch-name/# using the same plugin.ref-protection.useTimestamp setting.

By default, the backups are created as branches. Optionally, they may be created as tags, containing information about the original ref that was changed, as well as the user that performed the change. This can be enabled by setting plugin.ref-protection.createTag true.

根據說明 是當在gerrit上刪除分支/或者採用了 git 強制push的時候,會觸發這個備份分支的動作。
在使用過程中發現,git 強制push的時候會報如下的錯誤。通過分析發現是 git push的這個賬號沒有
在 refs/backups/* 下面有 create refs 的權限。加上這個權限就不會報錯了。
不過總覺得這個不合理。你管我怎麼操作的,你都要給我備份了就行了。


[2019-12-31 16:23:13,294] [ReceiveCommits-1] ERROR com.googlesource.gerrit.plugins.refprotection.BackupRef : CreateBranch.Input: refs/backups/heads/test_for_20191231_162313-5130c6f4d1dd84a9eae13eca14e627db50f843bd
[2019-12-31 16:23:13,294] [ReceiveCommits-1] ERROR com.googlesource.gerrit.plugins.refprotection.BackupRef : CreateBranch.Input: com.google.gerrit.server.project.CreateBranch$Factory
[2019-12-31 16:23:13,294] [ReceiveCommits-1] ERROR com.googlesource.gerrit.plugins.refprotection.BackupRef : project: com.google.gerrit.server.project.ProjectResource@55f9da39
[2019-12-31 16:23:13,297] [ReceiveCommits-1] ERROR com.googlesource.gerrit.plugins.refprotection.BackupRef : Cannot create "refs/backups/heads/test_for_20191231_162313"
com.google.gerrit.extensions.restapi.AuthException: Cannot create "refs/backups/heads/test_for_20191231_162313"
	at com.google.gerrit.server.project.CreateBranch.apply(CreateBranch.java:138)
	at com.googlesource.gerrit.plugins.refprotection.BackupRef.createBackup(BackupRef.java:162)
	at com.googlesource.gerrit.plugins.refprotection.RefUpdateListener.onEvent(RefUpdateListener.java:92)
	at com.google.gerrit.common.ChangeHookRunner.fireEventForUnrestrictedListeners(ChangeHookRunner.java:742)
	at com.google.gerrit.common.ChangeHookRunner.fireEvent(ChangeHookRunner.java:789)
	at com.google.gerrit.common.ChangeHookRunner.doRefUpdatedHook(ChangeHookRunner.java:610)
	at com.google.gerrit.server.git.ReceiveCommits.processCommands(ReceiveCommits.java:662)
	at com.google.gerrit.server.git.AsyncReceiveCommits$Worker.run(AsyncReceiveCommits.java:89)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at com.google.gerrit.server.util.RequestScopePropagator$5.call(RequestScopePropagator.java:222)
	at com.google.gerrit.server.util.RequestScopePropagator$4.call(RequestScopePropagator.java:201)
	at com.google.gerrit.server.util.ThreadLocalRequestScopePropagator$1.call(ThreadLocalRequestScopePropagator.java:55)
	at com.google.gerrit.server.util.RequestScopePropagator$1.call(RequestScopePropagator.java:98)
	at com.google.gerrit.server.util.RequestScopePropagator$2.run(RequestScopePropagator.java:131)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
	at com.google.gerrit.server.git.WorkQueue$Task.run(WorkQueue.java:376)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)


在 refs/backups/* 下面有 create refs 的權限
-[access "refs/backups/*"]
-	create = group Administrators



下面這個是在gerrit上刪除分支 觸發的 打印的日誌。

[2019-12-31 16:21:26,179] [HTTP-71] INFO  com.googlesource.gerrit.plugins.refprotection.RefUpdateListener : Ref Deleted: project [git/shared/tools/blog] refname [refs/heads/test4] old object id [5130c6f4d1dd84a9eae13eca14e627db50f843bd]
[2019-12-31 16:21:26,180] [HTTP-71] ERROR com.googlesource.gerrit.plugins.refprotection.BackupRef : CreateBranch.Input: refs/backups/heads/test4_for_20191231_162126-5130c6f4d1dd84a9eae13eca14e627db50f843bd
[2019-12-31 16:21:26,180] [HTTP-71] ERROR com.googlesource.gerrit.plugins.refprotection.BackupRef : CreateBranch.Input: com.google.gerrit.server.project.CreateBranch$Factory
[2019-12-31 16:21:26,180] [HTTP-71] ERROR com.googlesource.gerrit.plugins.refprotection.BackupRef : project: com.google.gerrit.server.project.ProjectResource@2ad678a6


下面準備通過源碼來 跟蹤一下執行過程,看看爲啥會有這個區別。或者爲啥會有這個報錯。

準備工作

gerrit 2.12.x 版本

從github克隆插件源代碼。並且檢出到 2.12的分支上。
~/gerrit/plugins/ref-protection
$ git ll
*   3422dca - Merge branch 'stable-2.11' into master                                                                                   — Doug Kelly (HEAD, origin/stable-2.12) - (4 年 2 個月前)
|\  
| * 0359382 - Fix buck test in standalone BUCK build                                                                                   — David Ostrovsky - (4 年 7 個月前)
| * 31473ff - Add standalone BUCK build                                                                                                — David Pursehouse - (4 年 7 個月前)
* | 0b80a00 - Add documentation updates                                                                                                — Doug Kelly - (4 年 5 個月前)
* | bc23cba - Add details from original tag                                                                                            — Doug Kelly - (4 年 3 個月前)
* | 7ca1b83 - Add ability to back up as tag                                                                                            — Doug Kelly - (4 年 3 個月前)
* | 164b578 - Correct backup of tags                                                                                                   — Doug Kelly - (4 年 2 個月前)
* | 241b34a - Switch to EventListener                                                                                                  — Doug Kelly - (4 年 3 個月前)
* | 6367acf - Add configuration for backup branch names                                                                                — Doug Kelly - (4 年 3 個月前)
* | a711e12 - Add configuration for levels of protection                                                                               — Doug Kelly - (4 年 3 個月前)
* | 95d2f2c - Fix MissingObjectException when checking for non-ff update                                                               — Doug Kelly - (4 年 3 個月前)
* | 007313a - Refactor backup creation to BackupRef                                                                                    — Doug Kelly - (4 年 6 個月前)
|/  
* 7d6c9c6 - Add missing licence headers                                                                                              — David Pursehouse - (4 年 7 個月前)
* 9d3c6e2 - Convert to use auto-closeable Repository and RevWalk                                                                     — David Pursehouse - (4 年 10 個月前)
* 72eebe7 - Create backup branches under refs/backups/                                                                               — David Pursehouse - (5 年前)
* ea03470 - Fix a couple of minor style nits                                                                                         — David Pursehouse - (5 年前)
* 27c081e - Add manifest entries in BUCK file                                                                                        — David Pursehouse - (5 年前)
* 3c9f593 - Handle non-fast-forward pushes                                                                                           — Arun Kumar - (5 年前)
* a17c079 - Added backup branch creation for deleted refs                                                                            — Arun Kumar - (6 年前)
* f5cf43e - Initial stub implementation                                                                                              — David Pursehouse - (6 年前)
* df617dc - Initial empty commit                                                                                                     — David Pursehouse - (6 年前)


從github克隆gerrit源代碼。並且檢出到 origin/stable-2.12 的分支上
*   84f29ff - Merge branch 'stable-2.11' into stable-2.12                                                                              — David Pursehouse (HEAD, origin/stable-2.12) - (12 個月前)
|\  
| *   a53bbb0 - Merge branch 'stable-2.10' into stable-2.11                                                                              — David Pursehouse (origin/stable-2.11) - (12 個月前)
| |\  
| | *   ed2d5ce - Merge branch 'stable-2.9' into stable-2.10                                                                               — David Pursehouse (origin/stable-2.10) - (12 個月前)
| | |\  
| | | * 5c6e69a - Consume JGit artifacts from Maven Central                                                                                — David Pursehouse (origin/stable-2.9) - (12 個月前)
| | * | 51a1fa3 - Add release notes for Gerrit v2.10.8                                                                                     — Luca Milanesio - (12 個月前)
| | * |   8943b0c - Merge branch 'stable-2.9' into stable-2.10                                                                               — Luca Milanesio - (12 個月前)
| | |\ \  
| | | |/  
| | | * decc35e - Add release notes for Gerrit v2.9.5                                                                                      — Luca Milanesio - (12 個月前)
| | | * 2434df4 - Set version to 2.9.5                                                                                                     — Luca Milanesio (tag: v2.9.5) - (12 個月前)
| | * | b5290de - Set version to 2.10.8                                                                                                    — Luca Milanesio (tag: v2.10.8) - (12 個月前)
| * | | ec3ba0c - Set version to 2.11.12                                                                                                   — Luca Milanesio (tag: v2.11.12) - (12 個月前)
* | | | 57ceed8 - Set version to 2.12.9                                                                                                    — Luca Milanesio (tag: v2.12.9) - (12 個月前)
* | | |   08dd052 - Merge branch 'stable-2.11' into stable-2.12                                                                              — Luca Milanesio - (12 個月前)
|\ \ \ \  
| |/ / /  
| * | |   043b101 - Merge branch 'stable-2.10' into stable-2.11                                                                              — Luca Milanesio - (12 個月前)
| |\ \ \  


編譯gerrit 2.12.x版本需要用到buck工具

在github上克隆https://github.com/facebook/buck.git用到buck工具

通過gerrit代碼中的.buckversion文件決定 buck 工具的版本,
$ cat .buckversion 
1b03b4313b91b634bd604fc3487a05f877e59dee

克隆完成buck工具,切換檢出到 1b03b4313b91b634bd604fc3487a05f877e59dee 這個節點。
* 1b03b43 - Add some support for running go tests.                                                                         
* 1a6880e - Revert "Add some support for running go tests."                                                                
* 0b581a2 - C/C++: remove lex/yacc support                                                                                 
* bd13811 - Add some support for running go tests.                                                                         
* 8979c16 - Update to build-tools-23.0.2 in Travis                                                                         
* 2c883f1 - Represent code sign identity fingerprint as Optional<HashCode>                                                 
* f23f93e - Introduce paths-only target hash file mode                                                                     
* 2e5ed11 - Default to BSER output from buck.py and remove JSON output parser                                              
* c22418c - [halide] Build "universal" binaries for Halide libraries                                                       
* d42cabf - Remove unexracted download artifacts                                                                           
* f097b5e - Install the NDK to run those tests                                                                             
* 47b9ee8 - Test Java 7 with CI as well                                                                                    
* a7f980b - Remember Watchman warnings encountered during query so we can pass them to Watchman glob handler               
* f1238db - Easy: Remove unused interface ProjectFilesystemWatcher

編譯buck工具,需要ant工具, 從網上下載ant工具就行,添加ant到環境變量 PATH
然後到 buck 目錄執行 ant 命令,編譯出來 buck 工具。

buck編譯完成後在 $HOME/bin 目錄下面 創建 buck 的軟連接。
$ ll ~/bin/buck
lrwxrwxrwx 1 mamh mamh 29 11月 11  2018 /home/mamh/bin/buck -> /work/buck/bin/buck*


編譯 gerrit 和 插件 

buck build release 

需要修改plugin/BUCK 文件
BASE = get_base_path()
CORE = [
  'commit-message-length-validator',
  'download-commands',
  'replication',
  'reviewnotes',
  'singleusergroup',
  'ref-protection'
]

插件生成位置: buck-out/gen/plugins/ref-protection/ref-protection.jar

或者不修改 BUCK文件 而 值編譯 這個插件本身
buck build plugins/ref-protection

報錯的地方 plugins/ref-protection/src/main/java/com/googlesource/gerrit/plugins/refprotection/BackupRef.java

} else {
    CreateBranch.Input input = new CreateBranch.Input();
    input.ref = backupRef;
    // We need to parse the commit to ensure if it's a tag, we get the
    // commit the tag points to!
    input.revision = ObjectId.toString(revWalk.parseCommit(ObjectId.fromString(event.refUpdate.oldRev)).getId());
    log.error("CreateBranch.Input: " + String.format("%s-%s",input.ref, input.revision));
    try {
        log.error("CreateBranch.Input: "+ createBranchFactory);
        log.error("project: " +  project);
        createBranchFactory.create(backupRef).apply(project, input);
    } catch (BadRequestException | AuthException | ResourceConflictException | IOException e) {
        log.error(e.getMessage(), e);
    }
}

通過打印 RefControl 對象,我們發現兩種操作() 時候的 RefControl 對象基本上沒啥差異

RefControl{
projectControl=
	ProjectControl{
		uploadGroups=
		[global%3ARegistered-Users, global%3AAnonymous-Users], receiveGroups=[global%3ARegistered-Users]
		, canonicalWebUrl='http://gerrit.example.com:8080/'
		, user=IdentifiedUser[account 1000000]
		, state=com.google.gerrit.server.project.ProjectState@151533ed
		, repoManager=com.google.gerrit.server.git.LocalDiskRepositoryManager@63fa17dc
		, changeControlFactory=com.google.gerrit.server.project.ChangeControl$AssistedFactory
		, permissionFilter=com.google.gerrit.server.project.PermissionCollection$Factory@2b652749
		, contributorAgreements=[]
		, tagCache=com.google.gerrit.server.git.TagCache@57e993dd
		, changeCache=com.google.gerrit.server.git.SearchingChangeCacheImpl@6b5f5896
		, allSections=[com.google.gerrit.server.project.SectionMatcher@4119ca1d, 
						com.google.gerrit.server.project.SectionMatcher@5093a140, 
						com.google.gerrit.server.project.SectionMatcher@4f92e3c2,
						com.google.gerrit.server.project.SectionMatcher@3bfc8530, 
						com.google.gerrit.server.project.SectionMatcher@34bae970]
		, localSections=null
		, labelTypes=null
		, declaredOwner=null
	}
, refName='refs/backups/heads/test5_for_20200109_181945'
, relevant=PermissionCollection{rules={read=[group Administrators, group Anonymous Users]}, overridden={}, ruleProps={group Administrators=ProjectRef{project=All-Projects, ref=refs/*}, group Anonymous Users=ProjectRef{project=All-Projects, ref=refs/*}}, perUser=false}
, effective={}
, owner=null
, canForgeAuthor=null
, canForgeCommitter=null
, isVisible=null
}


RefControl{
projectControl=
	ProjectControl{
	uploadGroups=[global%3ARegistered-Users, global%3AAnonymous-Users], receiveGroups=[global%3ARegistered-Users]
		, canonicalWebUrl='http://gerrit.example.com:8080/'
		, user=IdentifiedUser[account 1000000]
		, state=com.google.gerrit.server.project.ProjectState@151533ed
		, repoManager=com.google.gerrit.server.git.LocalDiskRepositoryManager@63fa17dc
		, changeControlFactory=com.google.gerrit.server.project.ChangeControl$AssistedFactory
		, permissionFilter=com.google.gerrit.server.project.PermissionCollection$Factory@2b652749
		, contributorAgreements=[]
		, tagCache=com.google.gerrit.server.git.TagCache@57e993dd
		, changeCache=com.google.gerrit.server.git.SearchingChangeCacheImpl@6b5f5896
		, allSections=[com.google.gerrit.server.project.SectionMatcher@4119ca1d, 
					com.google.gerrit.server.project.SectionMatcher@5093a140,
					com.google.gerrit.server.project.SectionMatcher@4f92e3c2,
					com.google.gerrit.server.project.SectionMatcher@3bfc8530, 
					com.google.gerrit.server.project.SectionMatcher@34bae970]
		, localSections=null
		, labelTypes=null
		, declaredOwner=null
	}
, refName='refs/backups/heads/test5_for_20200109_182142'
, relevant=PermissionCollection{rules={read=[group Administrators, group Anonymous Users]}, overridden={}, ruleProps={group Administrators=ProjectRef{project=All-Projects, ref=refs/*}, group ; Users=ProjectRef{project=All-Projects, ref=refs/*}}, perUser=false}
, effective={}
, owner=null
, canForgeAuthor=null
, canForgeCommitter=null
, isVisible=null
}

下面是在gerrit上操作刪除分支的日誌

[2020-01-09 18:43:32,983] [HTTP-62] INFO  com.google.gerrit.server.project.CreateBranch : ===========================================
[2020-01-09 18:43:32,985] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : ReviewDb = com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$20@188ac92c
[2020-01-09 18:43:32,985] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : RevWalk = org.eclipse.jgit.revwalk.ObjectWalk@41980182
[2020-01-09 18:43:32,985] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : RevObject = commit 2f335d90bca227f7c8d115990081c5dcf6be5ac5 1573610871 -----p
[2020-01-09 18:43:32,985] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : if (object instanceof RevCommit) { start
[2020-01-09 18:43:32,985] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : (admin || (owner && !isBlocked(Permission.CREATE))) 

下面是 強制 push輸出的日誌

[2020-01-09 18:44:32,117] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.CreateBranch : ===========================================
[2020-01-09 18:44:32,118] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : ReviewDb = com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$20@7b303c26
[2020-01-09 18:44:32,118] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : RevWalk = org.eclipse.jgit.revwalk.ObjectWalk@17c09ed9
[2020-01-09 18:44:32,118] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : RevObject = commit 2f335d90bca227f7c8d115990081c5dcf6be5ac5 1573610871 -----p
[2020-01-09 18:44:32,118] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : if (object instanceof RevCommit) { start
[2020-01-09 18:44:32,118] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : else if (!canPerform(Permission.CREATE)) 

繼續追蹤代碼

通過之前 push時候報錯 我追蹤到 這裏 plugins/ref-protection/src/main/java/com/googlesource/gerrit/plugins/refprotection/BackupRef.java
try {
    createBranchFactory.create(backupRef).apply(project, input);
} catch (BadRequestException | AuthException | ResourceConflictException | IOException e) {
    log.error(e.getMessage(), e);
}
          
繼續追蹤代碼執行找到這個文件 gerrit-server/src/main/java/com/google/gerrit/server/project/CreateBranch.java 中的apply()方法處
報錯的地方 直接找到這個處
rw.reset();
if (!refControl.canCreate(db.get(), rw, object)) {
    throw new AuthException("Cannot create \"" + ref + "\"");
}
到這裏找到了 報錯的地方, 也就是if判斷過後 主動 拋出了一個異常,到這裏的代碼都不屬於 插件的代碼了.
[2020-01-09 18:44:32,119] [ReceiveCommits-2] ERROR com.googlesource.gerrit.plugins.refprotection.BackupRef : Cannot create "refs/backups/heads/test5_for_20200109_184432"
com.google.gerrit.extensions.restapi.AuthException: Cannot create "refs/backups/heads/test5_for_20200109_184432"
	at com.google.gerrit.server.project.CreateBranch.apply(CreateBranch.java:144)
	at com.googlesource.gerrit.plugins.refprotection.BackupRef.createBackup(BackupRef.java:166)
	at com.googlesource.gerrit.plugins.refprotection.RefUpdateListener.onEvent(RefUpdateListener.java:103)
	at com.google.gerrit.common.ChangeHookRunner.fireEventForUnrestrictedListeners(ChangeHookRunner.java:742)
	at com.google.gerrit.common.ChangeHookRunner.fireEvent(ChangeHookRunner.java:789)
	at com.google.gerrit.common.ChangeHookRunner.doRefUpdatedHook(ChangeHookRunner.java:610)
	at com.google.gerrit.server.git.ReceiveCommits.processCommands(ReceiveCommits.java:662)
	at com.google.gerrit.server.git.AsyncReceiveCommits$Worker.run(AsyncReceiveCommits.java:89)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at com.google.gerrit.server.util.RequestScopePropagator$5.call(RequestScopePropagator.java:222)
	at com.google.gerrit.server.util.RequestScopePropagator$4.call(RequestScopePropagator.java:201)
	at com.google.gerrit.server.util.ThreadLocalRequestScopePropagator$1.call(ThreadLocalRequestScopePropagator.java:55)
	at com.google.gerrit.server.util.RequestScopePropagator$1.call(RequestScopePropagator.java:98)
	at com.google.gerrit.server.util.RequestScopePropagator$2.run(RequestScopePropagator.java:131)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
	at com.google.gerrit.server.git.WorkQueue$Task.run(WorkQueue.java:376)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

繼續追蹤代碼

繼續追蹤代碼 refControl.canCreate(db.get(), rw, object) 的執行

繼續定位,發現在 refControl.canCreate() 方法 中 兩種操作() 有不同了. 一個返回了false,一個返回true.

我們在  canCreate() 方法中 加上 日誌輸出 從而判斷 return true/false 是 在哪裏執行的return.
if (object instanceof RevCommit) {
    log.info("if (object instanceof RevCommit) { start");
    if (admin || (owner && !isBlocked(Permission.CREATE))) {
        // Admin or project owner; bypass visibility check.
        log.info("(admin || (owner && !isBlocked(Permission.CREATE))) "); 下面是在gerrit上操作刪除分支的日誌
        return true;
    } else if (!canPerform(Permission.CREATE)) {     
        log.info("else if (!canPerform(Permission.CREATE)) ");   強制 push輸出的日誌
        return false;
    } 
    
到這裏找到了
一種情況走到了 if (admin || (owner && !isBlocked(Permission.CREATE))) { 判斷,然後直接返回true了.

另外一種情況走到了 } else if (!canPerform(Permission.CREATE)) { 判斷,  然後直接返回 false 了.

下面就要分析 爲什麼兩種操作 走的 不同的 if else 語句了

我們在  canCreate() 方法中 繼續加上更多的  日誌輸出

public boolean canCreate(ReviewDb db, RevWalk rw, RevObject object) {
    log.info("ReviewDb = " + db);
    log.info("RevWalk = " + rw);
    log.info("RevObject = " + object);

    log.info("getUser() = " + getUser()); //IdentifiedUser[account 1000000]
    log.info("getUser().getAccessPath() = " + getUser().getAccessPath());
    log.info("getUser().getCapabilities().canAdministrateServer() = " + getUser().getCapabilities().canAdministrateServer());

    if (!canWrite()) {
        log.info("canWrite = " + canWrite());
        return false;
    }
    boolean owner;
    boolean admin;
    switch (getUser().getAccessPath()) {
        case REST_API:
        case JSON_RPC:
        case UNKNOWN:
            owner = isOwner();
            admin = getUser().getCapabilities().canAdministrateServer();
            break;

        default:
            owner = false;
            admin = false;
    }

下面是在gerrit上直接操作的輸出日誌
[2020-01-09 19:55:35,726] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : ReviewDb = com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$20@3ca80f6c
[2020-01-09 19:55:35,726] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : RevWalk = org.eclipse.jgit.revwalk.ObjectWalk@7594c212
[2020-01-09 19:55:35,726] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : RevObject = commit c620bcc00a0cefbfcb760ca4185dd0269b9bb409 1573610856 -----p
[2020-01-09 19:55:35,726] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : getUser() = IdentifiedUser[account 1000000]
[2020-01-09 19:55:35,726] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : getUser().getAccessPath() = REST_API
[2020-01-09 19:55:35,726] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : getUser().getCapabilities().canAdministrateServer() = true
[2020-01-09 19:55:35,726] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : if (object instanceof RevCommit) { start
[2020-01-09 19:55:35,726] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : (admin || (owner && !isBlocked(Permission.CREATE))) 


[2020-01-09 19:56:12,372] [HTTP-71] INFO  com.google.gerrit.server.project.RefControl : ReviewDb = com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$20@739b8695
[2020-01-09 19:56:12,372] [HTTP-71] INFO  com.google.gerrit.server.project.RefControl : RevWalk = org.eclipse.jgit.revwalk.ObjectWalk@98832ac
[2020-01-09 19:56:12,372] [HTTP-71] INFO  com.google.gerrit.server.project.RefControl : RevObject = commit 5130c6f4d1dd84a9eae13eca14e627db50f843bd 1577691879 -----p
[2020-01-09 19:56:12,372] [HTTP-71] INFO  com.google.gerrit.server.project.RefControl : getUser() = IdentifiedUser[account 1000000]
[2020-01-09 19:56:12,372] [HTTP-71] INFO  com.google.gerrit.server.project.RefControl : getUser().getAccessPath() = REST_API
[2020-01-09 19:56:12,372] [HTTP-71] INFO  com.google.gerrit.server.project.RefControl : getUser().getCapabilities().canAdministrateServer() = true
[2020-01-09 19:56:12,372] [HTTP-71] INFO  com.google.gerrit.server.project.RefControl : if (object instanceof RevCommit) { start
[2020-01-09 19:56:12,372] [HTTP-71] INFO  com.google.gerrit.server.project.RefControl : (admin || (owner && !isBlocked(Permission.CREATE))) 


下面是採用git push輸出的日誌
[2020-01-09 19:56:44,187] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : ReviewDb = com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$20@45bc3d47
[2020-01-09 19:56:44,187] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : RevWalk = org.eclipse.jgit.revwalk.RevWalk@368252f1
[2020-01-09 19:56:44,188] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : RevObject = commit c620bcc00a0cefbfcb760ca4185dd0269b9bb409 1573610856 -----p
[2020-01-09 19:56:44,188] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : getUser() = IdentifiedUser[account 1000000]
[2020-01-09 19:56:44,188] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : getUser().getAccessPath() = GIT
[2020-01-09 19:56:44,188] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : getUser().getCapabilities().canAdministrateServer() = true
[2020-01-09 19:56:44,188] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : if (object instanceof RevCommit) { start
[2020-01-09 19:56:44,188] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : else if (canUpdate())


[2020-01-09 19:57:36,970] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : ReviewDb = com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$20@6d1c1e42
[2020-01-09 19:57:36,970] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : RevWalk = org.eclipse.jgit.revwalk.ObjectWalk@281e8d85
[2020-01-09 19:57:36,970] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : RevObject = commit 2f335d90bca227f7c8d115990081c5dcf6be5ac5 1573610871 -----p
[2020-01-09 19:57:36,970] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : getUser() = IdentifiedUser[account 1000000]
[2020-01-09 19:57:36,970] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : getUser().getAccessPath() = GIT
[2020-01-09 19:57:36,970] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : getUser().getCapabilities().canAdministrateServer() = true
[2020-01-09 19:57:36,970] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : if (object instanceof RevCommit) { start
[2020-01-09 19:57:36,970] [ReceiveCommits-2] INFO  com.google.gerrit.server.project.RefControl : else if (!canPerform(Permission.CREATE)) 


通過日誌分析 我們發現 
 getUser().getAccessPath() = GIT 
 getUser().getAccessPath() = REST_API
這個2不一樣了

繼續加日誌分析


[2020-01-09 20:08:27,868] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : ReviewDb = com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$20@42530bd7
[2020-01-09 20:08:27,868] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : RevWalk = org.eclipse.jgit.revwalk.ObjectWalk@2a04d30b
[2020-01-09 20:08:27,868] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : RevObject = commit c620bcc00a0cefbfcb760ca4185dd0269b9bb409 1573610856 -----p
[2020-01-09 20:08:27,868] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : getUser() = IdentifiedUser[account 1000000]
[2020-01-09 20:08:27,868] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : getUser().getAccessPath() = REST_API
[2020-01-09 20:08:27,868] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : getUser().getCapabilities().canAdministrateServer() = true
[2020-01-09 20:08:27,869] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : owner = true
[2020-01-09 20:08:27,869] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : admin = true
[2020-01-09 20:08:27,869] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : if (object instanceof RevCommit) { start
[2020-01-09 20:08:27,869] [HTTP-62] INFO  com.google.gerrit.server.project.RefControl : (admin || (owner && !isBlocked(Permission.CREATE))) 

[2020-01-09 20:08:53,799] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : ReviewDb = com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$20@2996426b
[2020-01-09 20:08:53,799] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : RevWalk = org.eclipse.jgit.revwalk.ObjectWalk@68e4f072
[2020-01-09 20:08:53,799] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : RevObject = commit c620bcc00a0cefbfcb760ca4185dd0269b9bb409 1573610856 -----p
[2020-01-09 20:08:53,799] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : getUser() = IdentifiedUser[account 1000000]
[2020-01-09 20:08:53,800] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : getUser().getAccessPath() = REST_API
[2020-01-09 20:08:53,800] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : getUser().getCapabilities().canAdministrateServer() = true
[2020-01-09 20:08:53,800] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : owner = true
[2020-01-09 20:08:53,800] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : admin = true
[2020-01-09 20:08:53,800] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : if (object instanceof RevCommit) { start
[2020-01-09 20:08:53,800] [HTTP-64] INFO  com.google.gerrit.server.project.RefControl : (admin || (owner && !isBlocked(Permission.CREATE))) 




[2020-01-09 20:09:29,898] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : ReviewDb = com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$20@70fac7b8
[2020-01-09 20:09:29,898] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : RevWalk = org.eclipse.jgit.revwalk.ObjectWalk@385a985b
[2020-01-09 20:09:29,898] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : RevObject = commit 2f335d90bca227f7c8d115990081c5dcf6be5ac5 1573610871 -----p
[2020-01-09 20:09:29,898] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : getUser() = IdentifiedUser[account 1000000]
[2020-01-09 20:09:29,898] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : getUser().getAccessPath() = GIT
[2020-01-09 20:09:29,899] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : getUser().getCapabilities().canAdministrateServer() = true
[2020-01-09 20:09:29,899] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : default owner = false
[2020-01-09 20:09:29,899] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : default admin = false
[2020-01-09 20:09:29,899] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : if (object instanceof RevCommit) { start
[2020-01-09 20:09:29,899] [ReceiveCommits-1] INFO  com.google.gerrit.server.project.RefControl : else if (!canPerform(Permission.CREATE)) 

最終我們可以定位到這裏 
boolean owner;
boolean admin;
switch (getUser().getAccessPath()) {
    case REST_API:
    case JSON_RPC:
    case UNKNOWN:
        owner = isOwner();
        admin = getUser().getCapabilities().canAdministrateServer();
        log.info("owner = " + owner);
        log.info("admin = " + admin);
        break;

    default:

        owner = false;
        admin = false;
        log.info("default owner = " + owner);
        log.info("default admin = " + admin);
}
這個switch沒有判斷 等於 GIT 的這種情況,而是直接走到了default,這樣就會導致 owern和admin都是false了.
也就會報沒有權限創建refs/backups/*分支了.解決方法是 試着 在插件 那邊 把 getUser().getAccessPath()
的類型 改成 REST_API. 然後 最好能把 僅在push操作的時候 user 改成 admin 賬號.一般的gerrit 管理員 會
有 創建 refs/backups/* 的權限的.其中這裏我一致覺得 這個插件 做的不合理. 既然是備份分支,不管誰來操作,
你插件都應該給我備份上的.這個插件的安裝也是在管理員情況下面才能安裝的. 你備份分支還判斷 有沒有權限備份就太不合理了.

最終我給出了一個修改放啊,可以參考
https://github.com/mamh-java/plugins_ref-protection/tree/mamh-2.12.7

下面是 修改後 幾種操作的日誌輸出

git push fast forward的操作
[2020-01-10 17:39:35,744] [ReceiveCommits-1] not isRefDeleted or not NonFastForward: project [git/shared/tools/blog] refname [refs/heads/master1] oldRev [17b185ee7ee879242f38f8200c9855f530c5329b] newRev [bc071c0e21cad2a09c998af15b7b6ea90e5908a8]


git push  non fast forward的操作
[2020-01-10 17:40:01,026] [ReceiveCommits-1] this user want to delete ref or no fast forward update ref: IdentifiedUser[account 1000003]
[2020-01-10 17:40:01,026] [ReceiveCommits-1] Ref Deleted: project [git/shared/tools/blog] refname [refs/heads/master1] oldRev [bc071c0e21cad2a09c998af15b7b6ea90e5908a8] newRev [17b185ee7ee879242f38f8200c9855f530c5329b]
[2020-01-10 17:40:01,027] [ReceiveCommits-1] Ref  Backup: project [git/shared/tools/blog] refname [refs/heads/backup/master1_20200110_174001] oldRev [bc071c0e21cad2a09c998af15b7b6ea90e5908a8] newRev [17b185ee7ee879242f38f8200c9855f530c5329b]
[2020-01-10 17:40:01,045] [ReceiveCommits-1] not a relevant ref: project [git/shared/tools/blog] refname [refs/heads/backup/master1_20200110_174001] oldRev [0000000000000000000000000000000000000000] newRev [bc071c0e21cad2a09c998af15b7b6ea90e5908a8]


git push 刪除分支的操作
[2020-01-10 17:40:39,882] [ReceiveCommits-2] this user want to delete ref or no fast forward update ref: IdentifiedUser[account 1000003]
[2020-01-10 17:40:39,882] [ReceiveCommits-2] Ref Deleted: project [git/shared/tools/blog] refname [refs/heads/master1] oldRev [17b185ee7ee879242f38f8200c9855f530c5329b] newRev [0000000000000000000000000000000000000000]
[2020-01-10 17:40:39,883] [ReceiveCommits-2] Ref  Backup: project [git/shared/tools/blog] refname [refs/heads/backup/master1_20200110_174039] oldRev [17b185ee7ee879242f38f8200c9855f530c5329b] newRev [0000000000000000000000000000000000000000]
[2020-01-10 17:40:39,890] [ReceiveCommits-2] not a relevant ref: project [git/shared/tools/blog] refname [refs/heads/backup/master1_20200110_174039] oldRev [0000000000000000000000000000000000000000] newRev [17b185ee7ee879242f38f8200c9855f530c5329b]


gerrit網頁上創建分支輸入的日誌
[2020-01-10 17:42:24,059] [HTTP-65] not a relevant ref: project [git/shared/tools/blog] refname [refs/heads/sm8250_mp_zero] oldRev [0000000000000000000000000000000000000000] newRev [4fef20ecde1f67b20de9a4434bdbca568ffcb763]



gerrit網頁上刪除分支的日誌
[2020-01-10 17:42:44,435] [HTTP-63] this user want to delete ref or no fast forward update ref: IdentifiedUser[account 1000000]
[2020-01-10 17:42:44,435] [HTTP-63] Ref Deleted: project [git/shared/tools/blog] refname [refs/heads/sm8250_mp_zero_20200110] oldRev [4fef20ecde1f67b20de9a4434bdbca568ffcb763] newRev [0000000000000000000000000000000000000000]
[2020-01-10 17:42:44,435] [HTTP-63] Ref  Backup: project [git/shared/tools/blog] refname [refs/heads/backup/sm8250_mp_zero_20200110_20200110_174244] oldRev [4fef20ecde1f67b20de9a4434bdbca568ffcb763] newRev [0000000000000000000000000000000000000000]
[2020-01-10 17:42:44,443] [HTTP-63] not a relevant ref: project [git/shared/tools/blog] refname [refs/heads/backup/sm8250_mp_zero_20200110_20200110_174244] oldRev [0000000000000000000000000000000000000000] newRev [4fef20ecde1f67b20de9a4434bdbca568ffcb763]





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章