diff --git a/tools/antcontrib/samples/javaoverssh/build.xml b/tools/antcontrib/samples/javaoverssh/build.xml index 2b4f6637a3..3cb9fa25ec 100644 --- a/tools/antcontrib/samples/javaoverssh/build.xml +++ b/tools/antcontrib/samples/javaoverssh/build.xml @@ -19,7 +19,7 @@ ==================================================================== --> - + simple example build file @@ -67,17 +67,17 @@ - + - + - + - + diff --git a/tools/antcontrib/src/main/java/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java b/tools/antcontrib/src/main/java/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java deleted file mode 100644 index 2d91ee14b7..0000000000 --- a/tools/antcontrib/src/main/java/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java +++ /dev/null @@ -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 - * setOutput. 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(); - } - } - } -} diff --git a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHExecute.java b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHExecute.java new file mode 100644 index 0000000000..39824c3b05 --- /dev/null +++ b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHExecute.java @@ -0,0 +1,338 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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. + * + *

+ * 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 PumpStreamHandler 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 + * ${user.home}/.ssh/known_hosts. + * + * @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 Process. + * @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"); + } + } + +} diff --git a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJava.java b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJava.java index 9d1e404f2f..4e2f6a3387 100644 --- a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJava.java +++ b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJava.java @@ -25,22 +25,18 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.lang.reflect.Field; import java.security.SecureRandom; -import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.TimeoutException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Location; -import org.apache.tools.ant.MagicNames; import org.apache.tools.ant.Project; -import org.apache.tools.ant.PropertyHelper; import org.apache.tools.ant.Target; import org.apache.tools.ant.Task; 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.Scp; 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.Lists; import com.google.common.collect.Maps; +import com.jcraft.jsch.JSchException; /** * Version of the Java task that executes over ssh. @@ -67,11 +64,9 @@ import com.google.common.collect.Maps; * @author Adrian Cole */ public class SSHJava extends Java { - private final SSHExec exec; + private final SSHExecute exec; private final Scp scp; private final SSHUserInfo userInfo; - - private String jvm = "/usr/bin/java"; private File localDirectory; private File remotebase; private File remotedir; @@ -91,7 +86,8 @@ public class SSHJava extends Java { public SSHJava() { super(); setFork(true); - exec = new SSHExec(); + exec = new SSHExecute(); + exec.setProject(getProject()); scp = new Scp(); userInfo = new SSHUserInfo(); } @@ -107,7 +103,6 @@ public class SSHJava extends Java { @Override public int executeJava() throws BuildException { - checkNotNull(jvm, "jvm must be set"); checkNotNull(remotebase, "remotebase must be set"); if (localDirectory == null) { @@ -124,13 +119,13 @@ public class SSHJava extends Java { if (osFamily == OsFamily.UNIX) { log("removing old contents: " + remotedir.getAbsolutePath(), Project.MSG_VERBOSE); - exec.setCommand(exec("rm -rf " + remotedir.getAbsolutePath()).render(osFamily)); - exec.execute(); + sshexec(exec("rm -rf " + remotedir.getAbsolutePath()).render(osFamily)); } else { // TODO need recursive remove on windows } // 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 { BufferedWriter out = new BufferedWriter(new FileWriter(new File(localDirectory, "init." @@ -162,27 +157,43 @@ public class SSHJava extends Java { } if (osFamily == OsFamily.UNIX) { - exec.setCommand(exec("chmod 755 " + remotedir.getAbsolutePath() + "{fs}init.{sh}").render( - osFamily)); - exec.execute(); + sshexec(exec("chmod 755 " + remotedir.getAbsolutePath() + "{fs}init.{sh}") + .render(osFamily)); } Statement statement = new StatementList(exec("{cd} " + remotedir.getAbsolutePath()), exec(remotedir.getAbsolutePath() + "{fs}init.{sh} init"), exec(remotedir .getAbsolutePath() + "{fs}init.{sh} run")); - getProjectProperties().remove(id); - exec.setResultProperty(id); - exec.setFailonerror(false); - exec.setCommand(statement.render(osFamily)); - exec.setError(errorFile); - exec.setErrorproperty(errorProperty); - exec.setOutput(outputFile); - exec.setOutputproperty(outputProperty); - exec.setAppend(append); + try { + return sshexecRedirectStreams(statement); + } catch (IOException e) { + throw new BuildException(e, getLocation()); + } + } + + private int sshexec(String command) { + 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); - exec.execute(); - return Integer.parseInt(getProject().getProperty(id)); + int rc; + try { + rc = sshexec(statement.render(osFamily)); + } finally { + redirector.complete(); + } + return rc; } private void mkdirAndCopyTo(String destination, Iterable sets) { @@ -190,19 +201,11 @@ public class SSHJava extends Java { log("no content: " + destination, Project.MSG_DEBUG); return; } - exec.setCommand(exec("test -d " + destination).render(osFamily)); // TODO windows - getProjectProperties().remove(id); - exec.setResultProperty(id); - exec.setFailonerror(false); - exec.execute(); - if (getProject().getProperty(id).equals("0")) { + if (sshexec(exec("test -d " + destination).render(osFamily)) == 0) {// TODO windows log("already created: " + destination, Project.MSG_VERBOSE); return; } - getProjectProperties().remove(id); - exec.setCommand(exec("{md} " + destination).render(osFamily)); - exec.setFailonerror(true); - exec.execute(); + sshexec(exec("{md} " + destination).render(osFamily)); scp.init(); String scpDestination = getScpDir(destination); log("staging: " + scpDestination, Project.MSG_VERBOSE); @@ -271,20 +274,21 @@ public class SSHJava extends Java { return in; } - String convertJavaToScriptNormalizingPaths(CommandlineJava commandLine) { + String createInitScript(OsFamily osFamily, String id, String basedir, Environment env, + CommandlineJava commandLine) { Map envVariables = Maps.newHashMap(); String[] environment = env.getVariables(); if (environment != null) { 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("="); envVariables.put(keyValue[0], keyValue[1]); } } - StringBuilder commandBuilder = new StringBuilder(jvm); - if (getCommandLine().getBootclasspath() != null) { + StringBuilder commandBuilder = new StringBuilder(commandLine.getVmCommand().getExecutable()); + if (commandLine.getBootclasspath() != null) { commandBuilder.append(" -Xbootclasspath:bootclasspath"); resetPathToUnderPrefixIfExistsAndIsFileIfNotExistsAddAsIs(commandLine.getBootclasspath(), "bootclasspath", commandBuilder); @@ -314,8 +318,8 @@ public class SSHJava extends Java { Joiner.on(' ').join(commandLine.getJavaCommand().getArguments())); } - InitBuilder testInitBuilder = new InitBuilder(id, remotedir.getAbsolutePath(), remotedir - .getAbsolutePath(), envVariables, commandBuilder.toString()); + InitBuilder testInitBuilder = new InitBuilder(id, basedir, basedir, envVariables, + commandBuilder.toString()); String script = testInitBuilder.build(osFamily); return reprefix(script); } @@ -348,11 +352,6 @@ public class SSHJava extends Java { 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. * @@ -364,15 +363,6 @@ public class SSHJava extends Java { scp.setHost(host); } - /** - * Get the host. - * - * @return the host - */ - public String getHost() { - return exec.getHost(); - } - /** * Username known to remote host. * @@ -459,27 +449,6 @@ public class SSHJava extends Java { 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 * 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); } - /** - * 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 public void setProject(Project project) { super.setProject(project); @@ -538,45 +470,40 @@ public class SSHJava extends Java { @Override public void setOwningTarget(Target target) { super.setOwningTarget(target); - exec.setOwningTarget(target); scp.setOwningTarget(target); } @Override public void setTaskName(String taskName) { super.setTaskName(taskName); - exec.setTaskName(taskName); scp.setTaskName(taskName); } @Override public void setDescription(String description) { super.setDescription(description); - exec.setDescription(description); scp.setDescription(description); } @Override public void setLocation(Location location) { super.setLocation(location); - exec.setLocation(location); scp.setLocation(location); } @Override public void setTaskType(String type) { super.setTaskType(type); - exec.setTaskType(type); scp.setTaskType(type); } @Override public String toString() { return "SSHJava [append=" + append + ", env=" + env + ", errorFile=" + errorFile - + ", errorProperty=" + errorProperty + ", jvm=" + jvm + ", localDirectory=" - + localDirectory + ", osFamily=" + osFamily + ", outputFile=" + outputFile - + ", outputProperty=" + outputProperty + ", remoteDirectory=" + remotebase - + ", userInfo=" + userInfo + "]"; + + ", errorProperty=" + errorProperty + ", localDirectory=" + localDirectory + + ", osFamily=" + osFamily + ", outputFile=" + outputFile + ", outputProperty=" + + outputProperty + ", remoteDirectory=" + remotebase + ", userInfo=" + userInfo + + "]"; } @Override @@ -592,17 +519,4 @@ public class SSHJava extends Java { } } - @SuppressWarnings("unchecked") - Hashtable getProjectProperties() { - PropertyHelper helper = (PropertyHelper) getProject().getReference( - MagicNames.REFID_PROPERTY_HELPER); - Field field; - try { - field = PropertyHelper.class.getDeclaredField("properties"); - field.setAccessible(true); - return (Hashtable) field.get(helper); - } catch (Exception e) { - throw new BuildException(e); - } - } } diff --git a/tools/antcontrib/src/test/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJavaTest.java b/tools/antcontrib/src/test/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJavaTest.java index 26b0a678de..067b3de85d 100644 --- a/tools/antcontrib/src/test/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJavaTest.java +++ b/tools/antcontrib/src/test/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJavaTest.java @@ -47,28 +47,9 @@ public class SSHJavaTest { .entrySet()); // TODO, this test will break in windows - @Test(enabled = false) - 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 { + public void testShift() throws SecurityException, NoSuchMethodException { SSHJava task = makeSSHJava(); 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. of(System.getProperty("user.home") + "/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() { SSHJava task = new SSHJava(); populateTask(task); task.setRemotebase(new File("/tmp/foo")); - task.setVerbose(true); task.setTrust(true); return task; }