diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt index 296c42e43c..14470b085f 100644 --- a/Documentation/dev-plugins.txt +++ b/Documentation/dev-plugins.txt @@ -416,6 +416,14 @@ its own custom event class derived from `ChangeEvent`. Certain operations in Gerrit can be validated by plugins by implementing the corresponding link:config-validation.html[listeners]. +[[receive-pack]] +== Receive Pack Initializers + +Plugins may provide ReceivePack initializers which will be invoked +by Gerrit just before a ReceivePack instance will be used. Usually, +plugins will make use of the setXXX methods on the ReceivePack to +set additional properties on it. + [[ssh]] == SSH Commands diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitOverHttpServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitOverHttpServlet.java index 4ecd020a96..b40b1fa39b 100644 --- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitOverHttpServlet.java +++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitOverHttpServlet.java @@ -16,6 +16,7 @@ package com.google.gerrit.httpd; import com.google.common.cache.Cache; import com.google.gerrit.common.data.Capable; +import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.AccessPath; @@ -23,6 +24,7 @@ import com.google.gerrit.server.AnonymousUser; import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.cache.CacheModule; +import com.google.gerrit.server.config.ReceivePackInitializer; import com.google.gerrit.server.git.AsyncReceiveCommits; import com.google.gerrit.server.git.ChangeCache; import com.google.gerrit.server.git.GitRepositoryManager; @@ -244,11 +246,14 @@ public class GitOverHttpServlet extends GitServlet { static class ReceiveFactory implements ReceivePackFactory { private final AsyncReceiveCommits.Factory factory; private final TransferConfig config; + private DynamicSet receivePackInitializers; @Inject - ReceiveFactory(AsyncReceiveCommits.Factory factory, TransferConfig config) { + ReceiveFactory(AsyncReceiveCommits.Factory factory, TransferConfig config, + DynamicSet receivePackInitializers) { this.factory = factory; this.config = config; + this.receivePackInitializers = receivePackInitializers; } @Override @@ -267,9 +272,16 @@ public class GitOverHttpServlet extends GitServlet { rp.setRefLogIdent(user.newRefLogIdent()); rp.setTimeout(config.getTimeout()); rp.setMaxObjectSizeLimit(config.getMaxObjectSizeLimit()); + init(pc.getProject().getNameKey(), rp); req.setAttribute(ATT_RC, rc); return rp; } + + private void init(Project.NameKey project, ReceivePack rp) { + for (ReceivePackInitializer initializer : receivePackInitializers) { + initializer.init(project, rp); + } + } } static class ReceiveFilter implements Filter { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java index aa772f9add..73f6bf76bf 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java @@ -243,6 +243,7 @@ public class GerritGlobalModule extends FactoryModule { DynamicSet.setOf(binder(), CacheRemovalListener.class); DynamicMap.mapOf(binder(), CapabilityDefinition.class); DynamicSet.setOf(binder(), GitReferenceUpdatedListener.class); + DynamicSet.setOf(binder(), ReceivePackInitializer.class); DynamicSet.setOf(binder(), NewProjectCreatedListener.class); DynamicSet.setOf(binder(), ProjectDeletedListener.class); DynamicSet.setOf(binder(), HeadUpdatedListener.class); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/ReceivePackInitializer.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/ReceivePackInitializer.java new file mode 100644 index 0000000000..cfc384d69b --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/ReceivePackInitializer.java @@ -0,0 +1,36 @@ +// Copyright (C) 2014 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. + +package com.google.gerrit.server.config; + +import com.google.gerrit.extensions.annotations.ExtensionPoint; +import com.google.gerrit.reviewdb.client.Project; + +import org.eclipse.jgit.transport.ReceivePack; + +@ExtensionPoint +public interface ReceivePackInitializer { + + /** + * ReceivePack initialization. + * + * Invoked by Gerrit when a new ReceivePack instance is created and just + * before it is used. Implementors will usually call setXXX methods on the + * receivePack parameter in order to set additional properties on it. + * + * @param project project for which the ReceivePack is created + * @param receivePack the ReceivePack instance which is being initialized + */ + public void init(Project.NameKey project, ReceivePack receivePack); +} diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java index 92444f45a8..6c8af21de4 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java @@ -15,8 +15,10 @@ package com.google.gerrit.sshd.commands; import com.google.gerrit.common.data.Capable; +import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.server.IdentifiedUser; +import com.google.gerrit.server.config.ReceivePackInitializer; import com.google.gerrit.server.git.AsyncReceiveCommits; import com.google.gerrit.server.git.ReceiveCommits; import com.google.gerrit.server.git.TransferConfig; @@ -59,6 +61,9 @@ final class Receive extends AbstractGitCommand { @Inject private TransferConfig config; + @Inject + private DynamicSet receivePackInitializers; + private final Set reviewerId = new HashSet(); private final Set ccId = new HashSet(); @@ -97,6 +102,7 @@ final class Receive extends AbstractGitCommand { rp.setTimeout(config.getTimeout()); rp.setMaxObjectSizeLimit(config.getEffectiveMaxObjectSizeLimit( projectControl.getProjectState())); + init(rp); try { rp.receive(in, out, err); } catch (UnpackException badStream) { @@ -163,6 +169,12 @@ final class Receive extends AbstractGitCommand { } } + private void init(ReceivePack rp) { + for (ReceivePackInitializer initializer : receivePackInitializers) { + initializer.init(projectControl.getProject().getNameKey(), rp); + } + } + private void verifyProjectVisible(final String type, final Set who) throws UnloggedFailure { for (final Account.Id id : who) {