Allow replication to match only some hosts
By supporting substring matches on URLs during "gerrit replicate" an
administrator can reforce replication to a single remote system after
network connectivity with that system is known to be working.
Bug: GERRIT-110
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java b/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java
index e13df07..0df522c 100644
--- a/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java
+++ b/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java
@@ -29,13 +29,23 @@
private static final Logger log =
LoggerFactory.getLogger(PushAllProjectsOp.class);
+ private final String urlMatch;
+
+ public PushAllProjectsOp() {
+ this(null);
+ }
+
+ public PushAllProjectsOp(final String urlMatch) {
+ this.urlMatch = urlMatch;
+ }
+
public void run() {
final HashSet<Branch.NameKey> pending = new HashSet<Branch.NameKey>();
try {
final ReviewDb db = Common.getSchemaFactory().open();
try {
for (final Project project : db.projects().all()) {
- PushQueue.scheduleFullSync(project.getNameKey());
+ PushQueue.scheduleFullSync(project.getNameKey(), urlMatch);
}
} finally {
db.close();
@@ -47,6 +57,10 @@
@Override
public String toString() {
- return "Replicate All Projects";
+ String s = "Replicate All Projects";
+ if (urlMatch != null) {
+ s = s + " to " + urlMatch;
+ }
+ return s;
}
}
diff --git a/src/main/java/com/google/gerrit/git/PushQueue.java b/src/main/java/com/google/gerrit/git/PushQueue.java
index 6426da2..f52f91e 100644
--- a/src/main/java/com/google/gerrit/git/PushQueue.java
+++ b/src/main/java/com/google/gerrit/git/PushQueue.java
@@ -75,10 +75,12 @@
* removed from the local repository.
*
* @param project identity of the project to replicate.
+ * @param urlMatch substring that must appear in a URI to support replication.
*/
- public static void scheduleFullSync(final Project.NameKey project) {
+ public static void scheduleFullSync(final Project.NameKey project,
+ final String urlMatch) {
for (final ReplicationConfig cfg : allConfigs()) {
- for (final URIish uri : cfg.getURIs(project)) {
+ for (final URIish uri : cfg.getURIs(project, urlMatch)) {
scheduleImp(project, PushOp.MIRROR_ALL, cfg, uri);
}
}
@@ -98,7 +100,7 @@
final String ref) {
for (final ReplicationConfig cfg : allConfigs()) {
if (cfg.wouldPushRef(ref)) {
- for (final URIish uri : cfg.getURIs(project)) {
+ for (final URIish uri : cfg.getURIs(project, null)) {
scheduleImp(project, ref, cfg, uri);
}
}
@@ -192,8 +194,8 @@
delay = posInt(rc, cfg, "replicationdelay", 15);
}
- private static int posInt(final RemoteConfig rc, final RepositoryConfig cfg,
- final String name, final int defValue) {
+ private static int posInt(final RemoteConfig rc,
+ final RepositoryConfig cfg, final String name, final int defValue) {
return Math.max(0, cfg.getInt("remote", rc.getName(), name, defValue));
}
@@ -206,13 +208,22 @@
return false;
}
- List<URIish> getURIs(final Project.NameKey project) {
+ List<URIish> getURIs(final Project.NameKey project, final String urlMatch) {
final List<URIish> r = new ArrayList<URIish>(remote.getURIs().size());
for (URIish uri : remote.getURIs()) {
- uri = uri.setPath(replace(uri.getPath(), "name", project.get()));
- r.add(uri);
+ if (matches(uri, urlMatch)) {
+ uri = uri.setPath(replace(uri.getPath(), "name", project.get()));
+ r.add(uri);
+ }
}
return r;
}
+
+ private static boolean matches(URIish uri, final String urlMatch) {
+ if (urlMatch == null || urlMatch.equals("") || urlMatch.equals("*")) {
+ return true;
+ }
+ return uri.toString().contains(urlMatch);
+ }
}
}
diff --git a/src/main/java/com/google/gerrit/server/ssh/AdminReplicate.java b/src/main/java/com/google/gerrit/server/ssh/AdminReplicate.java
index 8df7a17..31998f7 100644
--- a/src/main/java/com/google/gerrit/server/ssh/AdminReplicate.java
+++ b/src/main/java/com/google/gerrit/server/ssh/AdminReplicate.java
@@ -31,6 +31,9 @@
@Option(name = "--all", usage = "push all known projects")
private boolean all;
+ @Option(name = "--url", metaVar = "PATTERN", usage = "pattern to match URL on")
+ private String urlMatch;
+
@Argument(index = 0, multiValued = true, metaVar = "PROJECT", usage = "project name")
private List<String> projectNames;
@@ -47,13 +50,13 @@
}
if (all) {
- WorkQueue.schedule(new PushAllProjectsOp(), 0, TimeUnit.SECONDS);
+ WorkQueue.schedule(new PushAllProjectsOp(urlMatch), 0, TimeUnit.SECONDS);
} else {
for (final String name : projectNames) {
final Project.NameKey key = new Project.NameKey(name);
if (Common.getProjectCache().get(key) != null) {
- PushQueue.scheduleFullSync(key);
+ PushQueue.scheduleFullSync(key, urlMatch);
} else {
throw new Failure(1, "error: '" + name + "': not a Gerrit project");
}