Browse Source

Support the SSH configuration file (~/.ssh/config) in the sshexec, sshsession and scp tasks

This closes #106 pull request at github/apache/ant repo
master
Emmanuel Bourg Jaikiran Pai 5 years ago
parent
commit
b6143efab2
8 changed files with 99 additions and 7 deletions
  1. +4
    -0
      WHATSNEW
  2. +8
    -0
      manual/Tasks/scp.html
  3. +8
    -0
      manual/Tasks/sshexec.html
  4. +8
    -0
      manual/Tasks/sshsession.html
  5. +55
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
  6. +3
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java
  7. +3
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java
  8. +10
    -7
      src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java

+ 4
- 0
WHATSNEW View File

@@ -14,6 +14,10 @@ Fixed bugs:
files.
Bugzilla Report 63874

* sshexec, sshsession and scp now support a new sshConfig parameter.
It specified the SSH configuration file (typically ${user.home}/.ssh/config)
defining the username and keyfile to be used per host.

Other changes:
--------------



+ 8
- 0
manual/Tasks/scp.html View File

@@ -142,6 +142,14 @@ information. This task has been tested with <code>jsch-0.1.2</code> and later.<
<td>Passphrase for your private key.</td>
<td>No; defaults to an empty string</td>
</tr>
<tr>
<td>sshConfig</td>
<td>Location of the file holding the OpenSSH style configuration (e.g. <code>${user.home}/.ssh/config</code>).
The username and the key file are read from the configuration file,
unless they are already specified in the task parameters.
<em>since Ant 1.10.8</em></td>
<td>No</td>
</tr>
<tr>
<td>verbose</td>
<td>Determines whether SCP outputs verbosely to the user. Currently this means outputting


+ 8
- 0
manual/Tasks/sshexec.html View File

@@ -104,6 +104,14 @@ JSCh earlier than 0.1.28.</p>
<td>Passphrase for your private key.</td>
<td>No; defaults to an empty string</td>
</tr>
<tr>
<td>sshConfig</td>
<td>Location of the file holding the OpenSSH style configuration (e.g. <code>${user.home}/.ssh/config</code>).
The username and the key file are read from the configuration file,
unless they are already specified in the task parameters.
<em>since Ant 1.10.8</em></td>
<td>No</td>
</tr>
<tr>
<td>suppresssystemout</td>
<td>Whether to suppress system out. <em>since Ant 1.9.0</em></td>


+ 8
- 0
manual/Tasks/sshsession.html View File

@@ -110,6 +110,14 @@ JSCh earlier than 0.1.28.</p>
<td>Passphrase for your private key.</td>
<td>No; defaults to an empty string</td>
</tr>
<tr>
<td>sshConfig</td>
<td>Location of the file holding the OpenSSH style configuration (e.g. <code>${user.home}/.ssh/config</code>).
The username and the key file are read from the configuration file,
unless they are already specified in the task parameters.
<em>since Ant 1.10.8</em></td>
<td>No</td>
</tr>
<tr>
<td>timeout</td>
<td>Give up if the connection cannot be established within the specified time (given in


+ 55
- 0
src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java View File

@@ -18,6 +18,11 @@

package org.apache.tools.ant.taskdefs.optional.ssh;

import java.io.File;
import java.io.IOException;

import com.jcraft.jsch.ConfigRepository;
import com.jcraft.jsch.OpenSSHConfig;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
@@ -42,6 +47,7 @@ public abstract class SSHBase extends Task implements LogListener {
private boolean failOnError = true;
private boolean verbose;
private final SSHUserInfo userInfo;
private String sshConfig;
private int serverAliveCountMax = 3;
private int serverAliveIntervalSeconds = 0;

@@ -106,6 +112,24 @@ public abstract class SSHBase extends Task implements LogListener {
return verbose;
}

/**
* Get the OpenSSH config file (~/.ssh/config).
* @return the OpenSSH config file
* @since Ant 1.10.8
*/
public String getSshConfig() {
return sshConfig;
}

/**
* Set the OpenSSH config file (~/.ssh/config).
* @param sshConfig the OpenSSH config file
* @since Ant 1.10.8
*/
public void setSshConfig(String sshConfig) {
this.sshConfig = sshConfig;
}

/**
* Set the serverAliveCountMax value.
* @param countMax int
@@ -235,6 +259,37 @@ public abstract class SSHBase extends Task implements LogListener {
this.port = SSH_PORT;
}

/**
* Load the SSH configuration file.
* @throws BuildException on error
*/
protected void loadSshConfig() throws BuildException {
if (sshConfig != null && (userInfo.getName() == null || userInfo.getKeyfile() == null)) {
if (!new File(sshConfig).exists()) {
throw new BuildException("The SSH configuration file specified doesn't exist: " + sshConfig);
}
log("Loading SSH configuration file " + sshConfig, Project.MSG_DEBUG);
ConfigRepository.Config config = null;
try {
config = OpenSSHConfig.parseFile(sshConfig).getConfig(host);
} catch (IOException e) {
throw new BuildException("Failed to load the SSH configuration file " + sshConfig, e);
}
host = config.getHostname();
if (userInfo.getName() == null) {
userInfo.setName(config.getUser());
}
if (userInfo.getKeyfile() == null) {
log("Using SSH key file " + config.getValue("IdentityFile") + " for host " + host, Project.MSG_INFO);
userInfo.setKeyfile(config.getValue("IdentityFile"));
}
}
}

/**
* Open an ssh session.
* @return the opened session


+ 3
- 0
src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java View File

@@ -284,6 +284,9 @@ public class SSHExec extends SSHBase {
if (getHost() == null) {
throw new BuildException("Host is required.");
}
loadSshConfig();
if (getUserInfo().getName() == null) {
throw new BuildException("Username is required.");
}


+ 3
- 0
src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java View File

@@ -132,6 +132,9 @@ public class SSHSession extends SSHBase {
if (getHost() == null) {
throw new BuildException("Host is required.");
}
loadSshConfig();
if (getUserInfo().getName() == null) {
throw new BuildException("Username is required.");
}


+ 10
- 7
src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java View File

@@ -435,19 +435,22 @@ public class Scp extends SSHBase {
throw new BuildException("no username was given. Can't authenticate.");
}

if (getUserInfo().getPassword() == null
&& getUserInfo().getKeyfile() == null) {
throw new BuildException(
"neither password nor keyfile for user %s has been given. Can't authenticate.",
getUserInfo().getName());
}

final int indexOfPath = uri.indexOf(':', indexOfAt + 1);
if (indexOfPath == -1) {
throw new BuildException("no remote path in %s", uri);
}

setHost(uri.substring(indexOfAt + 1, indexOfPath));
loadSshConfig();
if (getUserInfo().getPassword() == null
&& getUserInfo().getKeyfile() == null) {
throw new BuildException(
"neither password nor keyfile for user %s has been given. Can't authenticate.",
getUserInfo().getName());
}
String remotePath = uri.substring(indexOfPath + 1);
if (remotePath.isEmpty()) {
remotePath = ".";


Loading…
Cancel
Save