mirror of https://github.com/apache/jclouds.git
work to date on ant
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2620 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
947d00ac5e
commit
7f5b800470
|
@ -21,13 +21,22 @@ package org.jclouds.tools.ant.taskdefs.sshjava;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||
|
||||
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 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;
|
||||
|
@ -38,13 +47,19 @@ import org.apache.tools.ant.types.CommandlineJava;
|
|||
import org.apache.tools.ant.types.Environment;
|
||||
import org.apache.tools.ant.types.FileSet;
|
||||
import org.apache.tools.ant.types.Path;
|
||||
import org.apache.tools.ant.types.Environment.Variable;
|
||||
import org.jclouds.scriptbuilder.InitBuilder;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.ShellToken;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Version of the Java task that executes over ssh.
|
||||
|
@ -58,7 +73,8 @@ public class SSHJava extends Java {
|
|||
|
||||
private String jvm = "/usr/bin/java";
|
||||
private File localDirectory;
|
||||
private File remoteDirectory;
|
||||
private File remotebase;
|
||||
private File remotedir;
|
||||
private Environment env = new Environment();
|
||||
|
||||
private OsFamily osFamily = OsFamily.UNIX;
|
||||
|
@ -66,7 +82,11 @@ public class SSHJava extends Java {
|
|||
private String errorProperty;
|
||||
private File outputFile;
|
||||
private String outputProperty;
|
||||
private String id = "javassh" + new SecureRandom().nextLong();
|
||||
|
||||
private boolean append;
|
||||
@VisibleForTesting
|
||||
final Map<String, String> shiftMap = Maps.newHashMap();
|
||||
|
||||
public SSHJava() {
|
||||
super();
|
||||
|
@ -81,49 +101,111 @@ public class SSHJava extends Java {
|
|||
bindToOwner(owner);
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeJava() throws BuildException {
|
||||
checkNotNull(jvm, "jvm must be set");
|
||||
checkNotNull(remoteDirectory, "remotedir must be set");
|
||||
// must copy the files over first as we are changing the system properties based on this.
|
||||
checkNotNull(remotebase, "remotebase must be set");
|
||||
|
||||
if (localDirectory == null) {
|
||||
try {
|
||||
localDirectory = File.createTempFile("sshjava", "dir");
|
||||
localDirectory.delete();
|
||||
localDirectory.mkdirs();
|
||||
} catch (IOException e) {
|
||||
throw new BuildException(e);
|
||||
}
|
||||
}
|
||||
if (remotedir == null)
|
||||
remotedir = new File(remotebase, id);
|
||||
|
||||
if (osFamily == OsFamily.UNIX) {
|
||||
log("removing old contents: " + remotedir.getAbsolutePath(), Project.MSG_VERBOSE);
|
||||
exec.setCommand(exec("rm -rf " + remotedir.getAbsolutePath()).render(osFamily));
|
||||
exec.execute();
|
||||
} 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());
|
||||
|
||||
try {
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(new File(localDirectory, "init."
|
||||
+ ShellToken.SH.to(osFamily))));
|
||||
out.write(command);
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
throw new BuildException(e);
|
||||
}
|
||||
|
||||
if (localDirectory != null) {
|
||||
FileSet cwd = new FileSet();
|
||||
cwd.setDir(localDirectory);
|
||||
mkdirAndCopyTo(remoteDirectory.getAbsolutePath(), ImmutableList.of(cwd));
|
||||
mkdirAndCopyTo(remotedir.getAbsolutePath(), ImmutableList.of(cwd));
|
||||
|
||||
for (Entry<String, String> entry : shiftMap.entrySet()) {
|
||||
FileSet set = new FileSet();
|
||||
set.setDir(new File(entry.getKey()));
|
||||
mkdirAndCopyTo(remotebase.getAbsolutePath() + ShellToken.FS.to(osFamily)
|
||||
+ entry.getValue(), ImmutableList.of(set));
|
||||
}
|
||||
|
||||
if (getCommandLine().getClasspath() != null) {
|
||||
copyPathTo(getCommandLine().getClasspath(), remoteDirectory.getAbsolutePath()
|
||||
+ "/classpath");
|
||||
copyPathTo(getCommandLine().getClasspath(), remotedir.getAbsolutePath() + "/classpath");
|
||||
}
|
||||
|
||||
if (getCommandLine().getBootclasspath() != null) {
|
||||
copyPathTo(getCommandLine().getBootclasspath(), remoteDirectory.getAbsolutePath()
|
||||
copyPathTo(getCommandLine().getBootclasspath(), remotedir.getAbsolutePath()
|
||||
+ "/bootclasspath");
|
||||
}
|
||||
|
||||
String command = convertJavaToScriptNormalizingPaths(getCommandLine());
|
||||
if (osFamily == OsFamily.UNIX) {
|
||||
exec.setCommand(exec("chmod 755 " + remotedir.getAbsolutePath() + "{fs}init.{sh}").render(
|
||||
osFamily));
|
||||
exec.execute();
|
||||
}
|
||||
|
||||
String random = new SecureRandom().nextInt() + "";
|
||||
exec.setResultProperty(random);
|
||||
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(command);
|
||||
exec.setCommand(statement.render(osFamily));
|
||||
exec.setError(errorFile);
|
||||
exec.setErrorproperty(errorProperty);
|
||||
exec.setOutput(outputFile);
|
||||
exec.setOutputproperty(outputProperty);
|
||||
exec.setAppend(append);
|
||||
log("starting java as:\n" + statement.render(osFamily), Project.MSG_VERBOSE);
|
||||
exec.execute();
|
||||
return Integer.parseInt(getProject().getProperty(random));
|
||||
return Integer.parseInt(getProject().getProperty(id));
|
||||
}
|
||||
|
||||
private void mkdirAndCopyTo(String destination, Iterable<FileSet> sets) {
|
||||
scp.init();
|
||||
exec.setCommand(exec("{md} " + destination).render(osFamily));
|
||||
if (Iterables.size(sets) == 0) {
|
||||
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")) {
|
||||
log("already created: " + destination, Project.MSG_VERBOSE);
|
||||
return;
|
||||
}
|
||||
getProjectProperties().remove(id);
|
||||
exec.setCommand(exec("{md} " + destination).render(osFamily));
|
||||
exec.setFailonerror(true);
|
||||
exec.execute();
|
||||
scp.init();
|
||||
String scpDestination = getScpDir(destination);
|
||||
System.out.println("Sending to: " + scpDestination);
|
||||
log("staging: " + scpDestination, Project.MSG_VERBOSE);
|
||||
for (FileSet set : sets)
|
||||
scp.addFileset(set);
|
||||
scp.setTodir(scpDestination);
|
||||
|
@ -143,16 +225,17 @@ public class SSHJava extends Java {
|
|||
String[] paths = path.list();
|
||||
if (paths != null && paths.length > 0) {
|
||||
for (int i = 0; i < paths.length; i++) {
|
||||
File file = new File(paths[i]);
|
||||
if (file.exists()) {
|
||||
// directories are flattened under the prefix anyway, so there's no need to add them
|
||||
// to the path
|
||||
if (file.isFile())
|
||||
destination.append("{ps}").append(file.getName());
|
||||
log("converting: " + paths[i], Project.MSG_DEBUG);
|
||||
File file = new File(reprefix(paths[i]));
|
||||
if (file.getAbsolutePath().equals(paths[i]) && file.exists() && file.isFile()) {
|
||||
String newPath = prefix + "{fs}" + file.getName();
|
||||
log("adding new: " + newPath, Project.MSG_DEBUG);
|
||||
destination.append("{ps}").append(prefix + "{fs}" + file.getName());
|
||||
} else {
|
||||
// if the file doesn't exist, it is probably a "forward reference" to something that
|
||||
// is already on the remote machine
|
||||
destination.append("{ps}").append(file.getAbsolutePath());
|
||||
log("adding existing: " + file.getAbsolutePath(), Project.MSG_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,6 +245,8 @@ public class SSHJava extends Java {
|
|||
List<FileSet> filesets = Lists.newArrayList();
|
||||
if (path.list() != null && path.list().length > 0) {
|
||||
for (String filepath : path.list()) {
|
||||
if (!filepath.equals(reprefix(filepath)))
|
||||
continue;// we've already copied
|
||||
File file = new File(filepath);
|
||||
if (file.exists()) {
|
||||
FileSet fileset = new FileSet();
|
||||
|
@ -177,17 +262,27 @@ public class SSHJava extends Java {
|
|||
mkdirAndCopyTo(destination, filesets);
|
||||
}
|
||||
|
||||
String reprefix(String in) {
|
||||
for (Entry<String, String> entry : shiftMap.entrySet()) {
|
||||
if (in.startsWith(entry.getKey()))
|
||||
in = remotebase + ShellToken.FS.to(osFamily) + entry.getValue()
|
||||
+ in.substring(entry.getKey().length());
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
String convertJavaToScriptNormalizingPaths(CommandlineJava commandLine) {
|
||||
List<Statement> statements = Lists.newArrayList();
|
||||
|
||||
Map<String, String> 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);
|
||||
String[] keyValue = environment[i].split("=");
|
||||
statements.add(exec(String.format("{export} %s={vq}%s{vq}", keyValue[0], keyValue[1])));
|
||||
envVariables.put(keyValue[0], keyValue[1]);
|
||||
}
|
||||
}
|
||||
statements.add(exec("{cd} " + remoteDirectory));
|
||||
|
||||
StringBuilder commandBuilder = new StringBuilder(jvm);
|
||||
if (getCommandLine().getBootclasspath() != null) {
|
||||
commandBuilder.append(" -Xbootclasspath:bootclasspath");
|
||||
|
@ -218,10 +313,11 @@ public class SSHJava extends Java {
|
|||
commandBuilder.append(" ").append(
|
||||
Joiner.on(' ').join(commandLine.getJavaCommand().getArguments()));
|
||||
}
|
||||
statements.add(exec(commandBuilder.toString()));
|
||||
|
||||
String command = new StatementList(statements).render(osFamily);
|
||||
return command;
|
||||
InitBuilder testInitBuilder = new InitBuilder(id, remotedir.getAbsolutePath(), remotedir
|
||||
.getAbsolutePath(), envVariables, commandBuilder.toString());
|
||||
String script = testInitBuilder.build(osFamily);
|
||||
return reprefix(script);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -238,8 +334,12 @@ public class SSHJava extends Java {
|
|||
this.localDirectory = checkNotNull(localDir, "dir");
|
||||
}
|
||||
|
||||
public void setRemotedir(File remotedir) {
|
||||
this.remoteDirectory = checkNotNull(remotedir, "remotedir");
|
||||
/**
|
||||
* All files transfered to the host will be relative to this. The java process itself will be at
|
||||
* this path/{@code id}.
|
||||
*/
|
||||
public void setRemotebase(File remotebase) {
|
||||
this.remotebase = checkNotNull(remotebase, "remotebase");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -469,4 +569,40 @@ public class SSHJava extends Java {
|
|||
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 + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSysproperty(Variable sysp) {
|
||||
if (sysp.getKey().startsWith("sshjava.map.")) {
|
||||
shiftMap.put(sysp.getKey().replaceFirst("sshjava.map.", ""), sysp.getValue());
|
||||
} else if (sysp.getKey().equals("sshjava.id")) {
|
||||
setId(sysp.getValue());
|
||||
} else if (sysp.getKey().equals("sshjava.remotebase")) {
|
||||
setRemotebase(new File(sysp.getValue()));
|
||||
} else {
|
||||
super.addSysproperty(sysp);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.tools.ant.types.Environment.Variable;
|
|||
import org.jclouds.tools.ant.TestClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
|
@ -46,6 +47,7 @@ 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
|
||||
|
@ -56,6 +58,21 @@ public class SSHJavaTest {
|
|||
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();
|
||||
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")
|
||||
+ "/apache-maven-2.2.1", "maven"));
|
||||
}
|
||||
|
||||
private Java populateTask(Java task) {
|
||||
Project p = new Project();
|
||||
task.setProject(p);
|
||||
|
@ -64,7 +81,6 @@ public class SSHJavaTest {
|
|||
Variable prop1 = new Environment.Variable();
|
||||
prop1.setKey("fooble");
|
||||
prop1.setValue("baz");
|
||||
|
||||
task.addSysproperty(prop1);
|
||||
Variable prop2 = new Environment.Variable();
|
||||
prop2.setKey("foo");
|
||||
|
@ -105,6 +121,25 @@ public class SSHJavaTest {
|
|||
.getProperty("result"));
|
||||
}
|
||||
|
||||
@Test(enabled = false, groups = { "live" })
|
||||
public void testSshShift() throws NumberFormatException, FileNotFoundException, IOException {
|
||||
Java java = makeJava();
|
||||
directoryShift(java);
|
||||
java.execute();
|
||||
|
||||
SSHJava javaOverSsh = makeSSHJava();
|
||||
addDestinationTo(javaOverSsh);
|
||||
directoryShift(javaOverSsh);
|
||||
javaOverSsh.execute();
|
||||
|
||||
assertEquals(javaOverSsh.getProject().getProperty("out"), javaOverSsh.getProject()
|
||||
.getProperty("out"));
|
||||
assertEquals(javaOverSsh.getProject().getProperty("err"), javaOverSsh.getProject()
|
||||
.getProperty("err"));
|
||||
assertEquals(javaOverSsh.getProject().getProperty("result"), javaOverSsh.getProject()
|
||||
.getProperty("result"));
|
||||
}
|
||||
|
||||
private void addDestinationTo(SSHJava javaOverSsh) throws UnknownHostException {
|
||||
String sshHost = System.getProperty("jclouds.test.ssh.host");
|
||||
String sshPort = System.getProperty("jclouds.test.ssh.port");
|
||||
|
@ -125,10 +160,19 @@ 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.setRemotedir(new File("/tmp/foo"));
|
||||
task.setRemotebase(new File("/tmp/foo"));
|
||||
task.setVerbose(true);
|
||||
task.setTrust(true);
|
||||
return task;
|
||||
|
@ -137,4 +181,20 @@ public class SSHJavaTest {
|
|||
private Java makeJava() {
|
||||
return populateTask(new Java());
|
||||
}
|
||||
|
||||
private <T extends Java> T directoryShift(T java) {
|
||||
Variable prop1 = new Environment.Variable();
|
||||
prop1.setKey("sshjava.map." + System.getProperty("user.home") + "/apache-maven-2.2.1");
|
||||
prop1.setValue("maven");
|
||||
java.addSysproperty(prop1);
|
||||
Variable prop2 = new Environment.Variable();
|
||||
prop2.setKey("settingsfile");
|
||||
prop2.setValue(System.getProperty("user.home") + "/apache-maven-2.2.1/conf/settings.xml");
|
||||
java.addSysproperty(prop2);
|
||||
Variable prop3 = new Environment.Variable();
|
||||
prop3.setKey("appHome");
|
||||
prop3.setValue(System.getProperty("user.home") + "/apache-maven-2.2.1");
|
||||
java.addSysproperty(prop3);
|
||||
return java;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue