mirror of https://github.com/apache/jclouds.git
Issue 1112:Move antcontrib to new jclouds-ant repository
This commit is contained in:
parent
69a8304617
commit
7a1e902c15
|
@ -1,91 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. jclouds 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.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.jclouds</groupId>
|
|
||||||
<artifactId>jclouds-project</artifactId>
|
|
||||||
<version>1.5.5-SNAPSHOT</version>
|
|
||||||
<relativePath>../project/pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
<artifactId>jclouds-antcontrib</artifactId>
|
|
||||||
<name>Ant-Contrib extensions</name>
|
|
||||||
<properties>
|
|
||||||
<jclouds.test.listener />
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>${project.groupId}</groupId>
|
|
||||||
<artifactId>jclouds-scriptbuilder</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>${project.groupId}</groupId>
|
|
||||||
<artifactId>jclouds-compute</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.ant</groupId>
|
|
||||||
<artifactId>ant</artifactId>
|
|
||||||
<version>1.7.1</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.ant</groupId>
|
|
||||||
<artifactId>ant-jsch</artifactId>
|
|
||||||
<version>1.7.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jclouds.driver</groupId>
|
|
||||||
<artifactId>jclouds-jsch</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.jcraft</groupId>
|
|
||||||
<artifactId>jsch</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<finalName>${project.artifactId}</finalName>
|
|
||||||
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>single</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<descriptorRefs>
|
|
||||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
|
||||||
</descriptorRefs>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,183 +0,0 @@
|
||||||
<!--
|
|
||||||
|
|
||||||
Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. jclouds 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.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project name="compute" default="dump" basedir="." xmlns:artifact="urn:maven-artifact-ant">
|
|
||||||
<property file="build.properties" />
|
|
||||||
<property name="jclouds.version" value="1.0-beta-9a" />
|
|
||||||
<property name="privatekeyfile" value="${user.home}/.ssh/id_rsa" />
|
|
||||||
<property name="publickeyfile" value="${user.home}/.ssh/id_rsa.pub" />
|
|
||||||
|
|
||||||
<mkdir dir="build" />
|
|
||||||
|
|
||||||
<get src="http://opensource.become.com/apache//maven/binaries/maven-ant-tasks-2.1.1.jar" dest="build/maven-ant-tasks.jar"/>
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Which provider would you like to use (aws-ec2, bluelock-vcdirector, cloudservers-uk, cloudservers-us, cloudsigma-zrh, eucalyptus-partnercloud-ec2, elastichosts-lon-b, elastichosts-lon-p, elastichosts-sat-p, gogrid, openhosting-east1, serverlove-z1-man, skalicloud-sdg-my, slicehost, trmk-ecloud, trmk-vcloudexpress)?"
|
|
||||||
validargs="aws-ec2,bluelock-vcdirector,cloudservers-uk,cloudservers-us,cloudsigma-zrh,eucalyptus-partnercloud-ec2,elastichosts-lon-b,elastichosts-lon-p,elastichosts-sat-p,gogrid,openhosting-east1,serverlove-z1-man,skalicloud-sdg-my,slicehost,trmk-ecloud,trmk-vcloudexpress"
|
|
||||||
addproperty="provider"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<path id="maven-ant-tasks.classpath" path="build/maven-ant-tasks.jar" />
|
|
||||||
<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
|
|
||||||
|
|
||||||
<artifact:localRepository id="local.repository" path="${user.home}/.m2/repository" />
|
|
||||||
<artifact:remoteRepository id="jclouds-snapshot.repository" url="https://oss.sonatype.org/content/repositories/snapshots" />
|
|
||||||
|
|
||||||
<artifact:dependencies pathId="jclouds.classpath">
|
|
||||||
<dependency groupId="org.jclouds" artifactId="jclouds-antcontrib" version="${jclouds.version}" />
|
|
||||||
<dependency groupId="org.jclouds.provider" artifactId="${provider}" version="${jclouds.version}" />
|
|
||||||
<localRepository refid="local.repository" />
|
|
||||||
<remoteRepository refid="jclouds-snapshot.repository" />
|
|
||||||
</artifact:dependencies>
|
|
||||||
|
|
||||||
<typedef name="compute" classname="org.jclouds.tools.ant.taskdefs.compute.ComputeTask" classpathref="jclouds.classpath" />
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="What is your identity on ${provider}?"
|
|
||||||
addproperty="identity"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="What is the credential for ${identity}?"
|
|
||||||
addproperty="credential"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<property name="jclouds.compute.url" value="compute://${identity}:${credential}@${provider}" />
|
|
||||||
|
|
||||||
<target name="list" description="list the identity of all nodes">
|
|
||||||
<compute actions="list" provider="${jclouds.compute.url}" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="list-details" description="list the details of all nodes">
|
|
||||||
<compute actions="list-details" provider="${jclouds.compute.url}" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="list-images" description="list the images supported">
|
|
||||||
<compute actions="list-images" provider="${jclouds.compute.url}" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="list-hardwares" description="list the hardwares supported">
|
|
||||||
<compute actions="list-sizes" provider="${jclouds.compute.url}" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="list-locations" description="list the locations supported">
|
|
||||||
<compute actions="list-locations" provider="${jclouds.compute.url}" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="dump" description="list all information we can obtain about the cloud">
|
|
||||||
<compute actions="list-locations,list-sizes,list-images,list-details" provider="${jclouds.compute.url}" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="reboot" depends="reboot-id,reboot-group" />
|
|
||||||
|
|
||||||
<target name="reboot-id" description="reboot the node ${id}" unless="group">
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Which node do you wish to reboot"
|
|
||||||
addproperty="id"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<compute actions="reboot" provider="${jclouds.compute.url}">
|
|
||||||
<nodes id="${id}" />
|
|
||||||
</compute>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="reboot-group" description="reboot the nodes with group ${group}" unless="id" >
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Which group do you wish to reboot"
|
|
||||||
addproperty="group"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<compute actions="reboot" provider="${jclouds.compute.url}">
|
|
||||||
<nodes group="${group}" />
|
|
||||||
</compute>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="destroy" depends="destroy-id,destroy-group" />
|
|
||||||
|
|
||||||
<target name="destroy-id" description="destroy the node ${id}" unless="group">
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Which node do you wish to destroy"
|
|
||||||
addproperty="id"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<compute actions="destroy" provider="${jclouds.compute.url}">
|
|
||||||
<nodes id="${id}" />
|
|
||||||
</compute>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="destroy-group" description="destroy the nodes with group ${group}" unless="id" >
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Which group do you wish to destroy"
|
|
||||||
addproperty="group"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<compute actions="destroy" provider="${jclouds.compute.url}">
|
|
||||||
<nodes group="${group}" />
|
|
||||||
</compute>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="get" depends="get-group,get-id" />
|
|
||||||
|
|
||||||
<target name="get-id" description="get the node ${id}" unless="group">
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Which node do you wish to get"
|
|
||||||
addproperty="id"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<compute actions="get" provider="${jclouds.compute.url}">
|
|
||||||
<nodes id="${id}" />
|
|
||||||
</compute>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="get-group" description="get the nodes with group ${group}" unless="id" >
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Which group do you wish to get"
|
|
||||||
addproperty="group"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<compute actions="get" provider="${jclouds.compute.url}">
|
|
||||||
<nodes group="${group}" />
|
|
||||||
</compute>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<property name="location" value="" />
|
|
||||||
<target name="create" description="create the node ${group}">
|
|
||||||
<property name="privatekeyfile" value="${user.home}/.ssh/id_rsa" />
|
|
||||||
<property name="publickeyfile" value="${user.home}/.ssh/id_rsa.pub" />
|
|
||||||
<property name="os" value="UBUNTU" />
|
|
||||||
<property name="count" value="1" />
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="What do you want to group your nodes with?"
|
|
||||||
addproperty="group"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<compute actions="create" provider="${jclouds.compute.url}">
|
|
||||||
<nodes privatekeyfile="${privatekeyfile}" publickeyfile="${publickeyfile}" group="${group}" count="${count}" os="${os}" hardware="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
|
|
||||||
</compute>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,26 +0,0 @@
|
||||||
====
|
|
||||||
Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. jclouds 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.
|
|
||||||
====
|
|
||||||
|
|
||||||
this is a simple ant script that executes a java command on a remote machine via ssh
|
|
||||||
1. find or download a copy of jclouds-antcontrib-1.0-SNAPSHOT-jar-with-dependencies.jar
|
|
||||||
- ex. ~/.m2/repository/org/jclouds/jclouds-antcontrib/1.0-SNAPSHOT/jclouds-antcontrib-1.0-SNAPSHOT-jar-with-dependencies.jar
|
|
||||||
- ex. curl http://jclouds.rimuhosting.com/maven2/snapshots/org/jclouds/jclouds-antcontrib/1.0-SNAPSHOT/jclouds-antcontrib-1.0-20091215.023231-1-jar-with-dependencies.jar >jclouds-antcontrib-all.jar
|
|
||||||
2. invoke ant, adding the library above, and passing the properties 'host' 'username' 'keyfile' which corresponds to your remote credentials
|
|
||||||
- ex. ant -lib ~/.m2/repository/org/jclouds/jclouds-antcontrib/1.0-SNAPSHOT/jclouds-antcontrib-1.0-SNAPSHOT-jar-with-dependencies.jar -Dhost=67.202.42.237 -Dusername=root -Dkeyfile=$HOME/.ssh/id_dsa
|
|
||||||
- ex. ant -lib ~/.m2/repository/org/jclouds/jclouds-antcontrib/1.0-SNAPSHOT/jclouds-antcontrib-1.0-SNAPSHOT-jar-with-dependencies.jar -Dhost=localhost -Dusername=$USER -Dkeyfile=$HOME/.ssh/id_dsa
|
|
|
@ -1,83 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. jclouds 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.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project name="sshjava" default="sshjava" basedir=".">
|
|
||||||
<description>
|
|
||||||
simple example build file
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<!-- set global properties for this build -->
|
|
||||||
<property name="src" location="src"/>
|
|
||||||
<property name="build" location="build"/>
|
|
||||||
<property name="dist" location="dist"/>
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Please enter the ip or hostname of the ssh machine"
|
|
||||||
addproperty="host"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Please enter the user you will connect as"
|
|
||||||
addproperty="username"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Please enter the path to the dsa key"
|
|
||||||
addproperty="keyfile"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input
|
|
||||||
message="Please enter the strings you'd like to test"
|
|
||||||
addproperty="line"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<target name="init">
|
|
||||||
<!-- Create the time stamp -->
|
|
||||||
<tstamp/>
|
|
||||||
<!-- Create the build directory structure used by compile -->
|
|
||||||
<mkdir dir="${build}"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="compile" depends="init" description="compile the source ">
|
|
||||||
<!-- Compile the java code from ${src} into ${build} -->
|
|
||||||
<javac srcdir="${src}" destdir="${build}"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="clean" description="clean up">
|
|
||||||
<!-- Delete the ${build} and ${dist} directory trees -->
|
|
||||||
<delete dir="${build}"/>
|
|
||||||
<delete dir="${dist}"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<taskdef name="sshjava" classname="org.jclouds.tools.ant.taskdefs.sshjava.SSHJava" />
|
|
||||||
|
|
||||||
<target name="sshjava" depends="compile" description="remote execute the java command">
|
|
||||||
<echo message="normal java task"/>
|
|
||||||
<java classname="TestClass" classpath="${build}" dir="${user.dir}" >
|
|
||||||
<arg line="${line}"/>
|
|
||||||
</java>
|
|
||||||
<echo message="java task over ssh"/>
|
|
||||||
<sshjava classname="TestClass" classpath="${build}" dir="${user.dir}" host="${host}" username="${username}" keyfile="${keyfile}" trust="true" remotebase="/tmp/test" >
|
|
||||||
<arg line="${line}"/>
|
|
||||||
</sshjava>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,34 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.
|
|
||||||
*/
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class TestClass {
|
|
||||||
public static void main(String... args) {
|
|
||||||
File cwd = new File(System.getProperty("user.dir"));
|
|
||||||
System.out.println("children:");
|
|
||||||
for (File child : cwd.listFiles())
|
|
||||||
System.out.println(" " + child);
|
|
||||||
System.out.println("what you wrote:");
|
|
||||||
System.out.println(Arrays.asList(args));
|
|
||||||
System.err.println("this is the error stream");
|
|
||||||
System.out.println("will exit 3:");
|
|
||||||
System.exit(3);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,119 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.jclouds.tools.ant.logging;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.tools.ant.Project;
|
|
||||||
import org.jclouds.logging.BaseLogger;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link org.apache.tools.ant.Project} implementation of {@link Logger}.
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AntLogger extends BaseLogger {
|
|
||||||
private final Project project;
|
|
||||||
private final String category;
|
|
||||||
private boolean alwaysLog;
|
|
||||||
|
|
||||||
public static class AntLoggerFactory implements LoggerFactory {
|
|
||||||
private final Project project;
|
|
||||||
private final Set<String> upgrades;
|
|
||||||
|
|
||||||
public AntLoggerFactory(Project project, String... upgrades) {
|
|
||||||
this.project = checkNotNull(project, "project");
|
|
||||||
this.upgrades = Sets.newHashSet(upgrades);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Logger getLogger(String category) {
|
|
||||||
return new AntLogger(project, category, upgrades.contains(category));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AntLogger(Project project, String category, boolean alwaysLog) {
|
|
||||||
this.project = checkNotNull(project, "project");
|
|
||||||
this.category = category;
|
|
||||||
this.alwaysLog = alwaysLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logTrace(String message) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTraceEnabled() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logDebug(String message) {
|
|
||||||
project.log(" " + message, alwaysLog ? Project.MSG_INFO : Project.MSG_DEBUG);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDebugEnabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logInfo(String message) {
|
|
||||||
project.log(" " + message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInfoEnabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logWarn(String message) {
|
|
||||||
project.log(" " + message, Project.MSG_WARN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logWarn(String message, Throwable e) {
|
|
||||||
project.log(" " + message, e, Project.MSG_WARN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isWarnEnabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logError(String message) {
|
|
||||||
project.log(" " + message, Project.MSG_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logError(String message, Throwable e) {
|
|
||||||
project.log(" " + message, e, Project.MSG_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isErrorEnabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCategory() {
|
|
||||||
return category;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.jclouds.tools.ant.logging.config;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import org.apache.tools.ant.Project;
|
|
||||||
import org.jclouds.logging.Logger.LoggerFactory;
|
|
||||||
import org.jclouds.logging.config.LoggingModule;
|
|
||||||
import org.jclouds.tools.ant.logging.AntLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures logging of type {@link AntLogger}
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AntLoggingModule extends LoggingModule {
|
|
||||||
|
|
||||||
private final Project project;
|
|
||||||
private final String[] upgrades;
|
|
||||||
|
|
||||||
public AntLoggingModule(Project project, String ... upgrades) {
|
|
||||||
this.project = project;
|
|
||||||
this.upgrades = upgrades;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoggerFactory createLoggerFactory() {
|
|
||||||
return new AntLogger.AntLoggerFactory(checkNotNull(project, "project"), upgrades);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,298 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.jclouds.tools.ant.taskdefs.compute;
|
|
||||||
|
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
|
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
|
||||||
import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.buildComputeMap;
|
|
||||||
import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.createTemplateFromElement;
|
|
||||||
import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.ipOrEmptyString;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
import org.apache.tools.ant.BuildException;
|
|
||||||
import org.apache.tools.ant.Project;
|
|
||||||
import org.apache.tools.ant.Task;
|
|
||||||
import org.jclouds.compute.ComputeService;
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
|
||||||
import org.jclouds.compute.RunNodesException;
|
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
|
||||||
import org.jclouds.compute.domain.Image;
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
|
||||||
import org.jclouds.compute.domain.Template;
|
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
|
||||||
import org.jclouds.domain.Location;
|
|
||||||
import org.jclouds.http.HttpUtils;
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
import org.jclouds.util.CredentialUtils;
|
|
||||||
|
|
||||||
import com.google.common.base.CaseFormat;
|
|
||||||
import com.google.common.base.Splitter;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Adrian Cole
|
|
||||||
* @author Ivan Meredith
|
|
||||||
*/
|
|
||||||
public class ComputeTask extends Task {
|
|
||||||
|
|
||||||
private final LoadingCache<URI, ComputeServiceContext> computeMap;
|
|
||||||
private String provider;
|
|
||||||
private String actions;
|
|
||||||
private NodeElement nodeElement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* we don't have a reference to the project during the constructor, so we need to defer expansion
|
|
||||||
* with a Provider.
|
|
||||||
*/
|
|
||||||
private final Provider<Project> projectProvider = new Provider<Project>() {
|
|
||||||
@Override
|
|
||||||
public Project get() {
|
|
||||||
return getProject();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public ComputeTask(@Nullable LoadingCache<URI, ComputeServiceContext> computeMap) {
|
|
||||||
this.computeMap = computeMap != null ? computeMap : buildComputeMap(projectProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComputeTask() throws IOException {
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum Action {
|
|
||||||
CREATE, GET, LIST, LIST_DETAILS, DESTROY, REBOOT, LIST_IMAGES, LIST_SIZES, LIST_LOCATIONS
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* makes a connection to the compute service and invokes
|
|
||||||
*/
|
|
||||||
public void execute() throws BuildException {
|
|
||||||
ComputeServiceContext context = computeMap.getUnchecked(HttpUtils.createUri(provider));
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (String action : Splitter.on(',').split(actions)) {
|
|
||||||
Action act = Action.valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, action));
|
|
||||||
try {
|
|
||||||
invokeActionOnService(act, context.getComputeService());
|
|
||||||
} catch (RunNodesException e) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new BuildException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
context.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void invokeActionOnService(Action action, ComputeService computeService) throws RunNodesException, IOException {
|
|
||||||
switch (action) {
|
|
||||||
case CREATE:
|
|
||||||
case GET:
|
|
||||||
case DESTROY:
|
|
||||||
case REBOOT:
|
|
||||||
if (nodeElement != null) {
|
|
||||||
switch (action) {
|
|
||||||
case CREATE:
|
|
||||||
create(computeService);
|
|
||||||
break;
|
|
||||||
case GET:
|
|
||||||
get(computeService);
|
|
||||||
break;
|
|
||||||
case DESTROY:
|
|
||||||
destroy(computeService);
|
|
||||||
break;
|
|
||||||
case REBOOT:
|
|
||||||
reboot(computeService);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.log("missing node element for action: " + action, Project.MSG_ERR);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LIST:
|
|
||||||
list(computeService);
|
|
||||||
break;
|
|
||||||
case LIST_DETAILS:
|
|
||||||
listDetails(computeService);
|
|
||||||
break;
|
|
||||||
case LIST_IMAGES:
|
|
||||||
listImages(computeService);
|
|
||||||
break;
|
|
||||||
case LIST_SIZES:
|
|
||||||
listHardwares(computeService);
|
|
||||||
break;
|
|
||||||
case LIST_LOCATIONS:
|
|
||||||
listLocations(computeService);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.log("bad action: " + action, Project.MSG_ERR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listDetails(ComputeService computeService) {
|
|
||||||
log("list details");
|
|
||||||
for (ComputeMetadata node : computeService.listNodes()) {// TODO
|
|
||||||
// parallel
|
|
||||||
logDetails(computeService, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listImages(ComputeService computeService) {
|
|
||||||
log("list images");
|
|
||||||
for (Image image : computeService.listImages()) {// TODO
|
|
||||||
log(String.format(" image location=%s, id=%s, name=%s, version=%s, osArch=%s, osfam=%s, osdesc=%s, desc=%s",
|
|
||||||
image.getLocation(), image.getProviderId(), image.getName(), image.getVersion(), image
|
|
||||||
.getOperatingSystem().getArch(), image.getOperatingSystem().getFamily(), image
|
|
||||||
.getOperatingSystem().getDescription(), image.getDescription()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listHardwares(ComputeService computeService) {
|
|
||||||
log("list hardwares");
|
|
||||||
for (Hardware hardware : computeService.listHardwareProfiles()) {// TODO
|
|
||||||
log(String.format(" hardware id=%s, cores=%s, ram=%s, volumes=%s", hardware.getProviderId(), getCores(hardware), hardware
|
|
||||||
.getRam(), hardware.getVolumes()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listLocations(ComputeService computeService) {
|
|
||||||
log("list locations");
|
|
||||||
for (Location location : computeService.listAssignableLocations()) {// TODO
|
|
||||||
log(String.format(" location id=%s, scope=%s, description=%s, parent=%s", location.getId(), location
|
|
||||||
.getScope(), location.getDescription(), location.getParent()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void list(ComputeService computeService) {
|
|
||||||
log("list");
|
|
||||||
for (ComputeMetadata node : computeService.listNodes()) {
|
|
||||||
log(String.format(" location=%s, id=%s, group=%s", node.getLocation(), node.getProviderId(), node.getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void create(ComputeService computeService) throws RunNodesException, IOException {
|
|
||||||
String group = nodeElement.getGroup();
|
|
||||||
|
|
||||||
log(String.format("create group: %s, count: %d, hardware: %s, os: %s", group, nodeElement.getCount(), nodeElement
|
|
||||||
.getHardware(), nodeElement.getOs()));
|
|
||||||
|
|
||||||
Template template = createTemplateFromElement(nodeElement, computeService);
|
|
||||||
|
|
||||||
for (NodeMetadata createdNode : computeService.createNodesInGroup(group, nodeElement.getCount(), template)) {
|
|
||||||
logDetails(computeService, createdNode);
|
|
||||||
addNodeDetailsAsProjectProperties(createdNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addNodeDetailsAsProjectProperties(NodeMetadata createdNode) {
|
|
||||||
if (nodeElement.getIdproperty() != null)
|
|
||||||
getProject().setProperty(nodeElement.getIdproperty(), createdNode.getProviderId());
|
|
||||||
if (nodeElement.getHostproperty() != null)
|
|
||||||
getProject().setProperty(nodeElement.getHostproperty(), ipOrEmptyString(createdNode.getPublicAddresses()));
|
|
||||||
if (nodeElement.getPasswordproperty() != null && !CredentialUtils.isPrivateKeyCredential(createdNode.getCredentials()))
|
|
||||||
getProject().setProperty(nodeElement.getPasswordproperty(), createdNode.getCredentials().credential);
|
|
||||||
if (nodeElement.getUsernameproperty() != null)
|
|
||||||
getProject().setProperty(nodeElement.getUsernameproperty(), createdNode.getCredentials().identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reboot(ComputeService computeService) {
|
|
||||||
if (nodeElement.getId() != null) {
|
|
||||||
log(String.format("reboot id: %s", nodeElement.getId()));
|
|
||||||
computeService.rebootNode(nodeElement.getId());
|
|
||||||
} else {
|
|
||||||
log(String.format("reboot group: %s", nodeElement.getGroup()));
|
|
||||||
computeService.rebootNodesMatching(NodePredicates.inGroup(nodeElement.getGroup()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void destroy(ComputeService computeService) {
|
|
||||||
if (nodeElement.getId() != null) {
|
|
||||||
log(String.format("destroy id: %s", nodeElement.getId()));
|
|
||||||
computeService.destroyNode(nodeElement.getId());
|
|
||||||
} else {
|
|
||||||
log(String.format("destroy group: %s", nodeElement.getGroup()));
|
|
||||||
computeService.destroyNodesMatching(NodePredicates.inGroup(nodeElement.getGroup()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void get(ComputeService computeService) {
|
|
||||||
if (nodeElement.getId() != null) {
|
|
||||||
log(String.format("get id: %s", nodeElement.getId()));
|
|
||||||
logDetails(computeService, computeService.getNodeMetadata(nodeElement.getId()));
|
|
||||||
} else {
|
|
||||||
log(String.format("get group: %s", nodeElement.getGroup()));
|
|
||||||
for (ComputeMetadata node : Iterables.filter(computeService.listNodesDetailsMatching(NodePredicates.all()),
|
|
||||||
NodePredicates.inGroup(nodeElement.getGroup()))) {
|
|
||||||
logDetails(computeService, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void logDetails(ComputeService computeService, ComputeMetadata node) {
|
|
||||||
NodeMetadata metadata = node instanceof NodeMetadata ? NodeMetadata.class.cast(node) : computeService
|
|
||||||
.getNodeMetadata(node.getId());
|
|
||||||
log(String.format(" node id=%s, name=%s, group=%s, location=%s, state=%s, publicIp=%s, privateIp=%s, hardware=%s",
|
|
||||||
metadata.getProviderId(), metadata.getName(), metadata.getGroup(), metadata.getLocation(), formatStatus(metadata), ComputeTaskUtils.ipOrEmptyString(metadata.getPublicAddresses()),
|
|
||||||
ipOrEmptyString(metadata.getPrivateAddresses()), metadata.getHardware()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the configured {@link NodeElement} element
|
|
||||||
*/
|
|
||||||
public final NodeElement createNodes() {
|
|
||||||
if (getNodes() == null) {
|
|
||||||
this.nodeElement = new NodeElement();
|
|
||||||
}
|
|
||||||
return this.nodeElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeElement getNodes() {
|
|
||||||
return this.nodeElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getActions() {
|
|
||||||
return actions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActions(String actions) {
|
|
||||||
this.actions = actions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeElement getNodeElement() {
|
|
||||||
return nodeElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNodeElement(NodeElement nodeElement) {
|
|
||||||
this.nodeElement = nodeElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProvider(String provider) {
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProvider() {
|
|
||||||
return provider;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,166 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.jclouds.tools.ant.taskdefs.compute;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.tools.ant.BuildException;
|
|
||||||
import org.apache.tools.ant.Project;
|
|
||||||
import org.jclouds.ContextBuilder;
|
|
||||||
import org.jclouds.compute.ComputeService;
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
|
||||||
import org.jclouds.compute.domain.Template;
|
|
||||||
import org.jclouds.compute.domain.TemplateBuilder;
|
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.scriptbuilder.domain.Statements;
|
|
||||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
|
||||||
import org.jclouds.tools.ant.logging.config.AntLoggingModule;
|
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.google.common.base.Splitter;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import com.google.inject.Module;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
public class ComputeTaskUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Creates a Map that associates a uri with a live connection to the compute provider. This is
|
|
||||||
* done on-demand.
|
|
||||||
*
|
|
||||||
* @param projectProvider
|
|
||||||
* allows access to the ant project to retrieve default properties needed for compute
|
|
||||||
* providers.
|
|
||||||
*/
|
|
||||||
static LoadingCache<URI, ComputeServiceContext> buildComputeMap(final Provider<Project> projectProvider) {
|
|
||||||
return CacheBuilder.newBuilder().build(new CacheLoader<URI, ComputeServiceContext>() {
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public ComputeServiceContext load(URI from) {
|
|
||||||
Properties props = new Properties();
|
|
||||||
props.putAll(projectProvider.get().getProperties());
|
|
||||||
Set<Module> modules = ImmutableSet.<Module> of(new AntLoggingModule(projectProvider.get(),
|
|
||||||
ComputeServiceConstants.COMPUTE_LOGGER), new JschSshClientModule());
|
|
||||||
// adding the properties to the factory will allow us to pass
|
|
||||||
// alternate endpoints
|
|
||||||
String provider = from.getHost();
|
|
||||||
Credentials creds = Credentials.parse(from);
|
|
||||||
return ContextBuilder.newBuilder(provider)
|
|
||||||
.credentials(creds.identity, creds.credential)
|
|
||||||
.modules(modules)
|
|
||||||
.overrides(props).buildView(ComputeServiceContext.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static Template createTemplateFromElement(NodeElement nodeElement, ComputeService computeService) throws IOException {
|
|
||||||
TemplateBuilder templateBuilder = computeService.templateBuilder();
|
|
||||||
if (nodeElement.getLocation() != null && !"".equals(nodeElement.getLocation()))
|
|
||||||
templateBuilder.locationId(nodeElement.getLocation());
|
|
||||||
if (nodeElement.getImage() != null && !"".equals(nodeElement.getImage())) {
|
|
||||||
final String imageId = nodeElement.getImage();
|
|
||||||
try {
|
|
||||||
templateBuilder.imageId(imageId);
|
|
||||||
} catch (NoSuchElementException e) {
|
|
||||||
throw new BuildException("image not found " + nodeElement.getImage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
templateBuilder.osFamily(OsFamily.valueOf(nodeElement.getOs()));
|
|
||||||
}
|
|
||||||
addHardwareFromElementToTemplate(nodeElement, templateBuilder);
|
|
||||||
templateBuilder.options(getNodeOptionsFromElement(nodeElement));
|
|
||||||
|
|
||||||
return templateBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addHardwareFromElementToTemplate(NodeElement nodeElement, TemplateBuilder template) {
|
|
||||||
if (nodeElement.getHardware().equalsIgnoreCase("smallest")) {
|
|
||||||
template.smallest();
|
|
||||||
} else if (nodeElement.getHardware().equalsIgnoreCase("fastest")) {
|
|
||||||
template.fastest();
|
|
||||||
} else if (nodeElement.getHardware().equalsIgnoreCase("biggest")) {
|
|
||||||
template.biggest();
|
|
||||||
} else {
|
|
||||||
throw new BuildException("size: " + nodeElement.getHardware()
|
|
||||||
+ " not supported. valid sizes are smallest, fastest, biggest");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static TemplateOptions getNodeOptionsFromElement(NodeElement nodeElement) throws IOException {
|
|
||||||
TemplateOptions options = new TemplateOptions().inboundPorts(getPortsToOpenFromElement(nodeElement));
|
|
||||||
addRunScriptToOptionsIfPresentInNodeElement(nodeElement, options);
|
|
||||||
addPrivateKeyToOptionsIfPresentInNodeElement(nodeElement, options);
|
|
||||||
addPublicKeyToOptionsIfPresentInNodeElement(nodeElement, options);
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addRunScriptToOptionsIfPresentInNodeElement(NodeElement nodeElement, TemplateOptions options) throws IOException {
|
|
||||||
if (nodeElement.getRunscript() != null)
|
|
||||||
options.runScript(Statements.exec(Files.toString(nodeElement.getRunscript(), Charsets.UTF_8)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addPrivateKeyToOptionsIfPresentInNodeElement(NodeElement nodeElement, TemplateOptions options)
|
|
||||||
throws IOException {
|
|
||||||
if (nodeElement.getPrivatekeyfile() != null)
|
|
||||||
options.installPrivateKey(Files.toString(nodeElement.getPrivatekeyfile(), Charsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addPublicKeyToOptionsIfPresentInNodeElement(NodeElement nodeElement, TemplateOptions options) throws IOException {
|
|
||||||
if (nodeElement.getPrivatekeyfile() != null)
|
|
||||||
options.authorizePublicKey(Files.toString(nodeElement.getPublickeyfile(), Charsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
static String ipOrEmptyString(Set<String> set) {
|
|
||||||
if (set.size() > 0) {
|
|
||||||
return Iterables.get(set, 0);
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int[] getPortsToOpenFromElement(NodeElement nodeElement) {
|
|
||||||
Iterable<String> portStrings = Splitter.on(',').split(nodeElement.getOpenports());
|
|
||||||
int[] ports = new int[Iterables.size(portStrings)];
|
|
||||||
int i = 0;
|
|
||||||
for (String port : portStrings) {
|
|
||||||
ports[i++] = Integer.parseInt(port);
|
|
||||||
}
|
|
||||||
return ports;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,181 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.jclouds.tools.ant.taskdefs.compute;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Adrian Cole
|
|
||||||
* @author Ivan Meredith
|
|
||||||
*/
|
|
||||||
public class NodeElement {
|
|
||||||
private String id;
|
|
||||||
private String group;
|
|
||||||
private String hardware;
|
|
||||||
private String os;
|
|
||||||
private String image;
|
|
||||||
private int count = 1;
|
|
||||||
private String openports = "22";
|
|
||||||
private String passwordproperty;
|
|
||||||
private File privatekeyfile;
|
|
||||||
private File publickeyfile;
|
|
||||||
private String hostproperty;
|
|
||||||
private String idproperty;
|
|
||||||
private String usernameproperty;
|
|
||||||
private String location;
|
|
||||||
private File runscript;
|
|
||||||
|
|
||||||
public String getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocation(String location) {
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getUsernameproperty() {
|
|
||||||
return usernameproperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of a property in which the username of the login user should be stored.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void setUsernameproperty(String usernameproperty) {
|
|
||||||
this.usernameproperty = usernameproperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getPasswordproperty() {
|
|
||||||
return passwordproperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of a property in which the password of the login user should be stored.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void setPasswordproperty(String passwordproperty) {
|
|
||||||
this.passwordproperty = passwordproperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of a property in which the hostname of the machine should be stored
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void setHostproperty(String hostproperty) {
|
|
||||||
this.hostproperty = hostproperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getHostproperty() {
|
|
||||||
return hostproperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of a property in which the id of the machine should be stored
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void setIdproperty(String idproperty) {
|
|
||||||
this.idproperty = idproperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getIdproperty() {
|
|
||||||
return idproperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setHardware(String hardware) {
|
|
||||||
this.hardware = hardware;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHardware() {
|
|
||||||
return hardware;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOs(String os) {
|
|
||||||
this.os = os;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOs() {
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRunscript(File runscript) {
|
|
||||||
this.runscript = runscript;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getRunscript() {
|
|
||||||
return runscript;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOpenports(String openports) {
|
|
||||||
this.openports = openports;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOpenports() {
|
|
||||||
return openports;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setImage(String image) {
|
|
||||||
this.image = image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getImage() {
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCount(int count) {
|
|
||||||
this.count = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCount() {
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGroup(String group) {
|
|
||||||
this.group = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGroup() {
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrivatekeyfile(File privatekeyfile) {
|
|
||||||
this.privatekeyfile = privatekeyfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getPrivatekeyfile() {
|
|
||||||
return privatekeyfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPublickeyfile(File publickeyfile) {
|
|
||||||
this.publickeyfile = publickeyfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getPublickeyfile() {
|
|
||||||
return publickeyfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,587 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.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.security.SecureRandom;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
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.Project;
|
|
||||||
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.Replace;
|
|
||||||
import org.apache.tools.ant.taskdefs.Replace.Replacefilter;
|
|
||||||
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;
|
|
||||||
import org.apache.tools.ant.types.Environment;
|
|
||||||
import org.apache.tools.ant.types.Environment.Variable;
|
|
||||||
import org.apache.tools.ant.types.FileSet;
|
|
||||||
import org.apache.tools.ant.types.Path;
|
|
||||||
import org.jclouds.scriptbuilder.InitScript;
|
|
||||||
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 org.jclouds.scriptbuilder.domain.Statements;
|
|
||||||
import org.jclouds.tools.ant.util.SSHExecute;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
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;
|
|
||||||
import com.jcraft.jsch.JSchException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Version of the Java task that executes over ssh.
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
public class SSHJava extends Java {
|
|
||||||
private final SSHExecute exec;
|
|
||||||
private final Scp scp;
|
|
||||||
private final SSHUserInfo userInfo;
|
|
||||||
private File localDirectory;
|
|
||||||
File remotebase;
|
|
||||||
@VisibleForTesting
|
|
||||||
File remotedir;
|
|
||||||
@VisibleForTesting
|
|
||||||
Environment env = new Environment();
|
|
||||||
|
|
||||||
private OsFamily osFamily = OsFamily.UNIX;
|
|
||||||
private File errorFile;
|
|
||||||
private String errorProperty;
|
|
||||||
private File outputFile;
|
|
||||||
private String outputProperty;
|
|
||||||
String id = "sshjava" + new SecureRandom().nextLong();
|
|
||||||
private boolean append;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
final LinkedHashMap<String, String> shiftMap = Maps.newLinkedHashMap();
|
|
||||||
@VisibleForTesting
|
|
||||||
final LinkedHashMap<String, String> replace = Maps.newLinkedHashMap();
|
|
||||||
|
|
||||||
public SSHJava() {
|
|
||||||
super();
|
|
||||||
exec = new SSHExecute();
|
|
||||||
exec.setProject(getProject());
|
|
||||||
scp = new Scp();
|
|
||||||
userInfo = new SSHUserInfo();
|
|
||||||
scp.init();
|
|
||||||
setFork(true);
|
|
||||||
setTrust(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SSHJava(Task owner) {
|
|
||||||
this();
|
|
||||||
bindToOwner(owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int executeJava() throws BuildException {
|
|
||||||
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);
|
|
||||||
|
|
||||||
String command = createInitScript(osFamily, id, remotedir.getAbsolutePath(), env, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
replaceAllTokensIn(localDirectory);
|
|
||||||
|
|
||||||
FileSet cwd = new FileSet();
|
|
||||||
cwd.setDir(localDirectory);
|
|
||||||
if (osFamily == OsFamily.UNIX) {
|
|
||||||
log("removing old contents: " + remotedir.getAbsolutePath(), Project.MSG_VERBOSE);
|
|
||||||
sshexec(exec("rm -rf " + remotedir.getAbsolutePath()).render(osFamily));
|
|
||||||
} else {
|
|
||||||
// TODO need recursive remove on windows
|
|
||||||
}
|
|
||||||
mkdirAndCopyTo(remotedir.getAbsolutePath(), ImmutableList.of(cwd));
|
|
||||||
|
|
||||||
for (Entry<String, String> entry : shiftMap.entrySet()) {
|
|
||||||
FileSet set = new FileSet();
|
|
||||||
File source = new File(entry.getKey());
|
|
||||||
if (source.isDirectory()) {
|
|
||||||
set.setDir(new File(entry.getKey()));
|
|
||||||
mkdirAndCopyTo(remotebase.getAbsolutePath() + ShellToken.FS.to(osFamily) + entry.getValue(), ImmutableList
|
|
||||||
.of(set));
|
|
||||||
} else {
|
|
||||||
String destination = remotebase.getAbsolutePath() + ShellToken.FS.to(osFamily)
|
|
||||||
+ new File(entry.getValue()).getParent();
|
|
||||||
sshexec(exec("{md} " + destination).render(osFamily));
|
|
||||||
scp.init();
|
|
||||||
String scpDestination = getScpDir(destination);
|
|
||||||
log("staging: " + scpDestination, Project.MSG_VERBOSE);
|
|
||||||
scp.setFile(source.getAbsolutePath());
|
|
||||||
scp.setTodir(scpDestination);
|
|
||||||
scp.execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getCommandLine().getClasspath() != null) {
|
|
||||||
copyPathTo(getCommandLine().getClasspath(), remotedir.getAbsolutePath() + "/classpath");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getCommandLine().getBootclasspath() != null) {
|
|
||||||
copyPathTo(getCommandLine().getBootclasspath(), remotedir.getAbsolutePath() + "/bootclasspath");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (osFamily == OsFamily.UNIX) {
|
|
||||||
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"));
|
|
||||||
try {
|
|
||||||
return sshexecRedirectStreams(statement);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new BuildException(e, getLocation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void replaceAllTokensIn(File directory) {
|
|
||||||
Replace replacer = new Replace();
|
|
||||||
replacer.setProject(getProject());
|
|
||||||
replacer.setDir(directory);
|
|
||||||
|
|
||||||
Map<String, String> map = Maps.newLinkedHashMap();
|
|
||||||
// this has to go first
|
|
||||||
map.put(directory.getAbsolutePath(), remotedir.getAbsolutePath());
|
|
||||||
|
|
||||||
map.putAll(Maps.transformValues(shiftMap, new Function<String, String>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String apply(String in) {
|
|
||||||
return remotebase + ShellToken.FS.to(osFamily) + in;
|
|
||||||
}
|
|
||||||
|
|
||||||
}));
|
|
||||||
map.putAll(replace);
|
|
||||||
|
|
||||||
for (Entry<String, String> entry : map.entrySet()) {
|
|
||||||
Replacefilter filter = replacer.createReplacefilter();
|
|
||||||
filter.setToken(entry.getKey());
|
|
||||||
filter.setValue(entry.getValue());
|
|
||||||
}
|
|
||||||
replacer.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
int exitStatus;
|
|
||||||
try {
|
|
||||||
exitStatus = sshexec(statement.render(osFamily));
|
|
||||||
} finally {
|
|
||||||
redirector.complete();
|
|
||||||
}
|
|
||||||
return exitStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void mkdirAndCopyTo(String destination, Iterable<FileSet> sets) {
|
|
||||||
if (Iterables.size(sets) == 0) {
|
|
||||||
log("no content: " + destination, Project.MSG_DEBUG);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (sshexec(exec("test -d " + destination).render(osFamily)) == 0) {// TODO windows
|
|
||||||
log("already created: " + destination, Project.MSG_VERBOSE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sshexec(exec("{md} " + destination).render(osFamily));
|
|
||||||
scp.init();
|
|
||||||
String scpDestination = getScpDir(destination);
|
|
||||||
log("staging: " + scpDestination, Project.MSG_VERBOSE);
|
|
||||||
for (FileSet set : sets)
|
|
||||||
scp.addFileset(set);
|
|
||||||
scp.setTodir(scpDestination);
|
|
||||||
scp.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getScpDir(String path) {
|
|
||||||
return String.format("%s:%s@%s:%s", userInfo.getName(), userInfo.getKeyfile() == null ? userInfo.getPassword()
|
|
||||||
: userInfo.getPassphrase(), scp.getHost(), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetPathToUnderPrefixIfExistsAndIsFileIfNotExistsAddAsIs(Path path, String prefix, StringBuilder destination) {
|
|
||||||
if (path == null)
|
|
||||||
return;
|
|
||||||
String[] paths = path.list();
|
|
||||||
if (paths != null && paths.length > 0) {
|
|
||||||
for (int i = 0; i < paths.length; i++) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void copyPathTo(Path path, String destination) {
|
|
||||||
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();
|
|
||||||
if (file.isFile()) {
|
|
||||||
fileset.setFile(file);
|
|
||||||
} else {
|
|
||||||
fileset.setDir(file);
|
|
||||||
}
|
|
||||||
filesets.add(fileset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mkdirAndCopyTo(destination, filesets);
|
|
||||||
}
|
|
||||||
|
|
||||||
String reprefix(String in) {
|
|
||||||
log("comparing: " + in, Project.MSG_DEBUG);
|
|
||||||
for (Entry<String, String> entry : shiftMap.entrySet()) {
|
|
||||||
if (in.startsWith(entry.getKey())) {
|
|
||||||
log("match shift map: " + entry.getKey(), Project.MSG_DEBUG);
|
|
||||||
in = remotebase + ShellToken.FS.to(osFamily) + entry.getValue() + in.substring(entry.getKey().length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Entry<String, String> entry : replace.entrySet()) {
|
|
||||||
if (in.startsWith(entry.getKey())) {
|
|
||||||
log("match replaceMap: " + entry.getKey(), Project.MSG_DEBUG);
|
|
||||||
in = entry.getValue() + in.substring(entry.getKey().length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log("now: " + in, Project.MSG_DEBUG);
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
String createInitScript(OsFamily osFamily, String id, String basedir, Environment env,
|
|
||||||
CommandlineJava commandLine) {
|
|
||||||
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_DEBUG);
|
|
||||||
String[] keyValue = environment[i].split("=");
|
|
||||||
envVariables.put(keyValue[0], keyValue[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StringBuilder commandBuilder = new StringBuilder(commandLine.getVmCommand().getExecutable());
|
|
||||||
if (commandLine.getBootclasspath() != null) {
|
|
||||||
commandBuilder.append(" -Xbootclasspath:bootclasspath");
|
|
||||||
resetPathToUnderPrefixIfExistsAndIsFileIfNotExistsAddAsIs(commandLine.getBootclasspath(),
|
|
||||||
"bootclasspath", commandBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (commandLine.getVmCommand().getArguments() != null
|
|
||||||
&& commandLine.getVmCommand().getArguments().length > 0) {
|
|
||||||
commandBuilder.append(" ").append(
|
|
||||||
Joiner.on(' ').join(commandLine.getVmCommand().getArguments()));
|
|
||||||
}
|
|
||||||
commandBuilder.append(" -cp classpath");
|
|
||||||
resetPathToUnderPrefixIfExistsAndIsFileIfNotExistsAddAsIs(commandLine.getClasspath(),
|
|
||||||
"classpath", commandBuilder);
|
|
||||||
|
|
||||||
if (commandLine.getSystemProperties() != null
|
|
||||||
&& commandLine.getSystemProperties().getVariables() != null
|
|
||||||
&& commandLine.getSystemProperties().getVariables().length > 0) {
|
|
||||||
commandBuilder.append(" ").append(
|
|
||||||
Joiner.on(' ').join(commandLine.getSystemProperties().getVariables()));
|
|
||||||
}
|
|
||||||
|
|
||||||
commandBuilder.append(" ").append(commandLine.getClassname());
|
|
||||||
|
|
||||||
if (commandLine.getJavaCommand().getArguments() != null
|
|
||||||
&& commandLine.getJavaCommand().getArguments().length > 0) {
|
|
||||||
commandBuilder.append(" ").append(
|
|
||||||
Joiner.on(' ').join(commandLine.getJavaCommand().getArguments()));
|
|
||||||
}
|
|
||||||
|
|
||||||
InitScript testInitBuilder = InitScript.builder().name(id).home(basedir).exportVariables(envVariables)
|
|
||||||
.run(Statements.interpret( commandBuilder.toString())).build();
|
|
||||||
return testInitBuilder.render(osFamily);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addEnv(Environment.Variable var) {
|
|
||||||
env.addVariable(var);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Note that if the {@code dir} property is set, this will be copied recursively to the remote
|
|
||||||
* host.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setDir(File localDir) {
|
|
||||||
this.localDirectory = checkNotNull(localDir, "dir");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All files transferred 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
|
|
||||||
public void setFork(boolean fork) {
|
|
||||||
if (!fork)
|
|
||||||
throw new IllegalArgumentException("this only operates when fork is set");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remote host, either DNS name or IP.
|
|
||||||
*
|
|
||||||
* @param host
|
|
||||||
* The new host value
|
|
||||||
*/
|
|
||||||
public void setHost(String host) {
|
|
||||||
exec.setHost(host);
|
|
||||||
scp.setHost(host);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Username known to remote host.
|
|
||||||
*
|
|
||||||
* @param username
|
|
||||||
* The new username value
|
|
||||||
*/
|
|
||||||
public void setUsername(String username) {
|
|
||||||
exec.setUsername(username);
|
|
||||||
scp.setUsername(username);
|
|
||||||
userInfo.setName(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the password for the user.
|
|
||||||
*
|
|
||||||
* @param password
|
|
||||||
* The new password value
|
|
||||||
*/
|
|
||||||
public void setPassword(String password) {
|
|
||||||
exec.setPassword(password);
|
|
||||||
scp.setPassword(password);
|
|
||||||
userInfo.setPassword(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the keyfile for the user.
|
|
||||||
*
|
|
||||||
* @param keyfile
|
|
||||||
* The new keyfile value
|
|
||||||
*/
|
|
||||||
public void setKeyfile(String keyfile) {
|
|
||||||
exec.setKeyfile(keyfile);
|
|
||||||
scp.setKeyfile(keyfile);
|
|
||||||
userInfo.setKeyfile(keyfile);
|
|
||||||
if (userInfo.getPassphrase() == null)
|
|
||||||
userInfo.setPassphrase("");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the passphrase for the users key.
|
|
||||||
*
|
|
||||||
* @param passphrase
|
|
||||||
* The new passphrase value
|
|
||||||
*/
|
|
||||||
public void setPassphrase(String passphrase) {
|
|
||||||
exec.setPassphrase(passphrase);
|
|
||||||
scp.setPassphrase(passphrase);
|
|
||||||
userInfo.setPassphrase(passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) {
|
|
||||||
exec.setKnownhosts(knownHosts);
|
|
||||||
scp.setKnownhosts(knownHosts);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) {
|
|
||||||
exec.setTrust(yesOrNo);
|
|
||||||
scp.setTrust(yesOrNo);
|
|
||||||
userInfo.setTrust(yesOrNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes the port used to connect to the remote host.
|
|
||||||
*
|
|
||||||
* @param port
|
|
||||||
* port number of remote host.
|
|
||||||
*/
|
|
||||||
public void setPort(int port) {
|
|
||||||
exec.setPort(port);
|
|
||||||
scp.setPort(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) {
|
|
||||||
exec.setTimeout(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setProject(Project project) {
|
|
||||||
super.setProject(project);
|
|
||||||
exec.setProject(project);
|
|
||||||
scp.setProject(project);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOwningTarget(Target target) {
|
|
||||||
super.setOwningTarget(target);
|
|
||||||
scp.setOwningTarget(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTaskName(String taskName) {
|
|
||||||
super.setTaskName(taskName);
|
|
||||||
scp.setTaskName(taskName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDescription(String description) {
|
|
||||||
super.setDescription(description);
|
|
||||||
scp.setDescription(description);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLocation(Location location) {
|
|
||||||
super.setLocation(location);
|
|
||||||
scp.setLocation(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTaskType(String type) {
|
|
||||||
super.setTaskType(type);
|
|
||||||
scp.setTaskType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SSHJava [append=" + append + ", env=" + env + ", errorFile=" + errorFile + ", errorProperty="
|
|
||||||
+ errorProperty + ", localDirectory=" + localDirectory + ", osFamily=" + osFamily + ", outputFile="
|
|
||||||
+ outputFile + ", outputProperty=" + outputProperty + ", remoteDirectory=" + remotebase + ", userInfo="
|
|
||||||
+ userInfo + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addSysproperty(Variable sysp) {
|
|
||||||
if (sysp.getKey().startsWith("sshjava.shift.")) {
|
|
||||||
shiftMap.put(sysp.getKey().replaceFirst("sshjava.shift.", ""), sysp.getValue());
|
|
||||||
} else if (sysp.getKey().startsWith("sshjava.replace.")) {
|
|
||||||
replace.put(sysp.getKey().replaceFirst("sshjava.replace.", ""), sysp.getValue());
|
|
||||||
} else if (sysp.getKey().equals("sshjava.id")) {
|
|
||||||
setId(sysp.getValue());
|
|
||||||
} else if (sysp.getKey().equals("sshjava.host")) {
|
|
||||||
setHost(sysp.getValue());
|
|
||||||
} else if (sysp.getKey().equals("sshjava.port") && !sysp.getValue().equals("")) {
|
|
||||||
setPort(Integer.parseInt(sysp.getValue()));
|
|
||||||
} else if (sysp.getKey().equals("sshjava.username")) {
|
|
||||||
setUsername(sysp.getValue());
|
|
||||||
} else if (sysp.getKey().equals("sshjava.password") && !sysp.getValue().equals("")) {
|
|
||||||
setPassword(sysp.getValue());
|
|
||||||
} else if (sysp.getKey().equals("sshjava.keyfile") && !sysp.getValue().equals("")) {
|
|
||||||
setKeyfile(sysp.getValue());
|
|
||||||
} else if (sysp.getKey().equals("sshjava.remotebase")) {
|
|
||||||
setRemotebase(new File(sysp.getValue()));
|
|
||||||
} else {
|
|
||||||
super.addSysproperty(sysp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,338 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.jclouds.tools.ant.util;
|
|
||||||
|
|
||||||
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 session.
|
|
||||||
*
|
|
||||||
* @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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.jclouds.tools.ant;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class TestClass {
|
|
||||||
public static void main(String... args) {
|
|
||||||
System.out.println("env:");
|
|
||||||
System.out.println(System.getenv(args[0]));
|
|
||||||
File cwd = new File(System.getProperty("user.dir"));
|
|
||||||
System.out.println("children:");
|
|
||||||
for (File child : cwd.listFiles())
|
|
||||||
System.out.println(" " + child);
|
|
||||||
System.out.println("what you wrote:");
|
|
||||||
System.out.println(Arrays.asList(args));
|
|
||||||
System.err.println("this is the error stream");
|
|
||||||
System.out.println("will exit 3:");
|
|
||||||
System.exit(3);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,195 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.jclouds.tools.ant.taskdefs.sshjava;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.apache.tools.ant.Project;
|
|
||||||
import org.apache.tools.ant.taskdefs.Java;
|
|
||||||
import org.apache.tools.ant.types.Environment;
|
|
||||||
import org.apache.tools.ant.types.Environment.Variable;
|
|
||||||
import org.apache.tools.ant.types.Path;
|
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
|
||||||
import org.jclouds.tools.ant.TestClass;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.io.CharStreams;
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import com.google.common.io.Resources;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Test(groups = "unit")
|
|
||||||
public class SSHJavaTest {
|
|
||||||
public static final Entry<String, String> LAST_ENV = Iterables.getLast(System.getenv()
|
|
||||||
.entrySet());
|
|
||||||
|
|
||||||
// TODO, this test will break in windows
|
|
||||||
@Test(enabled = false, groups = { "live" })
|
|
||||||
public void testShift() throws SecurityException, NoSuchMethodException, IOException {
|
|
||||||
SSHJava task = makeSSHJava();
|
|
||||||
task = directoryShift(task);
|
|
||||||
assertEquals(task.shiftMap, ImmutableMap.<String, String> of(System.getProperty("user.home")
|
|
||||||
+ "/apache-maven-2.2.1", "maven"));
|
|
||||||
assertEquals(task.replace, ImmutableMap.<String, String> of(System.getProperty("user.name"),
|
|
||||||
"root"));
|
|
||||||
new File("build").mkdirs();
|
|
||||||
Files.write(task.createInitScript(OsFamily.UNIX, "1", "remotedir", task.env, task
|
|
||||||
.getCommandLine()), new File("build", "init.sh"), Charsets.UTF_8);
|
|
||||||
task.remotedir=new File(task.remotebase, task.id);
|
|
||||||
task.replaceAllTokensIn(new File("build"));
|
|
||||||
assertEquals(Files.toString(new File("build", "init.sh"), Charsets.UTF_8), CharStreams
|
|
||||||
.toString(Resources.newReaderSupplier(Resources.getResource("init.sh"),
|
|
||||||
Charsets.UTF_8)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Java populateTask(Java task) {
|
|
||||||
Project p = new Project();
|
|
||||||
task.setProject(p);
|
|
||||||
task.setClassname(TestClass.class.getName());
|
|
||||||
task.createClasspath().add(new Path(p, "target/test-classes"));
|
|
||||||
Variable prop1 = new Environment.Variable();
|
|
||||||
prop1.setKey("fooble");
|
|
||||||
prop1.setValue("baz");
|
|
||||||
task.addSysproperty(prop1);
|
|
||||||
Variable prop2 = new Environment.Variable();
|
|
||||||
prop2.setKey("foo");
|
|
||||||
prop2.setValue("bar");
|
|
||||||
task.addSysproperty(prop2);
|
|
||||||
task.createJvmarg().setValue("-Xms16m");
|
|
||||||
task.createJvmarg().setValue("-Xmx32m");
|
|
||||||
Variable env = new Environment.Variable();
|
|
||||||
env.setKey(LAST_ENV.getKey());
|
|
||||||
env.setValue(LAST_ENV.getValue());
|
|
||||||
task.addEnv(env);
|
|
||||||
task.createArg().setValue(env.getKey());
|
|
||||||
task.createArg().setValue("hello");
|
|
||||||
task.createArg().setValue("world");
|
|
||||||
task.setDir(new File(System.getProperty("user.dir")));
|
|
||||||
task.setFork(true);
|
|
||||||
task.setJvm(System.getProperty("java.home") + "/bin/java");
|
|
||||||
task.setOutputproperty("out");
|
|
||||||
task.setErrorProperty("err");
|
|
||||||
task.setResultProperty("result");
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(enabled = false, groups = { "live" })
|
|
||||||
public void testSsh() throws NumberFormatException, FileNotFoundException, IOException {
|
|
||||||
Java java = makeJava();
|
|
||||||
java.execute();
|
|
||||||
|
|
||||||
SSHJava javaOverSsh = makeSSHJava();
|
|
||||||
addDestinationTo(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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@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("test.ssh.host");
|
|
||||||
String sshPort = System.getProperty("test.ssh.port");
|
|
||||||
String sshUser = System.getProperty("test.ssh.username");
|
|
||||||
String sshPass = System.getProperty("test.ssh.password");
|
|
||||||
String sshKeyFile = System.getProperty("test.ssh.keyfile");
|
|
||||||
|
|
||||||
int port = (sshPort != null) ? Integer.parseInt(sshPort) : 22;
|
|
||||||
InetAddress host = (sshHost != null) ? InetAddress.getByName(sshHost) : InetAddress
|
|
||||||
.getLocalHost();
|
|
||||||
javaOverSsh.setHost(host.getHostAddress());
|
|
||||||
javaOverSsh.setPort(port);
|
|
||||||
javaOverSsh.setUsername(sshUser);
|
|
||||||
if (sshKeyFile != null && !sshKeyFile.trim().equals("")) {
|
|
||||||
javaOverSsh.setKeyfile(sshKeyFile);
|
|
||||||
} else {
|
|
||||||
javaOverSsh.setPassword(sshPass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private SSHJava makeSSHJava() {
|
|
||||||
SSHJava task = new SSHJava();
|
|
||||||
populateTask(task);
|
|
||||||
task.setRemotebase(new File("/tmp/foo"));
|
|
||||||
task.setTrust(true);
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Java makeJava() {
|
|
||||||
return populateTask(new Java());
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T extends Java> T directoryShift(T java) {
|
|
||||||
Variable prop1 = new Environment.Variable();
|
|
||||||
prop1.setKey("sshjava.shift." + 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);
|
|
||||||
Variable prop4 = new Environment.Variable();
|
|
||||||
prop4.setKey("sshjava.replace." + System.getProperty("user.name"));
|
|
||||||
prop4.setValue("root");
|
|
||||||
java.addSysproperty(prop4);
|
|
||||||
Variable prop5 = new Environment.Variable();
|
|
||||||
prop5.setKey("username");
|
|
||||||
prop5.setValue(System.getProperty("user.name"));
|
|
||||||
java.addSysproperty(prop5);
|
|
||||||
return java;
|
|
||||||
}
|
|
||||||
}
|
|
1
pom.xml
1
pom.xml
|
@ -45,7 +45,6 @@
|
||||||
<module>blobstore</module>
|
<module>blobstore</module>
|
||||||
<module>skeletons</module>
|
<module>skeletons</module>
|
||||||
<module>drivers</module>
|
<module>drivers</module>
|
||||||
<module>antcontrib</module>
|
|
||||||
<module>scriptbuilder</module>
|
<module>scriptbuilder</module>
|
||||||
<module>allcompute</module>
|
<module>allcompute</module>
|
||||||
<module>allblobstore</module>
|
<module>allblobstore</module>
|
||||||
|
|
Loading…
Reference in New Issue