summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaša Živkov <sasa.zivkov@sap.com>2018-10-12 17:15:48 +0200
committerSaša Živkov <sasa.zivkov@sap.com>2018-11-22 15:32:58 +0100
commitabafb83c47eb50c0ec5ce9a4b8d04dc355d5a5bf (patch)
treec7a0808a3de69bab6bd3e06f56cff5263b526b66
parentc16fe9c5a6da6c23dbf45a533f788dcc527e209c (diff)
Create missing repository only at the remote we are pushing to
When replication of a ref failed due to missing remote repository at one remote site, we then initiated creation of the missing repository on all remotes where this repository is replicated. The creation of the missing repository is considered to be success if it succeeded for all remotes and only in this case the ref replication was rescheduled. This logic could cause a ref replication to not be rescheduled when creation of a missing repository fails in a remote which is unrelated to the current push operation. For example, if we replicate to two remote sites: [remote "foo"] url = https://foo.org/... adminUrl = ssh://gerrit@foo.org/... [remote "bar"] url = https://bar.org/... adminUrl = ssh://gerrit@bar.org/... and if during a push to "foo" we find that the repository is missing then we will try to create it on both "foo" and "bar". It could happen that the creation of the missing repository succeeds on "foo" and then fails on "bar" because "bar" is unreachable or down at that moment. In this case the replication to "foo" will not be rescheduled but it should be as we successfully created the missing repository in "foo". Create missing repository only under the (admin) URL in the same remote. Note that there will be one ref replication task for each remote which ensures that the missing repository will be created in all remotes. Change-Id: Idbc3f614df53bb3aabcc4cf6cb0d6540e7000e29
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java3
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java16
2 files changed, 13 insertions, 6 deletions
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
index 241ca49..c4fcaf3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
@@ -397,7 +397,8 @@ class PushOne implements ProjectRunnable, CanceledWhileRunning {
if (pool.isCreateMissingRepos()) {
try {
Ref head = git.exactRef(Constants.HEAD);
- if (replicationQueue.createProject(projectName, head != null ? getName(head) : null)) {
+ if (replicationQueue.createProject(
+ config.getName(), projectName, head != null ? getName(head) : null)) {
repLog.warn("Missing repository created; retry replication to {}", uri);
pool.reschedule(this, Destination.RetryReason.REPOSITORY_MISSING);
} else {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
index d818742..f73530d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
@@ -18,6 +18,7 @@ import static com.googlesource.gerrit.plugins.replication.AdminApiFactory.isGerr
import static com.googlesource.gerrit.plugins.replication.AdminApiFactory.isSSH;
import com.google.common.base.Strings;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.events.HeadUpdatedListener;
import com.google.gerrit.extensions.events.LifecycleListener;
@@ -159,7 +160,7 @@ public class ReplicationQueue
@Override
public void onProjectDeleted(ProjectDeletedListener.Event event) {
Project.NameKey projectName = new Project.NameKey(event.getProjectName());
- for (URIish uri : getURIs(projectName, FilterType.PROJECT_DELETION)) {
+ for (URIish uri : getURIs(null, projectName, FilterType.PROJECT_DELETION)) {
deleteProject(uri, projectName);
}
}
@@ -167,12 +168,13 @@ public class ReplicationQueue
@Override
public void onHeadUpdated(HeadUpdatedListener.Event event) {
Project.NameKey project = new Project.NameKey(event.getProjectName());
- for (URIish uri : getURIs(project, FilterType.ALL)) {
+ for (URIish uri : getURIs(null, project, FilterType.ALL)) {
updateHead(uri, project, event.getNewHeadName());
}
}
- private Set<URIish> getURIs(Project.NameKey projectName, FilterType filterType) {
+ private Set<URIish> getURIs(
+ @Nullable String remoteName, Project.NameKey projectName, FilterType filterType) {
if (config.getDestinations(filterType).isEmpty()) {
return Collections.emptySet();
}
@@ -187,6 +189,10 @@ public class ReplicationQueue
continue;
}
+ if (remoteName != null && !config.getRemoteConfigName().equals(remoteName)) {
+ continue;
+ }
+
boolean adminURLUsed = false;
for (String url : config.getAdminUrls()) {
@@ -229,9 +235,9 @@ public class ReplicationQueue
return uris;
}
- public boolean createProject(Project.NameKey project, String head) {
+ public boolean createProject(String remoteName, Project.NameKey project, String head) {
boolean success = true;
- for (URIish uri : getURIs(project, FilterType.PROJECT_CREATION)) {
+ for (URIish uri : getURIs(remoteName, project, FilterType.PROJECT_CREATION)) {
success &= createProject(uri, project, head);
}
return success;