Merge branch 'stable-2.9' into stable-2.10 * stable-2.9: Prevent creating repos on extra servers Conflicts: src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java Change-Id: I5934d118a72dd249b17b7f381aa3081ef58aa09d
diff --git a/.gitignore b/.gitignore index fc3c0ff..9c143f3 100644 --- a/.gitignore +++ b/.gitignore
@@ -5,3 +5,6 @@ /.settings/org.eclipse.m2e.core.prefs /.idea replication.iml +/.buckd +/buck-cache +/buck-out
diff --git a/BUCK b/BUCK index 6048a93..2e8a623 100644 --- a/BUCK +++ b/BUCK
@@ -9,8 +9,9 @@ 'Gerrit-Module: com.googlesource.gerrit.plugins.replication.ReplicationModule', 'Gerrit-SshModule: com.googlesource.gerrit.plugins.replication.SshModule' ], - compile_deps = [ + provided_deps = [ '//lib/commons:io', + '//lib/log:log4j' ], ) @@ -18,13 +19,13 @@ name = 'replication_tests', srcs = glob(['src/test/java/**/*.java']), deps = [ - ':replication__plugin__compile', + ':replication__plugin', '//gerrit-common:server', '//gerrit-reviewdb:server', '//gerrit-server:server', - '//lib:easymock', '//lib:gwtorm', '//lib:junit', + '//lib/easymock:easymock', '//lib/jgit:jgit', ], )
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java index a2b66d1..83b97c6 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
@@ -13,13 +13,11 @@ // limitations under the License. package com.googlesource.gerrit.plugins.replication; -import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.PluginUser; import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.WorkQueue; -import com.google.gwtorm.server.SchemaFactory; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Singleton; @@ -44,14 +42,13 @@ private final SitePaths site; private final RemoteSiteUser.Factory remoteSiteUserFactory; private final PluginUser pluginUser; - private final SchemaFactory<ReviewDb> db; private final GitRepositoryManager gitRepositoryManager; private final GroupBackend groupBackend; private final WorkQueue workQueue; @Inject public AutoReloadConfigDecorator(Injector injector, SitePaths site, - RemoteSiteUser.Factory ruf, PluginUser pu, SchemaFactory<ReviewDb> db, + RemoteSiteUser.Factory ruf, PluginUser pu, GitRepositoryManager grm, GroupBackend gb, WorkQueue workQueue) throws ConfigInvalidException, IOException { @@ -59,7 +56,6 @@ this.site = site; this.remoteSiteUserFactory = ruf; this.pluginUser = pu; - this.db = db; this.gitRepositoryManager = grm; this.groupBackend = gb; this.currentConfig = loadConfig(); @@ -70,7 +66,7 @@ private ReplicationFileBasedConfig loadConfig() throws ConfigInvalidException, IOException { return new ReplicationFileBasedConfig(injector, site, - remoteSiteUserFactory, pluginUser, db, gitRepositoryManager, + remoteSiteUserFactory, pluginUser, gitRepositoryManager, groupBackend); }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java index feff6c0..ef659f2 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -38,7 +38,6 @@ import com.google.gerrit.server.project.PerRequestProjectControlCache; import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.util.RequestContext; -import com.google.gwtorm.server.SchemaFactory; import com.google.inject.Injector; import com.google.inject.Provider; import com.google.inject.Provides; @@ -65,8 +64,9 @@ import java.util.concurrent.TimeUnit; class Destination { - private static final Logger log = ReplicationQueue.log; - private static final ReplicationStateLogger stateLog = new ReplicationStateLogger(log); + private static final Logger repLog = ReplicationQueue.repLog; + private static final ReplicationStateLogger stateLog = + new ReplicationStateLogger(repLog); private final int poolThreads; private final String poolName; @@ -97,7 +97,6 @@ Destination(final Injector injector, final RemoteConfig rc, final Config cfg, - final SchemaFactory<ReviewDb> db, final RemoteSiteUser.Factory replicationUserFactory, final PluginUser pluginUser, final GitRepositoryManager gitRepositoryManager, @@ -130,7 +129,7 @@ if (g != null) { builder.add(g.getUUID()); } else { - log.warn(String.format( + repLog.warn(String.format( "Group \"%s\" not recognized, removing from authGroup", name)); } } @@ -220,6 +219,7 @@ void schedule(final Project.NameKey project, final String ref, final URIish uri, ReplicationState state) { + repLog.info("scheduling replication {}:{} => {}", project, ref, uri); if (!isVisible(project, state)) { return; } @@ -265,13 +265,15 @@ e.addRef(ref); state.increasePushTaskCount(project.get(), ref); e.addState(ref, state); + repLog.info("scheduled {}:{} => {} to run after {}s", project, ref, + e, delay); } } /** * It schedules again a PushOp instance. * <p> - * If the reason for rescheduling is to avoid a collison + * If the reason for rescheduling is to avoid a collision * with an in-flight push to the same URI, we don't * mark the operation as "retrying," and we schedule * using the replication delay, rather than the retry @@ -482,8 +484,9 @@ } else if (remoteNameStyle.equals("basenameOnly")) { name = FilenameUtils.getBaseName(name); } else if (!remoteNameStyle.equals("slash")) { - ReplicationQueue.log.debug(String.format( - "Unknown remoteNameStyle: %s, falling back to slash", remoteNameStyle)); + repLog.debug(String.format( + "Unknown remoteNameStyle: %s, falling back to slash", + remoteNameStyle)); } String replacedPath = ReplicationQueue.replaceName(uri.getPath(), name, isSingleProjectMatch());
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java b/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java index 165ef03..720da54 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java
@@ -21,15 +21,12 @@ import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; class PushAll implements Runnable { - private static final Logger log = LoggerFactory.getLogger(PushAll.class); - private static final ReplicationStateLogger stateLog = new ReplicationStateLogger(log); + private static final ReplicationStateLogger stateLog = + new ReplicationStateLogger(ReplicationQueue.repLog); interface Factory { PushAll create(String urlMatch, ReplicationState state);
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 876a4d5..b699e0d 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
@@ -14,6 +14,7 @@ package com.googlesource.gerrit.plugins.replication; +import com.google.common.base.Stopwatch; import com.google.common.base.Throwables; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Lists; @@ -33,6 +34,7 @@ import com.google.gerrit.server.git.VisibleRefFilter; import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.ProjectControl; +import com.google.gerrit.server.util.IdGenerator; import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.SchemaFactory; import com.google.inject.Inject; @@ -59,6 +61,7 @@ import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; import org.slf4j.Logger; +import org.slf4j.MDC; import java.io.IOException; import java.util.Collection; @@ -68,6 +71,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; /** * A push to remote operation started by {@link GitReferenceUpdatedListener}. @@ -76,9 +80,11 @@ * take that lock to ensure they are working with a current view of the object. */ class PushOne implements ProjectRunnable { - private static final Logger log = ReplicationQueue.log; - private static final ReplicationStateLogger stateLog = new ReplicationStateLogger(log); + private static final Logger repLog = ReplicationQueue.repLog; + private static final ReplicationStateLogger stateLog = + new ReplicationStateLogger(repLog); static final String ALL_REFS = "..all.."; + static final String ID_MDC_KEY = "pushOneId"; interface Factory { PushOne create(Project.NameKey d, URIish u); @@ -106,6 +112,7 @@ LinkedListMultimap.create(); private final int maxLockRetries; private int lockRetryCount; + private final int id; @Inject PushOne(final GitRepositoryManager grm, @@ -117,6 +124,7 @@ final PerThreadRequestScope.Scoper ts, final ChangeCache cc, final ReplicationQueue rq, + final IdGenerator ig, @Assisted final Project.NameKey d, @Assisted final URIish u) { gitManager = grm; @@ -132,6 +140,7 @@ uri = u; lockRetryCount = 0; maxLockRetries = pool.getLockErrorMaxRetries(); + id = ig.next(); } @Override @@ -151,10 +160,12 @@ @Override public String toString() { - if (retryCount == 0) { - return "push " + uri; + String print = "[" + IdGenerator.format(id) + "] push " + uri; + + if (retryCount > 0) { + print = "(retry " + retryCount + ") " + print; } - return "(retry " + retryCount + ") " + "push " + uri; + return print; } boolean isRetrying() { @@ -182,8 +193,10 @@ if (ALL_REFS.equals(ref)) { delta.clear(); pushAllRefs = true; + repLog.trace("Added all refs for replication to " + uri); } else if (!pushAllRefs) { delta.add(ref); + repLog.trace("Added ref " + ref + " for replication to " + uri); } } @@ -257,18 +270,23 @@ // we start replication (instead a new instance, with the same URI, is // created and scheduled for a future point in time.) // + MDC.put(ID_MDC_KEY, IdGenerator.format(id)); if (!pool.requestRunway(this)) { if (!canceled) { - log.info("Rescheduling replication to " + uri + - " to avoid collision with an in-flight push."); + repLog.info("Rescheduling replication to " + uri + + " to avoid collision with an in-flight push."); pool.reschedule(this, Destination.RetryReason.COLLISION); } return; } + Stopwatch stopwatch = Stopwatch.createStarted(); + repLog.info("Replication to " + uri + " started..."); try { git = gitManager.openRepository(projectName); runImpl(); + repLog.info("Replication to " + uri + " completed in " + + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms"); } catch (RepositoryNotFoundException e) { stateLog.error("Cannot replicate " + projectName + "; Local repository error: " @@ -282,9 +300,8 @@ if (msg.contains("access denied")) { createRepository(); } else { - log.error("Cannot replicate " + projectName - + "; Remote repository error: " - + msg); + repLog.error("Cannot replicate " + projectName + + "; Remote repository error: " + msg); } } catch (NoRemoteRepositoryException e) { @@ -296,33 +313,29 @@ Throwable cause = e.getCause(); if (cause instanceof JSchException && cause.getMessage().startsWith("UnknownHostKey:")) { - log.error("Cannot replicate to " + uri + ": " + cause.getMessage()); + repLog.error("Cannot replicate to " + uri + ": " + cause.getMessage()); } else if (e instanceof LockFailureException) { lockRetryCount++; // The LockFailureException message contains both URI and reason // for this failure. - log.error("Cannot replicate to " + e.getMessage()); + repLog.error("Cannot replicate to " + e.getMessage()); // The remote push operation should be retried. if (lockRetryCount <= maxLockRetries) { pool.reschedule(this, Destination.RetryReason.TRANSPORT_ERROR); } else { - log.error("Giving up after " + lockRetryCount + repLog.error("Giving up after " + lockRetryCount + " of this error during replication to " + e.getMessage()); } } else { - log.error("Cannot replicate to " + uri, e); + repLog.error("Cannot replicate to " + uri, e); // The remote push operation should be retried. pool.reschedule(this, Destination.RetryReason.TRANSPORT_ERROR); } } catch (IOException e) { stateLog.error("Cannot replicate to " + uri, e, getStatesAsArray()); - } catch (RuntimeException e) { + } catch (RuntimeException | Error e) { stateLog.error("Unexpected error during replication to " + uri, e, getStatesAsArray()); - - } catch (Error e) { - stateLog.error("Unexpected error during replication to " + uri, e, getStatesAsArray()); - } finally { if (git != null) { git.close(); @@ -348,7 +361,7 @@ } }; replicationQueue.onNewProjectCreated(event); - log.warn("Missing repository created; retry replication to " + uri); + repLog.warn("Missing repository created; retry replication to " + uri); pool.reschedule(this, Destination.RetryReason.REPOSITORY_MISSING); } catch (IOException ioe) { stateLog.error("Cannot replicate to " + uri + "; failed to create missing repository", @@ -368,7 +381,7 @@ try { tn.close(); } catch (Throwable e2) { - log.warn("Unexpected error while closing " + uri, e2); + repLog.warn("Unexpected error while closing " + uri, e2); } } @@ -389,7 +402,7 @@ return new PushResult(); } - log.info("Push to " + uri + " references: " + todo); + repLog.info("Push to " + uri + " references: " + todo); return tn.push(NullProgressMonitor.INSTANCE, todo); }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java index dd8f4f5..57d07b8 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
@@ -15,13 +15,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.PluginUser; import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.WorkQueue; -import com.google.gwtorm.server.SchemaFactory; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Singleton; @@ -50,7 +48,6 @@ private boolean replicateAllOnPluginStart; private boolean defaultForceUpdate; private Injector injector; - private final SchemaFactory<ReviewDb> database; private final RemoteSiteUser.Factory replicationUserFactory; private final PluginUser pluginUser; private final GitRepositoryManager gitRepositoryManager; @@ -60,13 +57,12 @@ @Inject public ReplicationFileBasedConfig(final Injector injector, final SitePaths site, final RemoteSiteUser.Factory ruf, final PluginUser pu, - final SchemaFactory<ReviewDb> db, final GitRepositoryManager grm, + final GitRepositoryManager grm, final GroupBackend gb) throws ConfigInvalidException, IOException { this.cfgPath = new File(site.etc_dir, "replication.config"); this.injector = injector; this.replicationUserFactory = ruf; this.pluginUser = pu; - this.database = db; this.gitRepositoryManager = grm; this.groupBackend = gb; this.config = new FileBasedConfig(cfgPath, FS.DETECTED); @@ -127,7 +123,7 @@ } Destination destination = - new Destination(injector, c, config, database, replicationUserFactory, + new Destination(injector, c, config, replicationUserFactory, pluginUser, gitRepositoryManager, groupBackend); if (!destination.isSingleProjectMatch()) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationLogFile.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationLogFile.java new file mode 100644 index 0000000..aeb0519 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationLogFile.java
@@ -0,0 +1,49 @@ +// 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.googlesource.gerrit.plugins.replication; + +import com.google.gerrit.extensions.events.LifecycleListener; +import com.google.gerrit.server.util.SystemLog; +import com.google.inject.Inject; + +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.apache.log4j.PatternLayout; + +public class ReplicationLogFile implements LifecycleListener { + + private final SystemLog systemLog; + + @Inject + public ReplicationLogFile(final SystemLog systemLog) { + this.systemLog = systemLog; + } + + @Override + public void start() { + Logger replicationLogger = + LogManager.getLogger(ReplicationQueue.REPLICATION_LOG_NAME); + replicationLogger.removeAllAppenders(); + replicationLogger.addAppender(systemLog.createAsyncAppender( + replicationLogger.getName(), new PatternLayout("[%d] [%X{" + + PushOne.ID_MDC_KEY + "}] %m%n"))); + replicationLogger.setAdditivity(false); + } + + @Override + public void stop() { + LogManager.getLogger(ReplicationQueue.repLog.getName()).removeAllAppenders(); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java index 8aa3248..6e2ffdc 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
@@ -47,6 +47,8 @@ bind(LifecycleListener.class) .annotatedWith(UniqueAnnotations.create()) .to(OnStartStop.class); + bind(LifecycleListener.class).annotatedWith(UniqueAnnotations.create()).to( + ReplicationLogFile.class); bind(CredentialsFactory.class).to( AutoReloadSecureCredentialsFactoryDecorator.class).in(Scopes.SINGLETON); bind(CapabilityDefinition.class)
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 223e597..8be6b21 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
@@ -60,8 +60,10 @@ NewProjectCreatedListener, ProjectDeletedListener, HeadUpdatedListener { - static final Logger log = LoggerFactory.getLogger(ReplicationQueue.class); - private static final ReplicationStateLogger stateLog = new ReplicationStateLogger(log); + static final String REPLICATION_LOG_NAME = "replication_log"; + static final Logger repLog = LoggerFactory.getLogger(REPLICATION_LOG_NAME); + private static final ReplicationStateLogger stateLog = + new ReplicationStateLogger(repLog); static String replaceName(String in, String name, boolean keyIsOptional) { String key = "${name}"; @@ -102,16 +104,16 @@ running = false; int discarded = config.shutdown(); if (discarded > 0) { - log.warn(String.format( - "Cancelled %d replication events during shutdown", - discarded)); + repLog.warn(String.format( + "Cancelled %d replication events during shutdown", discarded)); } } void scheduleFullSync(final Project.NameKey project, final String urlMatch, ReplicationState state) { if (!running) { - stateLog.warn("Replication plugin did not finish startup before event", state); + stateLog.warn("Replication plugin did not finish startup before event", + state); return; } @@ -170,7 +172,7 @@ return Collections.emptySet(); } if (!running) { - log.error("Replication plugin did not finish startup before event"); + repLog.error("Replication plugin did not finish startup before event"); return Collections.emptySet(); } @@ -195,20 +197,23 @@ try { uri = new URIish(url); } catch (URISyntaxException e) { - log.warn(String.format("adminURL '%s' is invalid: %s", url, e.getMessage())); + repLog.warn(String.format("adminURL '%s' is invalid: %s", url, + e.getMessage())); continue; } String path = replaceName(uri.getPath(), projectName.get(), config.isSingleProjectMatch()); if (path == null) { - log.warn(String.format("adminURL %s does not contain ${name}", uri)); + repLog.warn(String + .format("adminURL %s does not contain ${name}", uri)); continue; } uri = uri.setPath(path); if (!isSSH(uri)) { - log.warn(String.format("adminURL '%s' is invalid: only SSH is supported", uri)); + repLog.warn(String.format( + "adminURL '%s' is invalid: only SSH is supported", uri)); continue; } @@ -228,12 +233,12 @@ private void createProject(URIish replicateURI, String head) { if (!replicateURI.isRemote()) { createLocally(replicateURI, head); - log.info("Created local repository: " + replicateURI); + repLog.info("Created local repository: " + replicateURI); } else if (isSSH(replicateURI)) { createRemoteSsh(replicateURI, head); - log.info("Created remote repository: " + replicateURI); + repLog.info("Created remote repository: " + replicateURI); } else { - log.warn(String.format("Cannot create new project on remote site %s." + repLog.warn(String.format("Cannot create new project on remote site %s." + " Only local paths and SSH URLs are supported" + " for remote repository creation", replicateURI)); } @@ -254,9 +259,8 @@ repo.close(); } } catch (IOException e) { - log.error(String.format( - "Error creating local repository %s:\n", - uri.getPath()), e); + repLog.error(String.format( + "Error creating local repository %s:\n", uri.getPath()), e); } } @@ -272,7 +276,7 @@ try { executeRemoteSsh(uri, cmd, errStream); } catch (IOException e) { - log.error(String.format( + repLog.error(String.format( "Error creating remote repository at %s:\n" + " Exception: %s\n" + " Command: %s\n" @@ -284,12 +288,12 @@ private void deleteProject(URIish replicateURI) { if (!replicateURI.isRemote()) { deleteLocally(replicateURI); - log.info("Deleted local repository: " + replicateURI); + repLog.info("Deleted local repository: " + replicateURI); } else if (isSSH(replicateURI)) { deleteRemoteSsh(replicateURI); - log.info("Deleted remote repository: " + replicateURI); + repLog.info("Deleted remote repository: " + replicateURI); } else { - log.warn(String.format("Cannot delete project on remote site %s." + repLog.warn(String.format("Cannot delete project on remote site %s." + " Only local paths and SSH URLs are supported" + " for remote repository deletion", replicateURI)); } @@ -299,7 +303,7 @@ try { recursivelyDelete(new File(uri.getPath())); } catch (IOException e) { - log.error(String.format( + repLog.error(String.format( "Error deleting local repository %s:\n", uri.getPath()), e); } @@ -330,7 +334,7 @@ try { executeRemoteSsh(uri, cmd, errStream); } catch (IOException e) { - log.error(String.format( + repLog.error(String.format( "Error deleting remote repository at %s:\n" + " Exception: %s\n" + " Command: %s\n" @@ -345,9 +349,10 @@ } else if (isSSH(replicateURI)) { updateHeadRemoteSsh(replicateURI, newHead); } else { - log.warn(String.format("Cannot update HEAD of project on remote site %s." - + " Only local paths and SSH URLs are supported" - + " for remote HEAD update.", replicateURI)); + repLog.warn(String.format( + "Cannot update HEAD of project on remote site %s." + + " Only local paths and SSH URLs are supported" + + " for remote HEAD update.", replicateURI)); } } @@ -359,7 +364,7 @@ try { executeRemoteSsh(uri, cmd, errStream); } catch (IOException e) { - log.error(String.format( + repLog.error(String.format( "Error updating HEAD of remote repository at %s to %s:\n" + " Exception: %s\n" + " Command: %s\n" @@ -380,7 +385,9 @@ repo.close(); } } catch (IOException e) { - log.error(String.format("Failed to update HEAD of repository %s to %s", uri.getPath(), newHead), e); + repLog.error( + String.format("Failed to update HEAD of repository %s to %s", + uri.getPath(), newHead), e); } }