Add Gerrit multi-primary utilities Change-Id: I99d58dd6a1bf14edb8456b8454f287b71287e0a4
diff --git a/README.md b/README.md index ec4eb15..f52eb95 100644 --- a/README.md +++ b/README.md
@@ -20,3 +20,6 @@ [Administration Scripts](/admin/) ------------------------ + +[Gerrit multi-primary Scripts](/multi-primary/) +------------------------
diff --git a/multi-primary/README.md b/multi-primary/README.md new file mode 100644 index 0000000..cb7d092 --- /dev/null +++ b/multi-primary/README.md
@@ -0,0 +1,11 @@ +Gerrit multi-primary utilities +============================== + +Overview +-------- +Set of utilities to manage the setup and administration of Gerrit multi-primary +installation and BAU operations. + +Index +----- +* [globalrefdb](globalrefdb.md) - Checks the repository local-refdb vs. global-refdb
diff --git a/multi-primary/globalrefdb.groovy b/multi-primary/globalrefdb.groovy new file mode 100644 index 0000000..b47cdb8 --- /dev/null +++ b/multi-primary/globalrefdb.groovy
@@ -0,0 +1,108 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import com.google.gerrit.common.data.* +import com.google.gerrit.sshd.* +import com.google.gerrit.extensions.annotations.* +import com.google.gerrit.server.project.* +import com.google.gerrit.server.account.* +import com.google.gerrit.server.IdentifiedUser +import com.google.inject.* +import org.kohsuke.args4j.* +import com.google.gerrit.server.git.* +import com.google.gerrit.entities.* +import org.eclipse.jgit.errors.* +import com.gerritforge.gerrit.globalrefdb.* +import com.google.gerrit.extensions.registration.* +import org.eclipse.jgit.lib.* + +abstract class BaseSshCommand extends SshCommand { + void println(String msg) { + stdout.println msg + stdout.flush() + } + + void error(String msg) { + stderr.println msg + stderr.flush() + } +} + +@Export("check") +@CommandMetaData(description = "Check local refs alignment against the global-refdb for a project") +@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER) +class ProjectRefsCheck extends BaseSshCommand { + + @Argument(index = 0, usage = "Project name", metaVar = "PROJECT", required = true) + String project + + @Option(name = "--verbose", usage = "Display verbose check results for all refs") + boolean verbose = false + + @Option(name = "--ref", usage = "Check only one ref") + String singleRef + + @Inject + GitRepositoryManager repoMgr + + @Inject + DynamicItem<GlobalRefDatabase> globalRefDb + + public void run() { + try { + def projectName = Project.nameKey(project) + + repoMgr.openRepository(projectName).with { repo -> + def upToDate = true + + if (singleRef) { + println "Checking project $project:$singleRef ..." + def ref = repo.refDatabase.exactRef(singleRef) + if (!ref) { + error "Project $project does not have $singleRef" + return + } + + upToDate = checkRef(projectName, repo, ref) + } else { + println "Checking project $project ..." + repo.refDatabase.refs.each { ref -> + checkRef(projectName, repo, ref) + } + } + + println "Result: ${upToDate ? 'UP-TO-DATE':'OUTDATED'}" + } + } catch (RepositoryNotFoundException e) { + error "Project $project not found" + } + } + + boolean checkRef(Project.NameKey projectName, Repository repo, Ref ref) + { + def isUpToDate = globalRefDb.get().isUpToDate(projectName, ref) + + if (verbose && isUpToDate) { + println "[UP-TO-DATE] ${ref.name}" + } + + if (!isUpToDate) { + def globalRef = globalRefDb.get().get(projectName, ref.name, String.class) + println "[OUTDATED] ${ref.name}:${ref.objectId.name} <> ${globalRef.orElse('MISSING')}" + } + } +} + +commands = [ ProjectRefsCheck ] +
diff --git a/multi-primary/globalrefdb.md b/multi-primary/globalrefdb.md new file mode 100644 index 0000000..17f74f6 --- /dev/null +++ b/multi-primary/globalrefdb.md
@@ -0,0 +1,30 @@ +Global-refdb Check utility +============================== + +NAME +---- +`globalrefdb check` utility compare the repository refs status against the global-refdb. + +SYNOPSIS +-------- +> ssh -p <port> <host> globalrefdb check PROJECT [--ref <ref name>] [--verbose] + +DESCRIPTION +----------- +Verify if the local with the global refs for a project, reporting all differences +between the two SHA1s. The operation can operate on the individual ref passed as +a parameter. + +ACCESS +------ +Any user who has been granted the 'Administrate Server' capability. + +SCRIPTING +--------- +This command is intended to be used in scripts. + +EXAMPLES +-------- +Check if all refs of the All-Users project are up-to-date with the global-refdb: + +> $ ssh -p 29418 review.example.com globalrefdb check All-Users