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]





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