mirror of https://github.com/apache/jclouds.git
reduced log clutter and hardened code
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2621 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
7f5b800470
commit
b9de6558d5
|
@ -19,7 +19,7 @@
|
||||||
====================================================================
|
====================================================================
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<project name="javassh" default="javassh" basedir=".">
|
<project name="sshjava" default="sshjava" basedir=".">
|
||||||
<description>
|
<description>
|
||||||
simple example build file
|
simple example build file
|
||||||
</description>
|
</description>
|
||||||
|
@ -67,17 +67,17 @@
|
||||||
<delete dir="${dist}"/>
|
<delete dir="${dist}"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<taskdef name="javassh" classname="org.jclouds.tools.ant.JavaOverSsh"/>
|
<taskdef name="sshjava" classname="org.jclouds.tools.ant.taskdefs.sshjava.SSHJava" />
|
||||||
|
|
||||||
<target name="javassh" depends="compile" description="remote execute the java command">
|
<target name="sshjava" depends="compile" description="remote execute the java command">
|
||||||
<echo message="normal java task"/>
|
<echo message="normal java task"/>
|
||||||
<java classname="TestClass" classpath="${build}" dir="${user.dir}" >
|
<java classname="TestClass" classpath="${build}" dir="${user.dir}" >
|
||||||
<arg line="${line}"/>
|
<arg line="${line}"/>
|
||||||
</java>
|
</java>
|
||||||
<echo message="java task over ssh"/>
|
<echo message="java task over ssh"/>
|
||||||
<javassh classname="TestClass" classpath="${build}" dir="${user.dir}" host="${host}" username="${username}" keyfile="${keyfile}" trust="true" remotedir="/tmp/test" >
|
<sshjava classname="TestClass" classpath="${build}" dir="${user.dir}" host="${host}" username="${username}" keyfile="${keyfile}" trust="true" remotebase="/tmp/test" >
|
||||||
<arg line="${line}"/>
|
<arg line="${line}"/>
|
||||||
</javassh>
|
</sshjava>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,394 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.tools.ant.taskdefs.optional.ssh;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.StringReader;
|
|
||||||
|
|
||||||
import org.apache.tools.ant.BuildException;
|
|
||||||
import org.apache.tools.ant.Project;
|
|
||||||
import org.apache.tools.ant.types.Resource;
|
|
||||||
import org.apache.tools.ant.types.resources.FileResource;
|
|
||||||
import org.apache.tools.ant.util.FileUtils;
|
|
||||||
import org.apache.tools.ant.util.KeepAliveOutputStream;
|
|
||||||
import org.apache.tools.ant.util.TeeOutputStream;
|
|
||||||
|
|
||||||
import com.jcraft.jsch.ChannelExec;
|
|
||||||
import com.jcraft.jsch.JSchException;
|
|
||||||
import com.jcraft.jsch.Session;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a command on a remote machine via ssh.
|
|
||||||
* @since Ant 1.6 (created February 2, 2003)
|
|
||||||
*/
|
|
||||||
public class SSHExec extends SSHBase {
|
|
||||||
|
|
||||||
private static final int BUFFER_SIZE = 8192;
|
|
||||||
private static final int RETRY_INTERVAL = 500;
|
|
||||||
|
|
||||||
/** the command to execute via ssh */
|
|
||||||
private String command = null;
|
|
||||||
|
|
||||||
/** units are milliseconds, default is 0=infinite */
|
|
||||||
private long maxwait = 0;
|
|
||||||
|
|
||||||
/** for waiting for the command to finish */
|
|
||||||
private Thread thread = null;
|
|
||||||
|
|
||||||
private String outputProperty = null;
|
|
||||||
private File outputFile = null;
|
|
||||||
private String errorProperty = null;
|
|
||||||
private File errorFile = null;
|
|
||||||
private String resultProperty;
|
|
||||||
private boolean append = false;
|
|
||||||
|
|
||||||
private Resource commandResource = null;
|
|
||||||
|
|
||||||
private static final String TIMEOUT_MESSAGE =
|
|
||||||
"Timeout period exceeded, connection dropped.";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for SSHExecTask.
|
|
||||||
*/
|
|
||||||
public SSHExec() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the command to execute on the remote host.
|
|
||||||
*
|
|
||||||
* @param command The new command value
|
|
||||||
*/
|
|
||||||
public void setCommand(String command) {
|
|
||||||
this.command = command;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a commandResource from a file
|
|
||||||
* @param f the value to use.
|
|
||||||
* @since Ant 1.7.1
|
|
||||||
*/
|
|
||||||
public void setCommandResource(String f) {
|
|
||||||
this.commandResource = new FileResource(new File(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The connection can be dropped after a specified number of
|
|
||||||
* milliseconds. This is sometimes useful when a connection may be
|
|
||||||
* flaky. Default is 0, which means "wait forever".
|
|
||||||
*
|
|
||||||
* @param timeout The new timeout value in seconds
|
|
||||||
*/
|
|
||||||
public void setTimeout(long timeout) {
|
|
||||||
maxwait = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If used, stores the output of the command to the given file.
|
|
||||||
*
|
|
||||||
* @param output The file to write to.
|
|
||||||
*/
|
|
||||||
public void setOutput(File output) {
|
|
||||||
outputFile = output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If used, stores the error of the command to the given file.
|
|
||||||
*
|
|
||||||
* @param error The file to write to.
|
|
||||||
*/
|
|
||||||
public void setError(File error) {
|
|
||||||
this.errorFile = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if the output is appended to the file given in
|
|
||||||
* <code>setOutput</code>. Default is false, that is, overwrite
|
|
||||||
* the file.
|
|
||||||
*
|
|
||||||
* @param append True to append to an existing file, false to overwrite.
|
|
||||||
*/
|
|
||||||
public void setAppend(boolean append) {
|
|
||||||
this.append = append;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If set, the output of the command will be stored in the given property.
|
|
||||||
*
|
|
||||||
* @param property The name of the property in which the command output
|
|
||||||
* will be stored.
|
|
||||||
*/
|
|
||||||
public void setOutputproperty(String property) {
|
|
||||||
outputProperty = property;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the property name whose value should be set to the error of
|
|
||||||
* the process.
|
|
||||||
*
|
|
||||||
* @param property The name of a property in which the standard error of
|
|
||||||
* the command should be stored.
|
|
||||||
*/
|
|
||||||
public void setErrorproperty(String property) {
|
|
||||||
errorProperty = property;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the name of the property in which the return code of the
|
|
||||||
* command should be stored. Only of interest if failonerror=false.
|
|
||||||
*
|
|
||||||
* @param resultProperty name of property.
|
|
||||||
*
|
|
||||||
* @since Ant 1.6
|
|
||||||
*/
|
|
||||||
public void setResultProperty(String resultProperty) {
|
|
||||||
this.resultProperty = resultProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the command on the remote host.
|
|
||||||
*
|
|
||||||
* @exception BuildException Most likely a network error or bad parameter.
|
|
||||||
*/
|
|
||||||
public void execute() throws BuildException {
|
|
||||||
if (getHost() == null) {
|
|
||||||
throw new BuildException("Host is required.");
|
|
||||||
}
|
|
||||||
if (getUserInfo().getName() == null) {
|
|
||||||
throw new BuildException("Username is required.");
|
|
||||||
}
|
|
||||||
if (getUserInfo().getKeyfile() == null
|
|
||||||
&& getUserInfo().getPassword() == null) {
|
|
||||||
throw new BuildException("Password or Keyfile is required.");
|
|
||||||
}
|
|
||||||
if (command == null && commandResource == null) {
|
|
||||||
throw new BuildException("Command or commandResource is required.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Session session = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
session = openSession();
|
|
||||||
/* called once */
|
|
||||||
if (command != null) {
|
|
||||||
log("cmd : " + command, Project.MSG_INFO);
|
|
||||||
ExecResponse response = executeCommand(session, command);
|
|
||||||
if (outputProperty != null) {
|
|
||||||
getProject().setNewProperty(outputProperty, response.getOutput());
|
|
||||||
}
|
|
||||||
if (errorProperty != null) {
|
|
||||||
getProject().setNewProperty(outputProperty, response.getError());
|
|
||||||
}
|
|
||||||
if (resultProperty != null) {
|
|
||||||
getProject().setNewProperty(resultProperty, response.getCode()+"");
|
|
||||||
}
|
|
||||||
} else { // read command resource and execute for each command
|
|
||||||
try {
|
|
||||||
BufferedReader br = new BufferedReader(
|
|
||||||
new InputStreamReader(commandResource.getInputStream()));
|
|
||||||
String cmd;
|
|
||||||
StringBuilder output = new StringBuilder();
|
|
||||||
StringBuilder error = new StringBuilder();
|
|
||||||
int lastCode = -1;
|
|
||||||
while ((cmd = br.readLine()) != null) {
|
|
||||||
log("cmd : " + cmd, Project.MSG_INFO);
|
|
||||||
ExecResponse response = executeCommand(session, cmd);
|
|
||||||
output.append(response.getOutput());
|
|
||||||
error.append(response.getError());
|
|
||||||
lastCode = response.getCode();
|
|
||||||
}
|
|
||||||
if (outputProperty != null) {
|
|
||||||
getProject().setNewProperty(outputProperty, output.toString());
|
|
||||||
}
|
|
||||||
if (errorProperty != null) {
|
|
||||||
getProject().setNewProperty(outputProperty, error.toString());
|
|
||||||
}
|
|
||||||
if (resultProperty != null) {
|
|
||||||
getProject().setNewProperty(resultProperty, lastCode+"");
|
|
||||||
}
|
|
||||||
FileUtils.close(br);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JSchException e) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
} finally {
|
|
||||||
if (session != null && session.isConnected()) {
|
|
||||||
session.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static class ExecResponse {
|
|
||||||
|
|
||||||
private final String output;
|
|
||||||
private final String error;
|
|
||||||
private final int code;
|
|
||||||
|
|
||||||
public ExecResponse(String output, String error, int code) {
|
|
||||||
this.output = output;
|
|
||||||
this.error = error;
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getError() {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOutput() {
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private ExecResponse executeCommand(Session session, String cmd)
|
|
||||||
throws BuildException {
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
TeeOutputStream tee = new TeeOutputStream(out, new KeepAliveOutputStream(System.out));
|
|
||||||
ByteArrayOutputStream err = new ByteArrayOutputStream();
|
|
||||||
TeeOutputStream teeErr = new TeeOutputStream(err, new KeepAliveOutputStream(System.err));
|
|
||||||
int ec = -1;
|
|
||||||
|
|
||||||
try {
|
|
||||||
final ChannelExec channel;
|
|
||||||
session.setTimeout((int) maxwait);
|
|
||||||
/* execute the command */
|
|
||||||
channel = (ChannelExec) session.openChannel("exec");
|
|
||||||
channel.setCommand(cmd);
|
|
||||||
channel.setOutputStream(tee);
|
|
||||||
channel.setExtOutputStream(tee);
|
|
||||||
channel.setErrStream(teeErr);
|
|
||||||
channel.connect();
|
|
||||||
// wait for it to finish
|
|
||||||
thread =
|
|
||||||
new Thread() {
|
|
||||||
public void run() {
|
|
||||||
while (!channel.isClosed()) {
|
|
||||||
if (thread == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
sleep(RETRY_INTERVAL);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
thread.start();
|
|
||||||
thread.join(maxwait);
|
|
||||||
|
|
||||||
if (thread.isAlive()) {
|
|
||||||
// ran out of time
|
|
||||||
thread = null;
|
|
||||||
if (getFailonerror()) {
|
|
||||||
throw new BuildException(TIMEOUT_MESSAGE);
|
|
||||||
} else {
|
|
||||||
log(TIMEOUT_MESSAGE, Project.MSG_ERR);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//success
|
|
||||||
if (outputFile != null) {
|
|
||||||
writeToFile(out.toString(), append, outputFile);
|
|
||||||
}
|
|
||||||
if (errorFile != null) {
|
|
||||||
writeToFile(err.toString(), append, errorFile);
|
|
||||||
}
|
|
||||||
// this is the wrong test if the remote OS is OpenVMS,
|
|
||||||
// but there doesn't seem to be a way to detect it.
|
|
||||||
ec = channel.getExitStatus();
|
|
||||||
if (ec != 0) {
|
|
||||||
String msg = "Remote command failed with exit status " + ec;
|
|
||||||
if (getFailonerror()) {
|
|
||||||
throw new BuildException(msg);
|
|
||||||
} else {
|
|
||||||
log(msg, Project.MSG_ERR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (BuildException e) {
|
|
||||||
throw e;
|
|
||||||
} catch (JSchException e) {
|
|
||||||
if (e.getMessage().indexOf("session is down") >= 0) {
|
|
||||||
if (getFailonerror()) {
|
|
||||||
throw new BuildException(TIMEOUT_MESSAGE, e);
|
|
||||||
} else {
|
|
||||||
log(TIMEOUT_MESSAGE, Project.MSG_ERR);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (getFailonerror()) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
} else {
|
|
||||||
log("Caught exception: " + e.getMessage(),
|
|
||||||
Project.MSG_ERR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (getFailonerror()) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
} else {
|
|
||||||
log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ExecResponse(out.toString(), err.toString(), ec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a string to a file. If destination file exists, it may be
|
|
||||||
* overwritten depending on the "append" value.
|
|
||||||
*
|
|
||||||
* @param from string to write
|
|
||||||
* @param to file to write to
|
|
||||||
* @param append if true, append to existing file, else overwrite
|
|
||||||
* @exception Exception most likely an IOException
|
|
||||||
*/
|
|
||||||
private void writeToFile(String from, boolean append, File to)
|
|
||||||
throws IOException {
|
|
||||||
FileWriter out = null;
|
|
||||||
try {
|
|
||||||
out = new FileWriter(to.getAbsolutePath(), append);
|
|
||||||
StringReader in = new StringReader(from);
|
|
||||||
char[] buffer = new char[BUFFER_SIZE];
|
|
||||||
int bytesRead;
|
|
||||||
while (true) {
|
|
||||||
bytesRead = in.read(buffer);
|
|
||||||
if (bytesRead == -1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
out.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
} finally {
|
|
||||||
if (out != null) {
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,338 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* 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 org.jclouds.tools.ant.taskdefs.sshjava;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.apache.tools.ant.BuildException;
|
||||||
|
import org.apache.tools.ant.Project;
|
||||||
|
import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
|
||||||
|
import org.apache.tools.ant.taskdefs.PumpStreamHandler;
|
||||||
|
import org.apache.tools.ant.taskdefs.optional.ssh.SSHUserInfo;
|
||||||
|
import org.apache.tools.ant.util.FileUtils;
|
||||||
|
|
||||||
|
import com.jcraft.jsch.ChannelExec;
|
||||||
|
import com.jcraft.jsch.JSch;
|
||||||
|
import com.jcraft.jsch.JSchException;
|
||||||
|
import com.jcraft.jsch.Session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a command on a remote machine via ssh.
|
||||||
|
*
|
||||||
|
* <p/>
|
||||||
|
* adapted from SSHBase and SSHExec ant tasks, and Execute from the ant 1.7.1 release.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SSHExecute {
|
||||||
|
|
||||||
|
private static final int RETRY_INTERVAL = 500;
|
||||||
|
|
||||||
|
/** units are milliseconds, default is 0=infinite */
|
||||||
|
private long maxwait = 0;
|
||||||
|
|
||||||
|
private ExecuteStreamHandler streamHandler;
|
||||||
|
private String host;
|
||||||
|
private SSHUserInfo userInfo;
|
||||||
|
private int port = 22;
|
||||||
|
private Project project;
|
||||||
|
private String knownHosts = System.getProperty("user.home") + "/.ssh/known_hosts";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new execute object using <code>PumpStreamHandler</code> for stream handling.
|
||||||
|
*/
|
||||||
|
public SSHExecute() {
|
||||||
|
this(new PumpStreamHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new ssh object.
|
||||||
|
*
|
||||||
|
* @param streamHandler
|
||||||
|
* the stream handler used to handle the input and output streams of the subprocess.
|
||||||
|
*/
|
||||||
|
public SSHExecute(ExecuteStreamHandler streamHandler) {
|
||||||
|
setStreamHandler(streamHandler);
|
||||||
|
userInfo = new SSHUserInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stream handler to use.
|
||||||
|
*
|
||||||
|
* @param streamHandler
|
||||||
|
* ExecuteStreamHandler.
|
||||||
|
*/
|
||||||
|
public void setStreamHandler(ExecuteStreamHandler streamHandler) {
|
||||||
|
this.streamHandler = streamHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setting this to true trusts hosts whose identity is unknown.
|
||||||
|
*
|
||||||
|
* @param yesOrNo
|
||||||
|
* if true trust the identity of unknown hosts.
|
||||||
|
*/
|
||||||
|
public void setTrust(boolean yesOrNo) {
|
||||||
|
userInfo.setTrust(yesOrNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for logging
|
||||||
|
*/
|
||||||
|
public void setProject(Project project) {
|
||||||
|
this.project = project;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username known to remote host.
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* The new username value
|
||||||
|
*/
|
||||||
|
public void setUsername(String username) {
|
||||||
|
userInfo.setName(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the password for the user.
|
||||||
|
*
|
||||||
|
* @param password
|
||||||
|
* The new password value
|
||||||
|
*/
|
||||||
|
public void setPassword(String password) {
|
||||||
|
userInfo.setPassword(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the keyfile for the user.
|
||||||
|
*
|
||||||
|
* @param keyfile
|
||||||
|
* The new keyfile value
|
||||||
|
*/
|
||||||
|
public void setKeyfile(String keyfile) {
|
||||||
|
userInfo.setKeyfile(keyfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the passphrase for the users key.
|
||||||
|
*
|
||||||
|
* @param passphrase
|
||||||
|
* The new passphrase value
|
||||||
|
*/
|
||||||
|
public void setPassphrase(String passphrase) {
|
||||||
|
userInfo.setPassphrase(passphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote host, either DNS name or IP.
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* The new host value
|
||||||
|
*/
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the port used to connect to the remote host.
|
||||||
|
*
|
||||||
|
* @param port
|
||||||
|
* port number of remote host.
|
||||||
|
*/
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection can be dropped after a specified number of milliseconds. This is sometimes
|
||||||
|
* useful when a connection may be flaky. Default is 0, which means "wait forever".
|
||||||
|
*
|
||||||
|
* @param timeout
|
||||||
|
* The new timeout value in seconds
|
||||||
|
*/
|
||||||
|
public void setTimeout(long timeout) {
|
||||||
|
maxwait = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the path to the file that has the identities of all known hosts. This is used by SSH
|
||||||
|
* protocol to validate the identity of the host. The default is
|
||||||
|
* <i>${user.home}/.ssh/known_hosts</i>.
|
||||||
|
*
|
||||||
|
* @param knownHosts
|
||||||
|
* a path to the known hosts file.
|
||||||
|
*/
|
||||||
|
public void setKnownhosts(String knownHosts) {
|
||||||
|
this.knownHosts = knownHosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the command on the remote host.
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* - what to execute on the remote host.
|
||||||
|
*
|
||||||
|
* @return return code of the process.
|
||||||
|
* @throws BuildException
|
||||||
|
* bad parameter.
|
||||||
|
* @throws JSchException
|
||||||
|
* if there's an underlying problem exposed in SSH
|
||||||
|
* @throws IOException
|
||||||
|
* if there's a problem attaching streams.
|
||||||
|
* @throws TimeoutException
|
||||||
|
* if we exceeded our timeout
|
||||||
|
*/
|
||||||
|
public int execute(String command) throws BuildException, JSchException, IOException,
|
||||||
|
TimeoutException {
|
||||||
|
if (command == null) {
|
||||||
|
throw new BuildException("Command is required.");
|
||||||
|
}
|
||||||
|
if (host == null) {
|
||||||
|
throw new BuildException("Host is required.");
|
||||||
|
}
|
||||||
|
if (userInfo.getName() == null) {
|
||||||
|
throw new BuildException("Username is required.");
|
||||||
|
}
|
||||||
|
if (userInfo.getKeyfile() == null && userInfo.getPassword() == null) {
|
||||||
|
throw new BuildException("Password or Keyfile is required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
try {
|
||||||
|
session = openSession();
|
||||||
|
return executeCommand(session, command);
|
||||||
|
} finally {
|
||||||
|
if (session != null && session.isConnected()) {
|
||||||
|
session.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open an ssh seession.
|
||||||
|
*
|
||||||
|
* @return the opened session
|
||||||
|
* @throws JSchException
|
||||||
|
* on error
|
||||||
|
*/
|
||||||
|
protected Session openSession() throws JSchException {
|
||||||
|
JSch jsch = new JSch();
|
||||||
|
if (null != userInfo.getKeyfile()) {
|
||||||
|
jsch.addIdentity(userInfo.getKeyfile());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userInfo.getTrust() && knownHosts != null) {
|
||||||
|
project.log("Using known hosts: " + knownHosts, Project.MSG_DEBUG);
|
||||||
|
jsch.setKnownHosts(knownHosts);
|
||||||
|
}
|
||||||
|
|
||||||
|
Session session = jsch.getSession(userInfo.getName(), host, port);
|
||||||
|
session.setUserInfo(userInfo);
|
||||||
|
project.log("Connecting to " + host + ":" + port, Project.MSG_VERBOSE);
|
||||||
|
session.connect();
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* FIXME Comment this
|
||||||
|
*
|
||||||
|
* @param session
|
||||||
|
* @param cmd
|
||||||
|
* @return return code of the process.
|
||||||
|
* @throws JSchException
|
||||||
|
* if there's an underlying problem exposed in SSH
|
||||||
|
* @throws IOException
|
||||||
|
* if there's a problem attaching streams.
|
||||||
|
* @throws TimeoutException
|
||||||
|
* if we exceeded our timeout
|
||||||
|
*/
|
||||||
|
private int executeCommand(Session session, String cmd) throws JSchException, IOException,
|
||||||
|
TimeoutException {
|
||||||
|
final ChannelExec channel;
|
||||||
|
session.setTimeout((int) maxwait);
|
||||||
|
/* execute the command */
|
||||||
|
channel = (ChannelExec) session.openChannel("exec");
|
||||||
|
channel.setCommand(cmd);
|
||||||
|
attachStreams(channel);
|
||||||
|
project.log("executing command: " + cmd, Project.MSG_VERBOSE);
|
||||||
|
channel.connect();
|
||||||
|
try {
|
||||||
|
waitFor(channel);
|
||||||
|
} finally {
|
||||||
|
streamHandler.stop();
|
||||||
|
closeStreams(channel);
|
||||||
|
}
|
||||||
|
return channel.getExitStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void attachStreams(final ChannelExec channel) throws IOException {
|
||||||
|
streamHandler.setProcessInputStream(channel.getOutputStream());
|
||||||
|
streamHandler.setProcessOutputStream(channel.getInputStream());
|
||||||
|
streamHandler.setProcessErrorStream(channel.getErrStream());
|
||||||
|
streamHandler.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the streams belonging to the given Process.
|
||||||
|
*
|
||||||
|
* @param process
|
||||||
|
* the <code>Process</code>.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void closeStreams(ChannelExec process) throws IOException {
|
||||||
|
FileUtils.close(process.getInputStream());
|
||||||
|
FileUtils.close(process.getOutputStream());
|
||||||
|
FileUtils.close(process.getErrStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws TimeoutException
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private void waitFor(final ChannelExec channel) throws TimeoutException {
|
||||||
|
// wait for it to finish
|
||||||
|
Thread thread = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
while (!channel.isClosed()) {
|
||||||
|
try {
|
||||||
|
sleep(RETRY_INTERVAL);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
thread.start();
|
||||||
|
try {
|
||||||
|
thread.join(maxwait);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread.isAlive()) {
|
||||||
|
thread.destroy();
|
||||||
|
throw new TimeoutException("command still running");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,22 +25,18 @@ import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.apache.tools.ant.BuildException;
|
import org.apache.tools.ant.BuildException;
|
||||||
import org.apache.tools.ant.Location;
|
import org.apache.tools.ant.Location;
|
||||||
import org.apache.tools.ant.MagicNames;
|
|
||||||
import org.apache.tools.ant.Project;
|
import org.apache.tools.ant.Project;
|
||||||
import org.apache.tools.ant.PropertyHelper;
|
|
||||||
import org.apache.tools.ant.Target;
|
import org.apache.tools.ant.Target;
|
||||||
import org.apache.tools.ant.Task;
|
import org.apache.tools.ant.Task;
|
||||||
import org.apache.tools.ant.taskdefs.Java;
|
import org.apache.tools.ant.taskdefs.Java;
|
||||||
import org.apache.tools.ant.taskdefs.optional.ssh.SSHExec;
|
|
||||||
import org.apache.tools.ant.taskdefs.optional.ssh.SSHUserInfo;
|
import org.apache.tools.ant.taskdefs.optional.ssh.SSHUserInfo;
|
||||||
import org.apache.tools.ant.taskdefs.optional.ssh.Scp;
|
import org.apache.tools.ant.taskdefs.optional.ssh.Scp;
|
||||||
import org.apache.tools.ant.types.CommandlineJava;
|
import org.apache.tools.ant.types.CommandlineJava;
|
||||||
|
@ -60,6 +56,7 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.jcraft.jsch.JSchException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version of the Java task that executes over ssh.
|
* Version of the Java task that executes over ssh.
|
||||||
|
@ -67,11 +64,9 @@ import com.google.common.collect.Maps;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class SSHJava extends Java {
|
public class SSHJava extends Java {
|
||||||
private final SSHExec exec;
|
private final SSHExecute exec;
|
||||||
private final Scp scp;
|
private final Scp scp;
|
||||||
private final SSHUserInfo userInfo;
|
private final SSHUserInfo userInfo;
|
||||||
|
|
||||||
private String jvm = "/usr/bin/java";
|
|
||||||
private File localDirectory;
|
private File localDirectory;
|
||||||
private File remotebase;
|
private File remotebase;
|
||||||
private File remotedir;
|
private File remotedir;
|
||||||
|
@ -91,7 +86,8 @@ public class SSHJava extends Java {
|
||||||
public SSHJava() {
|
public SSHJava() {
|
||||||
super();
|
super();
|
||||||
setFork(true);
|
setFork(true);
|
||||||
exec = new SSHExec();
|
exec = new SSHExecute();
|
||||||
|
exec.setProject(getProject());
|
||||||
scp = new Scp();
|
scp = new Scp();
|
||||||
userInfo = new SSHUserInfo();
|
userInfo = new SSHUserInfo();
|
||||||
}
|
}
|
||||||
|
@ -107,7 +103,6 @@ public class SSHJava extends Java {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int executeJava() throws BuildException {
|
public int executeJava() throws BuildException {
|
||||||
checkNotNull(jvm, "jvm must be set");
|
|
||||||
checkNotNull(remotebase, "remotebase must be set");
|
checkNotNull(remotebase, "remotebase must be set");
|
||||||
|
|
||||||
if (localDirectory == null) {
|
if (localDirectory == null) {
|
||||||
|
@ -124,13 +119,13 @@ public class SSHJava extends Java {
|
||||||
|
|
||||||
if (osFamily == OsFamily.UNIX) {
|
if (osFamily == OsFamily.UNIX) {
|
||||||
log("removing old contents: " + remotedir.getAbsolutePath(), Project.MSG_VERBOSE);
|
log("removing old contents: " + remotedir.getAbsolutePath(), Project.MSG_VERBOSE);
|
||||||
exec.setCommand(exec("rm -rf " + remotedir.getAbsolutePath()).render(osFamily));
|
sshexec(exec("rm -rf " + remotedir.getAbsolutePath()).render(osFamily));
|
||||||
exec.execute();
|
|
||||||
} else {
|
} else {
|
||||||
// TODO need recursive remove on windows
|
// TODO need recursive remove on windows
|
||||||
}
|
}
|
||||||
// must copy the files over first as we are changing the system properties based on this.
|
// must copy the files over first as we are changing the system properties based on this.
|
||||||
String command = convertJavaToScriptNormalizingPaths(getCommandLine());
|
String command = createInitScript(osFamily, id, remotedir.getAbsolutePath(), env,
|
||||||
|
getCommandLine());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BufferedWriter out = new BufferedWriter(new FileWriter(new File(localDirectory, "init."
|
BufferedWriter out = new BufferedWriter(new FileWriter(new File(localDirectory, "init."
|
||||||
|
@ -162,27 +157,43 @@ public class SSHJava extends Java {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (osFamily == OsFamily.UNIX) {
|
if (osFamily == OsFamily.UNIX) {
|
||||||
exec.setCommand(exec("chmod 755 " + remotedir.getAbsolutePath() + "{fs}init.{sh}").render(
|
sshexec(exec("chmod 755 " + remotedir.getAbsolutePath() + "{fs}init.{sh}")
|
||||||
osFamily));
|
.render(osFamily));
|
||||||
exec.execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement statement = new StatementList(exec("{cd} " + remotedir.getAbsolutePath()),
|
Statement statement = new StatementList(exec("{cd} " + remotedir.getAbsolutePath()),
|
||||||
exec(remotedir.getAbsolutePath() + "{fs}init.{sh} init"), exec(remotedir
|
exec(remotedir.getAbsolutePath() + "{fs}init.{sh} init"), exec(remotedir
|
||||||
.getAbsolutePath()
|
.getAbsolutePath()
|
||||||
+ "{fs}init.{sh} run"));
|
+ "{fs}init.{sh} run"));
|
||||||
getProjectProperties().remove(id);
|
try {
|
||||||
exec.setResultProperty(id);
|
return sshexecRedirectStreams(statement);
|
||||||
exec.setFailonerror(false);
|
} catch (IOException e) {
|
||||||
exec.setCommand(statement.render(osFamily));
|
throw new BuildException(e, getLocation());
|
||||||
exec.setError(errorFile);
|
}
|
||||||
exec.setErrorproperty(errorProperty);
|
}
|
||||||
exec.setOutput(outputFile);
|
|
||||||
exec.setOutputproperty(outputProperty);
|
private int sshexec(String command) {
|
||||||
exec.setAppend(append);
|
try {
|
||||||
|
return exec.execute(command);
|
||||||
|
} catch (JSchException e) {
|
||||||
|
throw new BuildException(e, getLocation());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new BuildException(e, getLocation());
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
throw new BuildException(e, getLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int sshexecRedirectStreams(Statement statement) throws IOException {
|
||||||
|
exec.setStreamHandler(redirector.createHandler());
|
||||||
log("starting java as:\n" + statement.render(osFamily), Project.MSG_VERBOSE);
|
log("starting java as:\n" + statement.render(osFamily), Project.MSG_VERBOSE);
|
||||||
exec.execute();
|
int rc;
|
||||||
return Integer.parseInt(getProject().getProperty(id));
|
try {
|
||||||
|
rc = sshexec(statement.render(osFamily));
|
||||||
|
} finally {
|
||||||
|
redirector.complete();
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mkdirAndCopyTo(String destination, Iterable<FileSet> sets) {
|
private void mkdirAndCopyTo(String destination, Iterable<FileSet> sets) {
|
||||||
|
@ -190,19 +201,11 @@ public class SSHJava extends Java {
|
||||||
log("no content: " + destination, Project.MSG_DEBUG);
|
log("no content: " + destination, Project.MSG_DEBUG);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
exec.setCommand(exec("test -d " + destination).render(osFamily)); // TODO windows
|
if (sshexec(exec("test -d " + destination).render(osFamily)) == 0) {// TODO windows
|
||||||
getProjectProperties().remove(id);
|
|
||||||
exec.setResultProperty(id);
|
|
||||||
exec.setFailonerror(false);
|
|
||||||
exec.execute();
|
|
||||||
if (getProject().getProperty(id).equals("0")) {
|
|
||||||
log("already created: " + destination, Project.MSG_VERBOSE);
|
log("already created: " + destination, Project.MSG_VERBOSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getProjectProperties().remove(id);
|
sshexec(exec("{md} " + destination).render(osFamily));
|
||||||
exec.setCommand(exec("{md} " + destination).render(osFamily));
|
|
||||||
exec.setFailonerror(true);
|
|
||||||
exec.execute();
|
|
||||||
scp.init();
|
scp.init();
|
||||||
String scpDestination = getScpDir(destination);
|
String scpDestination = getScpDir(destination);
|
||||||
log("staging: " + scpDestination, Project.MSG_VERBOSE);
|
log("staging: " + scpDestination, Project.MSG_VERBOSE);
|
||||||
|
@ -271,20 +274,21 @@ public class SSHJava extends Java {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
String convertJavaToScriptNormalizingPaths(CommandlineJava commandLine) {
|
String createInitScript(OsFamily osFamily, String id, String basedir, Environment env,
|
||||||
|
CommandlineJava commandLine) {
|
||||||
|
|
||||||
Map<String, String> envVariables = Maps.newHashMap();
|
Map<String, String> envVariables = Maps.newHashMap();
|
||||||
String[] environment = env.getVariables();
|
String[] environment = env.getVariables();
|
||||||
if (environment != null) {
|
if (environment != null) {
|
||||||
for (int i = 0; i < environment.length; i++) {
|
for (int i = 0; i < environment.length; i++) {
|
||||||
log("Setting environment variable: " + environment[i], Project.MSG_VERBOSE);
|
log("Setting environment variable: " + environment[i], Project.MSG_DEBUG);
|
||||||
String[] keyValue = environment[i].split("=");
|
String[] keyValue = environment[i].split("=");
|
||||||
envVariables.put(keyValue[0], keyValue[1]);
|
envVariables.put(keyValue[0], keyValue[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder commandBuilder = new StringBuilder(jvm);
|
StringBuilder commandBuilder = new StringBuilder(commandLine.getVmCommand().getExecutable());
|
||||||
if (getCommandLine().getBootclasspath() != null) {
|
if (commandLine.getBootclasspath() != null) {
|
||||||
commandBuilder.append(" -Xbootclasspath:bootclasspath");
|
commandBuilder.append(" -Xbootclasspath:bootclasspath");
|
||||||
resetPathToUnderPrefixIfExistsAndIsFileIfNotExistsAddAsIs(commandLine.getBootclasspath(),
|
resetPathToUnderPrefixIfExistsAndIsFileIfNotExistsAddAsIs(commandLine.getBootclasspath(),
|
||||||
"bootclasspath", commandBuilder);
|
"bootclasspath", commandBuilder);
|
||||||
|
@ -314,8 +318,8 @@ public class SSHJava extends Java {
|
||||||
Joiner.on(' ').join(commandLine.getJavaCommand().getArguments()));
|
Joiner.on(' ').join(commandLine.getJavaCommand().getArguments()));
|
||||||
}
|
}
|
||||||
|
|
||||||
InitBuilder testInitBuilder = new InitBuilder(id, remotedir.getAbsolutePath(), remotedir
|
InitBuilder testInitBuilder = new InitBuilder(id, basedir, basedir, envVariables,
|
||||||
.getAbsolutePath(), envVariables, commandBuilder.toString());
|
commandBuilder.toString());
|
||||||
String script = testInitBuilder.build(osFamily);
|
String script = testInitBuilder.build(osFamily);
|
||||||
return reprefix(script);
|
return reprefix(script);
|
||||||
}
|
}
|
||||||
|
@ -348,11 +352,6 @@ public class SSHJava extends Java {
|
||||||
throw new IllegalArgumentException("this only operates when fork is set");
|
throw new IllegalArgumentException("this only operates when fork is set");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setJvm(String jvm) {
|
|
||||||
this.jvm = checkNotNull(jvm, "jvm");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remote host, either DNS name or IP.
|
* Remote host, either DNS name or IP.
|
||||||
*
|
*
|
||||||
|
@ -364,15 +363,6 @@ public class SSHJava extends Java {
|
||||||
scp.setHost(host);
|
scp.setHost(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the host.
|
|
||||||
*
|
|
||||||
* @return the host
|
|
||||||
*/
|
|
||||||
public String getHost() {
|
|
||||||
return exec.getHost();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Username known to remote host.
|
* Username known to remote host.
|
||||||
*
|
*
|
||||||
|
@ -459,27 +449,6 @@ public class SSHJava extends Java {
|
||||||
scp.setPort(port);
|
scp.setPort(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the port attribute.
|
|
||||||
*
|
|
||||||
* @return the port
|
|
||||||
*/
|
|
||||||
public int getPort() {
|
|
||||||
return exec.getPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the task. This initializizs the known hosts and sets the default port.
|
|
||||||
*
|
|
||||||
* @throws BuildException
|
|
||||||
* on error
|
|
||||||
*/
|
|
||||||
public void init() throws BuildException {
|
|
||||||
super.init();
|
|
||||||
exec.init();
|
|
||||||
scp.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The connection can be dropped after a specified number of milliseconds. This is sometimes
|
* The connection can be dropped after a specified number of milliseconds. This is sometimes
|
||||||
* useful when a connection may be flaky. Default is 0, which means "wait forever".
|
* useful when a connection may be flaky. Default is 0, which means "wait forever".
|
||||||
|
@ -491,43 +460,6 @@ public class SSHJava extends Java {
|
||||||
exec.setTimeout(timeout);
|
exec.setTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the verbose flag.
|
|
||||||
*
|
|
||||||
* @param verbose
|
|
||||||
* if true output more verbose logging
|
|
||||||
* @since Ant 1.6.2
|
|
||||||
*/
|
|
||||||
public void setVerbose(boolean verbose) {
|
|
||||||
exec.setVerbose(verbose);
|
|
||||||
scp.setVerbose(verbose);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setError(File error) {
|
|
||||||
this.errorFile = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setErrorProperty(String property) {
|
|
||||||
errorProperty = property;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOutput(File out) {
|
|
||||||
outputFile = out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOutputproperty(String outputProp) {
|
|
||||||
outputProperty = outputProp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAppend(boolean append) {
|
|
||||||
this.append = append;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setProject(Project project) {
|
public void setProject(Project project) {
|
||||||
super.setProject(project);
|
super.setProject(project);
|
||||||
|
@ -538,45 +470,40 @@ public class SSHJava extends Java {
|
||||||
@Override
|
@Override
|
||||||
public void setOwningTarget(Target target) {
|
public void setOwningTarget(Target target) {
|
||||||
super.setOwningTarget(target);
|
super.setOwningTarget(target);
|
||||||
exec.setOwningTarget(target);
|
|
||||||
scp.setOwningTarget(target);
|
scp.setOwningTarget(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTaskName(String taskName) {
|
public void setTaskName(String taskName) {
|
||||||
super.setTaskName(taskName);
|
super.setTaskName(taskName);
|
||||||
exec.setTaskName(taskName);
|
|
||||||
scp.setTaskName(taskName);
|
scp.setTaskName(taskName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDescription(String description) {
|
public void setDescription(String description) {
|
||||||
super.setDescription(description);
|
super.setDescription(description);
|
||||||
exec.setDescription(description);
|
|
||||||
scp.setDescription(description);
|
scp.setDescription(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLocation(Location location) {
|
public void setLocation(Location location) {
|
||||||
super.setLocation(location);
|
super.setLocation(location);
|
||||||
exec.setLocation(location);
|
|
||||||
scp.setLocation(location);
|
scp.setLocation(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTaskType(String type) {
|
public void setTaskType(String type) {
|
||||||
super.setTaskType(type);
|
super.setTaskType(type);
|
||||||
exec.setTaskType(type);
|
|
||||||
scp.setTaskType(type);
|
scp.setTaskType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SSHJava [append=" + append + ", env=" + env + ", errorFile=" + errorFile
|
return "SSHJava [append=" + append + ", env=" + env + ", errorFile=" + errorFile
|
||||||
+ ", errorProperty=" + errorProperty + ", jvm=" + jvm + ", localDirectory="
|
+ ", errorProperty=" + errorProperty + ", localDirectory=" + localDirectory
|
||||||
+ localDirectory + ", osFamily=" + osFamily + ", outputFile=" + outputFile
|
+ ", osFamily=" + osFamily + ", outputFile=" + outputFile + ", outputProperty="
|
||||||
+ ", outputProperty=" + outputProperty + ", remoteDirectory=" + remotebase
|
+ outputProperty + ", remoteDirectory=" + remotebase + ", userInfo=" + userInfo
|
||||||
+ ", userInfo=" + userInfo + "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -592,17 +519,4 @@ public class SSHJava extends Java {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Hashtable<String, String> getProjectProperties() {
|
|
||||||
PropertyHelper helper = (PropertyHelper) getProject().getReference(
|
|
||||||
MagicNames.REFID_PROPERTY_HELPER);
|
|
||||||
Field field;
|
|
||||||
try {
|
|
||||||
field = PropertyHelper.class.getDeclaredField("properties");
|
|
||||||
field.setAccessible(true);
|
|
||||||
return (Hashtable<String, String>) field.get(helper);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,28 +47,9 @@ public class SSHJavaTest {
|
||||||
.entrySet());
|
.entrySet());
|
||||||
|
|
||||||
// TODO, this test will break in windows
|
// TODO, this test will break in windows
|
||||||
@Test(enabled = false)
|
public void testShift() throws SecurityException, NoSuchMethodException {
|
||||||
public void testFull() throws SecurityException, NoSuchMethodException {
|
|
||||||
SSHJava task = makeSSHJava();
|
|
||||||
String expected = String
|
|
||||||
.format(
|
|
||||||
"export %s=\"%s\"%ncd /tmp/foo\n%s -Xms16m -Xmx32m -cp classpath -Dfooble=baz -Dfoo=bar org.jclouds.tools.ant.TestClass %s hello world\n",
|
|
||||||
LAST_ENV.getKey(), LAST_ENV.getValue(), System.getProperty("java.home")
|
|
||||||
+ "/bin/java", LAST_ENV.getKey());
|
|
||||||
assertEquals(task.convertJavaToScriptNormalizingPaths(task.getCommandLine()), expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO, this test will break in windows
|
|
||||||
@Test(enabled = false)
|
|
||||||
public void testFullShift() throws SecurityException, NoSuchMethodException {
|
|
||||||
SSHJava task = makeSSHJava();
|
SSHJava task = makeSSHJava();
|
||||||
task = directoryShift(task);
|
task = directoryShift(task);
|
||||||
String expected = String
|
|
||||||
.format(
|
|
||||||
"export %s=\"%s\"%ncd /tmp/foo\n%s -Xms16m -Xmx32m -cp classpath -Dfooble=baz -Dfoo=bar -Dsettingsfile=/tmp/foo/maven/conf/settings.xml -DappHome=/tmp/foo/maven org.jclouds.tools.ant.TestClass %s hello world\n",
|
|
||||||
LAST_ENV.getKey(), LAST_ENV.getValue(), System.getProperty("java.home")
|
|
||||||
+ "/bin/java", LAST_ENV.getKey());
|
|
||||||
assertEquals(task.convertJavaToScriptNormalizingPaths(task.getCommandLine()), expected);
|
|
||||||
assertEquals(task.shiftMap, ImmutableMap.<String, String> of(System.getProperty("user.home")
|
assertEquals(task.shiftMap, ImmutableMap.<String, String> of(System.getProperty("user.home")
|
||||||
+ "/apache-maven-2.2.1", "maven"));
|
+ "/apache-maven-2.2.1", "maven"));
|
||||||
}
|
}
|
||||||
|
@ -160,20 +141,10 @@ public class SSHJavaTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSSHJavaPropertyOverride() {
|
|
||||||
SSHJava task = new SSHJava();
|
|
||||||
Project p = new Project();
|
|
||||||
task.setProject(p);
|
|
||||||
p.setProperty("foo", "bar");
|
|
||||||
task.getProjectProperties().remove("foo");
|
|
||||||
assertEquals(p.getProperty("foo"), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private SSHJava makeSSHJava() {
|
private SSHJava makeSSHJava() {
|
||||||
SSHJava task = new SSHJava();
|
SSHJava task = new SSHJava();
|
||||||
populateTask(task);
|
populateTask(task);
|
||||||
task.setRemotebase(new File("/tmp/foo"));
|
task.setRemotebase(new File("/tmp/foo"));
|
||||||
task.setVerbose(true);
|
|
||||||
task.setTrust(true);
|
task.setTrust(true);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue