ProjectRepairer: Refactor to select actions through an enum repair() takes a 'copyPacks' boolean, which can only describe the one thing it knows how to do. A second kind of repair would mean a second boolean at every call site, with the order the two run in implicit in how repair() tests them. Take a collection of Action values instead. Individual flags are kept in flag order. '--full' and the no-flag default use Action.all() so actions run in enum declaration order. Action has only COPY_PACKS, so behaviour is unchanged. Change-Id: Ie7c0d9af40cab893a01a754bc984b8593ff6a5bc
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoRepairHandler.java b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoRepairHandler.java index b1462c4..fa97cf2 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoRepairHandler.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoRepairHandler.java
@@ -21,6 +21,7 @@ import com.google.gerrit.server.git.WorkQueue; import com.google.inject.Inject; import com.google.inject.Singleton; +import com.googlesource.gerrit.plugins.replication.ProjectRepairer.Action; import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig; import com.googlesource.gerrit.plugins.replication.events.dispatcher.EventDispatcher; import java.io.ByteArrayOutputStream; @@ -92,7 +93,7 @@ ByteArrayOutputStream buf = new ByteArrayOutputStream(); boolean isRepaired; try { - isRepaired = projectRepairer.repair(project, uri, buf, true); + isRepaired = projectRepairer.repair(project, uri, buf, Action.all()); } catch (InterruptedIOException e) { repLog.atWarning().withCause(e).log( "Auto-repair interrupted for project %s to %s", project.get(), uri);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ProjectRepairer.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ProjectRepairer.java index 68a2c9d..317e6b4 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/ProjectRepairer.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ProjectRepairer.java
@@ -29,6 +29,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.URIish; @@ -37,6 +38,14 @@ @Singleton public class ProjectRepairer { + public enum Action { + COPY_PACKS; + + public static List<Action> all() { + return List.of(values()); + } + } + private static final String PACK_DIR = "objects/pack/"; private final GitRepositoryManager gitManager; @@ -48,9 +57,10 @@ this.replicationConfig = replicationConfig; } - public boolean repair(Project.NameKey project, URIish uri, OutputStream out, boolean copyPacks) + public boolean repair( + Project.NameKey project, URIish uri, OutputStream out, Collection<Action> actions) throws InterruptedIOException { - if (!copyPacks) { + if (actions.isEmpty()) { return true; } @@ -59,11 +69,24 @@ return false; } - if (!copyPacksTo(objectsDir.resolve("pack"), uri, out)) { - repLog.atSevere().log("Repair failed for %s on %s", project.get(), uri); - return false; + boolean isRepaired = true; + for (Action action : actions) { + isRepaired &= repair(project, uri, out, objectsDir, action); } - return true; + return isRepaired; + } + + private boolean repair( + Project.NameKey project, URIish uri, OutputStream out, Path objectsDir, Action action) + throws InterruptedIOException { + boolean isRepaired = + switch (action) { + case COPY_PACKS -> copyPacksTo(objectsDir.resolve("pack"), uri, out); + }; + if (!isRepaired) { + repLog.atSevere().log("Repair (%s) failed for %s on %s", action, project.get(), uri); + } + return isRepaired; } public static boolean canCopy(URIish uri) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/RepairCommand.java b/src/main/java/com/googlesource/gerrit/plugins/replication/RepairCommand.java index ad6648a..6e04f8a 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/RepairCommand.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/RepairCommand.java
@@ -21,10 +21,12 @@ import com.google.gerrit.sshd.CommandMetaData; import com.google.gerrit.sshd.SshCommand; import com.google.inject.Inject; +import com.googlesource.gerrit.plugins.replication.ProjectRepairer.Action; import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig; import java.io.IOException; import java.io.InterruptedIOException; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -47,13 +49,19 @@ usage = "substring URL must match (or * to match everything)") private String urlMatch; + private final List<Action> actions = new ArrayList<>(); + @Option( name = "--copy-packs", usage = "rsync objects/pack files to SSH destinations before triggering replication") - private boolean copyPacks; + void setCopyPacks(@SuppressWarnings("unused") boolean arg) { + actions.add(Action.COPY_PACKS); + } @Option(name = "--full", usage = "run all supported repair actions (default)") - private boolean full; + void setFull(@SuppressWarnings("unused") boolean arg) { + actions.addAll(Action.all()); + } @Inject private ProjectCache projectCache; @Inject private ReplicationDestinations destinations; @@ -73,17 +81,18 @@ throw die(e); } - if (!copyPacks) { - full = true; - } - - Set<URIish> failedUris = repair(project); + Set<URIish> failedUris = repair(project, repairActions()); if (!failedUris.isEmpty()) { throw new UnloggedFailure(1, "Repair failed for " + failedUris.size() + " destination(s)"); } } - private Set<URIish> repair(Project.NameKey project) throws Failure, InterruptedIOException { + private Collection<Action> repairActions() { + return actions.isEmpty() ? Action.all() : actions; + } + + private Set<URIish> repair(Project.NameKey project, Collection<Action> actions) + throws Failure, InterruptedIOException { Set<URIish> copyTargets = new HashSet<>(); Collection<URIish> destUris = destinations @@ -92,7 +101,7 @@ for (URIish uri : destUris) { if (!ProjectRepairer.canCopy(uri)) { writeStdErrSync( - "Warning: skipping " + uri + " as copy-packs only supports plain SSH destinations"); + "Warning: skipping " + uri + " as repair only supports plain SSH destinations"); continue; } copyTargets.add(uri); @@ -106,7 +115,7 @@ OutputStream out = getFlushingOutputStream(); for (URIish uri : copyTargets) { writeStdOutSync("\nRepairing " + uri + " ..."); - if (projectRepairer.repair(project, uri, out, full || copyPacks)) { + if (projectRepairer.repair(project, uri, out, actions)) { writeStdOutSync( "\nRunning replication start for " + project.get() + " to " + uri.toString() + " ..."); replicationStarter.start(