summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/googlesource/gerrit/plugins/replication/GerritSshApi.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/googlesource/gerrit/plugins/replication/GerritSshApi.java')
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/GerritSshApi.java132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/GerritSshApi.java b/src/main/java/com/googlesource/gerrit/plugins/replication/GerritSshApi.java
new file mode 100644
index 0000000..b46a0d9
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/GerritSshApi.java
@@ -0,0 +1,132 @@
+// Copyright (C) 2017 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.reviewdb.client.Project;
+import com.google.gerrit.server.ssh.SshAddressesModule;
+import com.google.inject.Inject;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.jgit.transport.URIish;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GerritSshApi {
+ static int SSH_COMMAND_FAILED = -1;
+ private static final Logger log = LoggerFactory.getLogger(GerritSshApi.class);
+ private static String GERRIT_ADMIN_PROTOCOL_PREFIX = "gerrit+";
+
+ private final SshHelper sshHelper;
+
+ private final Set<URIish> withoutDeleteProjectPlugin = new HashSet<>();
+
+ @Inject
+ protected GerritSshApi(SshHelper sshHelper) {
+ this.sshHelper = sshHelper;
+ }
+
+ protected boolean createProject(URIish uri, Project.NameKey projectName, String head) {
+ OutputStream errStream = sshHelper.newErrorBufferStream();
+ String cmd = "gerrit create-project --branch " + head + " " + projectName.get();
+ try {
+ execute(uri, cmd, errStream);
+ } catch (IOException e) {
+ logError("creating", uri, errStream, cmd, e);
+ return false;
+ }
+ return true;
+ }
+
+ protected boolean deleteProject(URIish uri, Project.NameKey projectName) {
+ if (!withoutDeleteProjectPlugin.contains(uri)) {
+ OutputStream errStream = sshHelper.newErrorBufferStream();
+ String cmd = "deleteproject delete --yes-really-delete --force " + projectName.get();
+ int exitCode = -1;
+ try {
+ exitCode = execute(uri, cmd, errStream);
+ } catch (IOException e) {
+ logError("deleting", uri, errStream, cmd, e);
+ return false;
+ }
+ if (exitCode == 1) {
+ log.info(
+ "DeleteProject plugin is not installed on {}; will not try to forward this operation to that host");
+ withoutDeleteProjectPlugin.add(uri);
+ return true;
+ }
+ }
+ return true;
+ }
+
+ protected boolean updateHead(URIish uri, Project.NameKey projectName, String newHead) {
+ OutputStream errStream = sshHelper.newErrorBufferStream();
+ String cmd = "gerrit set-head " + projectName.get() + " --new-head " + newHead;
+ try {
+ execute(uri, cmd, errStream);
+ } catch (IOException e) {
+ log.error(
+ "Error updating HEAD of remote repository at {} to {}:\n"
+ + " Exception: {}\n Command: {}\n Output: {}",
+ uri,
+ newHead,
+ e,
+ cmd,
+ errStream,
+ e);
+ return false;
+ }
+ return true;
+ }
+
+ private URIish toSshUri(URIish uri) throws URISyntaxException {
+ String uriStr = uri.toString();
+ if (uri.getHost() != null && uriStr.startsWith(GERRIT_ADMIN_PROTOCOL_PREFIX)) {
+ return new URIish(uriStr.substring(GERRIT_ADMIN_PROTOCOL_PREFIX.length()));
+ }
+ String rawPath = uri.getRawPath();
+ if (!rawPath.endsWith("/")) {
+ rawPath = rawPath + "/";
+ }
+ URIish sshUri = new URIish("ssh://" + rawPath);
+ if (sshUri.getPort() < 0) {
+ sshUri = sshUri.setPort(SshAddressesModule.DEFAULT_PORT);
+ }
+ return sshUri;
+ }
+
+ private int execute(URIish uri, String cmd, OutputStream errStream) throws IOException {
+ try {
+ URIish sshUri = toSshUri(uri);
+ return sshHelper.executeRemoteSsh(sshUri, cmd, errStream);
+ } catch (URISyntaxException e) {
+ log.error("Cannot convert {} to SSH uri", uri, e);
+ }
+ return SSH_COMMAND_FAILED;
+ }
+
+ public void logError(String msg, URIish uri, OutputStream errStream, String cmd, IOException e) {
+ log.error(
+ "Error {} remote repository at {}:\n Exception: {}\n Command: {}\n Output: {}",
+ msg,
+ uri,
+ e,
+ cmd,
+ errStream,
+ e);
+ }
+}