Merge "Introduce SshSupport to centralize SSH related utility code"
This commit is contained in:
commit
6f82de449f
|
@ -47,9 +47,7 @@
|
|||
import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT_ENCODING;
|
||||
import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -66,20 +64,17 @@
|
|||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.transport.HttpConfig;
|
||||
import org.eclipse.jgit.transport.HttpTransport;
|
||||
import org.eclipse.jgit.transport.RemoteSession;
|
||||
import org.eclipse.jgit.transport.SshSessionFactory;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.eclipse.jgit.transport.http.HttpConnection;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.eclipse.jgit.util.HttpSupport;
|
||||
import org.eclipse.jgit.util.io.MessageWriter;
|
||||
import org.eclipse.jgit.util.io.StreamCopyThread;
|
||||
import org.eclipse.jgit.util.SshSupport;
|
||||
|
||||
/**
|
||||
* Provides means to get a valid LFS connection for a given repository.
|
||||
*/
|
||||
public class LfsConnectionFactory {
|
||||
|
||||
private static final int SSH_AUTH_TIMEOUT_SECONDS = 5;
|
||||
private static final String SCHEME_HTTPS = "https"; //$NON-NLS-1$
|
||||
private static final String SCHEME_SSH = "ssh"; //$NON-NLS-1$
|
||||
private static final Map<String, AuthCache> sshAuthCache = new TreeMap<>();
|
||||
|
@ -193,10 +188,11 @@ private static Protocol.ExpiringAction getSshAuthentication(
|
|||
// discover and authenticate; git-lfs does "ssh
|
||||
// -p <port> -- <host> git-lfs-authenticate
|
||||
// <project> <upload/download>"
|
||||
String json = runSshCommand(u.setPath(""), //$NON-NLS-1$
|
||||
db.getFS(),
|
||||
String json = SshSupport.runSshCommand(u.setPath(""), //$NON-NLS-1$
|
||||
null, db.getFS(),
|
||||
"git-lfs-authenticate " + extractProjectName(u) + " " //$NON-NLS-1$//$NON-NLS-2$
|
||||
+ purpose);
|
||||
+ purpose,
|
||||
SSH_AUTH_TIMEOUT_SECONDS);
|
||||
|
||||
action = Protocol.gson().fromJson(json,
|
||||
Protocol.ExpiringAction.class);
|
||||
|
@ -253,42 +249,6 @@ private static String extractProjectName(URIish u) {
|
|||
}
|
||||
}
|
||||
|
||||
private static String runSshCommand(URIish sshUri, FS fs, String command)
|
||||
throws IOException {
|
||||
RemoteSession session = null;
|
||||
Process process = null;
|
||||
StreamCopyThread errorThread = null;
|
||||
try (MessageWriter stderr = new MessageWriter()) {
|
||||
session = SshSessionFactory.getInstance().getSession(sshUri, null,
|
||||
fs, 5_000);
|
||||
process = session.exec(command, 0);
|
||||
errorThread = new StreamCopyThread(process.getErrorStream(),
|
||||
stderr.getRawStream());
|
||||
errorThread.start();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream(),
|
||||
org.eclipse.jgit.lib.Constants.CHARSET))) {
|
||||
return reader.readLine();
|
||||
}
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
if (errorThread != null) {
|
||||
try {
|
||||
errorThread.halt();
|
||||
} catch (InterruptedException e) {
|
||||
// Stop waiting and return anyway.
|
||||
} finally {
|
||||
errorThread = null;
|
||||
}
|
||||
}
|
||||
if (session != null) {
|
||||
SshSessionFactory.getInstance().releaseSession(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param operation
|
||||
* the operation to perform, e.g. Protocol.OPERATION_DOWNLOAD
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (C) 2018, Markus Duft <markus.duft@ssi-schaefer.com>
|
||||
* and other copyright owners as documented in the project's IP log.
|
||||
*
|
||||
* This program and the accompanying materials are made available
|
||||
* under the terms of the Eclipse Distribution License v1.0 which
|
||||
* accompanies this distribution, is reproduced below, and is
|
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the
|
||||
* names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.eclipse.jgit.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.eclipse.jgit.annotations.Nullable;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.RemoteSession;
|
||||
import org.eclipse.jgit.transport.SshSessionFactory;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.eclipse.jgit.util.io.MessageWriter;
|
||||
import org.eclipse.jgit.util.io.StreamCopyThread;
|
||||
|
||||
/**
|
||||
* Extra utilities to support usage of SSH.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public class SshSupport {
|
||||
|
||||
/**
|
||||
* Utility to execute a remote SSH command and read the first line of
|
||||
* output.
|
||||
*
|
||||
* @param sshUri
|
||||
* the SSH remote URI
|
||||
* @param provider
|
||||
* the {@link CredentialsProvider} or <code>null</code>.
|
||||
* @param fs
|
||||
* the {@link FS} implementation passed to
|
||||
* {@link SshSessionFactory}
|
||||
* @param command
|
||||
* the remote command to execute.
|
||||
* @param timeout
|
||||
* a timeout in seconds.
|
||||
* @return The first line of output read from stdout. Stderr is discarded.
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String runSshCommand(URIish sshUri,
|
||||
@Nullable CredentialsProvider provider, FS fs, String command,
|
||||
int timeout) throws IOException {
|
||||
RemoteSession session = null;
|
||||
Process process = null;
|
||||
StreamCopyThread errorThread = null;
|
||||
try (MessageWriter stderr = new MessageWriter()) {
|
||||
session = SshSessionFactory.getInstance().getSession(sshUri,
|
||||
provider, fs, 1000 * timeout);
|
||||
process = session.exec(command, 0);
|
||||
errorThread = new StreamCopyThread(process.getErrorStream(),
|
||||
stderr.getRawStream());
|
||||
errorThread.start();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream(),
|
||||
Constants.CHARSET))) {
|
||||
return reader.readLine();
|
||||
}
|
||||
} finally {
|
||||
if (errorThread != null) {
|
||||
try {
|
||||
errorThread.halt();
|
||||
} catch (InterruptedException e) {
|
||||
// Stop waiting and return anyway.
|
||||
} finally {
|
||||
errorThread = null;
|
||||
}
|
||||
}
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
if (session != null) {
|
||||
SshSessionFactory.getInstance().releaseSession(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue