ProjectRepairer: Add a --copy-loose-objects repair action Add a COPY_LOOSE_OBJECTS action, exposed as '--copy-loose-objects', rsyncing the two hex character fanout directories under objects/. The include patterns keep rsync out of pack/, info/ and their siblings. The action is declared ahead of COPY_PACKS, so when both are selected loose objects are copied first. '--full' now covers both. Change-Id: I9c3d12182bdc5fa9da662269d8681db174057f21
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 317e6b4..887a464 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/ProjectRepairer.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ProjectRepairer.java
@@ -39,6 +39,7 @@ @Singleton public class ProjectRepairer { public enum Action { + COPY_LOOSE_OBJECTS, COPY_PACKS; public static List<Action> all() { @@ -46,7 +47,8 @@ } } - private static final String PACK_DIR = "objects/pack/"; + private static final String OBJECTS_DIR = "objects/"; + private static final String PACK_DIR = OBJECTS_DIR + "pack/"; private final GitRepositoryManager gitManager; private final ReplicationConfig replicationConfig; @@ -81,6 +83,7 @@ throws InterruptedIOException { boolean isRepaired = switch (action) { + case COPY_LOOSE_OBJECTS -> copyLooseObjectsTo(objectsDir, uri, out); case COPY_PACKS -> copyPacksTo(objectsDir.resolve("pack"), uri, out); }; if (!isRepaired) { @@ -112,6 +115,16 @@ } } + private boolean copyLooseObjectsTo(Path objectsDir, URIish uri, OutputStream out) + throws InterruptedIOException { + if (!Files.isDirectory(objectsDir)) { + repLog.atSevere().log("No objects directory %s", objectsDir); + return false; + } + + return copy(objectsDir, uri, out, OBJECTS_DIR, "/??/", "/??/*") == 0; + } + private boolean copyPacksTo(Path packDir, URIish uri, OutputStream out) throws InterruptedIOException { if (!Files.isDirectory(packDir)) {
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 6e04f8a..7aa7e94 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/RepairCommand.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/RepairCommand.java
@@ -52,6 +52,13 @@ private final List<Action> actions = new ArrayList<>(); @Option( + name = "--copy-loose-objects", + usage = "rsync loose object files to SSH destinations before triggering replication") + void setCopyLooseObjects(@SuppressWarnings("unused") boolean arg) { + actions.add(Action.COPY_LOOSE_OBJECTS); + } + + @Option( name = "--copy-packs", usage = "rsync objects/pack files to SSH destinations before triggering replication") void setCopyPacks(@SuppressWarnings("unused") boolean arg) {
diff --git a/src/main/resources/Documentation/cmd-repair.md b/src/main/resources/Documentation/cmd-repair.md index 3f95907..ca20350 100644 --- a/src/main/resources/Documentation/cmd-repair.md +++ b/src/main/resources/Documentation/cmd-repair.md
@@ -11,7 +11,7 @@ ```console ssh -p @SSH_PORT@ @SSH_HOST@ @PLUGIN@ repair [--url <PATTERN>] - [--full | --copy-packs] + [--full | [--copy-loose-objects] [--copy-packs]] <PROJECT> ``` @@ -24,6 +24,13 @@ If no repair action flag is supplied, `--full` is assumed. +For each remote, [remote.NAME.adminUrl](config.md#remote.NAME.adminUrl) is +preferred when set (same as repository creation); otherwise +[remote.NAME.url](config.md#remote.NAME.url) is used. Only plain SSH +destinations are eligible (for example `user@host:/path/to/repo.git`). +Destinations whose URL uses `gerrit+ssh`, HTTP(S), or a local path are +skipped. + REQUIREMENTS ------------ The Gerrit runtime user must have `ssh` on `PATH`, plus `rsync` either on @@ -51,15 +58,13 @@ `--full` : Run every supported repair action. +`--copy-loose-objects` +: rsync the loose objects. Everything else under `objects/`, such as +`pack/` and `info/`, is left untouched. + `--copy-packs` : rsync regular files in `objects/pack/` whose names end with `.pack`, -`.idx`, `.bitmap`, or `.rev` to each matching destination. For each -remote, [remote.NAME.adminUrl](config.md#remote.NAME.adminUrl) is preferred -when set (same as repository creation); otherwise -[remote.NAME.url](config.md#remote.NAME.url) is used. Only plain SSH -destinations are eligible (for example `user@host:/path/to/repo.git`). -Destinations whose URL uses `gerrit+ssh`, HTTP(S), or a local path are -skipped. +`.idx`, `.bitmap`, or `.rev` to each matching destination. `PROJECT` : Exact Gerrit project name. @@ -86,6 +91,12 @@ $ ssh -p @SSH_PORT@ @SSH_HOST@ @PLUGIN@ repair --copy-packs tools/gerrit ``` +Only copy loose objects: + +```console + $ ssh -p @SSH_PORT@ @SSH_HOST@ @PLUGIN@ repair --copy-loose-objects tools/gerrit +``` + Repair only against destinations whose URL mentions `replica1`: ```console
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md index 76a1858..a2f5459 100644 --- a/src/main/resources/Documentation/config.md +++ b/src/main/resources/Documentation/config.md
@@ -276,9 +276,10 @@ replication.rsyncPath : Path to the `rsync` binary on the host running Gerrit, used by the - `@PLUGIN@ repair --copy-packs` command when transferring pack files - to SSH destinations. Set this when the Gerrit runtime user's `PATH` - does not contain `rsync`, or to pin a specific build. + [`@PLUGIN@ repair`](cmd-repair.md) command when transferring loose + objects and pack files to SSH destinations. Set this when the Gerrit + runtime user's `PATH` does not contain `rsync`, or to pin a specific + build. Default: `rsync` (resolved via the Gerrit runtime user's `PATH`)