added statements for extracting targzs and running commands from a http request

This commit is contained in:
Adrian Cole 2010-09-12 17:35:51 -07:00
parent 0e15e52a70
commit 00361f859b
11 changed files with 424 additions and 70 deletions

View File

@ -21,18 +21,23 @@ package org.jclouds.aws;
import static org.jclouds.compute.BaseComputeServiceLiveTest.buildScript;
import static org.jclouds.compute.options.TemplateOptions.Builder.runScript;
import static org.jclouds.compute.util.ComputeServiceUtils.buildCurlsh;
import static org.jclouds.io.Payloads.newStringPayload;
import static org.jclouds.compute.util.ComputeServiceUtils.execHttpResponse;
import static org.jclouds.compute.util.ComputeServiceUtils.extractTargzIntoDirectory;
import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
import java.net.URI;
import org.jclouds.aws.ec2.compute.BlobStoreAndComputeServiceLiveTest;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.scriptbuilder.domain.Statement;
import org.testng.annotations.Test;
/**
* This test helps us understand how we can use the power of blobstores to our favor.
*
* @author Adrian Cole
*/
@ -57,9 +62,9 @@ public class ComputeAndBlobStoreTogetherHappilyLiveTest extends BlobStoreAndComp
* next convert this into something that can be invoked via the commandline. Looking around, it
* seems like alestic runurl is pretty close. However, it is limited as it only works on requests
* that can be fully specified without headers (ex. Amazon S3). Instead, we use a variant
* (curlsh).
* (execHttpResponse).
* <p/>
* curlsh simply assembles an http request, headers and all, and passes it to bash
* execHttpResponse simply assembles an http request, headers and all, and passes it to bash
* <p/>
* With this script ready, any node or nodes will take instructions from the blobstore when it
* boots up. we verify this with an assertion.
@ -79,15 +84,27 @@ public class ComputeAndBlobStoreTogetherHappilyLiveTest extends BlobStoreAndComp
// configured for amz. Note we are getting temporary access to a private blob.
HttpRequest signedRequestOfInstallScript = blobContext.getBlobStore().signRequestForBlob(tag, "openjdk/install");
// instruct the bootstrap to pull the script from the blobstore and invoke it directly with bash.
TemplateOptions runOpenJDKInstallDirectlyFromBlobStore = runScript(newStringPayload(buildCurlsh(signedRequestOfInstallScript)));
// so one of our commands is to execute the contents of the blob above
Statement installOpenJDK = execHttpResponse(signedRequestOfInstallScript);
// if we want to, we can mix and match batched and ad-hoc commands, such as extracting maven
String mavenVersion = "3.0-beta-3";
Statement extractMavenIntoUsrLocal = extractTargzIntoDirectory(URI
.create("http://mirrors.ibiblio.org/pub/mirrors/apache//maven/binaries/apache-maven-" + mavenVersion
+ "-bin.tar.gz"), "/usr/local");
// have both of these commands occur on boot
Statement bootstrapInstructions = newStatementList(installOpenJDK, extractMavenIntoUsrLocal);
// now that we have the correct instructions, kick-off the provisioner
Iterable<? extends NodeMetadata> nodes = computeContext.getComputeService().runNodesWithTag(tag, 1,
runOpenJDKInstallDirectlyFromBlobStore);
Iterable<? extends NodeMetadata> nodes = computeContext.getComputeService().runNodesWithTag(tag, 2,
runScript(bootstrapInstructions));
// ensure the bootstrap operated by checking for a known signature of success.
assertSshOutputOfCommandContains(nodes, "openjdk -version", "OpenJDK");
// ensure the bootstrap operated by checking for the components we installed at boot time.
// Note this test will ensure both nodes are in sync.
assertSshOutputOfCommandContains(nodes, "java -version", "OpenJDK");
assertSshOutputOfCommandContains(nodes, "/usr/local/apache-maven-" + mavenVersion + "/bin/mvn -version",
"Apache Maven " + mavenVersion + "");
}
}

View File

@ -64,25 +64,26 @@ public class BlobStoreAndComputeServiceLiveTest {
setupCredentials();
computeContext = new ComputeServiceContextFactory().createContext(computeServiceProvider, identity, credential,
ImmutableSet.of(new Log4JLoggingModule(), new JschSshClientModule()));
blobContext = new BlobStoreContextFactory().createContext(blobStoreProvider, identity, credential,
ImmutableSet.of(new Log4JLoggingModule()));
blobContext = new BlobStoreContextFactory().createContext(blobStoreProvider, identity, credential, ImmutableSet
.of(new Log4JLoggingModule()));
blobContext.getAsyncBlobStore().createContainerInLocation(null, tag);
computeContext.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
}
protected void assertSshOutputOfCommandContains(Iterable<? extends NodeMetadata> nodes, String cmd, String expects) {
IPSocket socket = new IPSocket(get(get(nodes, 0).getPublicAddresses(), 0), 22);
for (NodeMetadata node : nodes) {
IPSocket socket = new IPSocket(get(node.getPublicAddresses(), 0), 22);
SshClient ssh = computeContext.utils().sshFactory().create(socket, get(nodes, 0).getCredentials().identity,
get(nodes, 0).getCredentials().credential.getBytes());
try {
ssh.connect();
;
ExecResponse exec = ssh.exec(cmd);
assert exec.getOutput().indexOf(expects) != -1 || exec.getError().indexOf(expects) != -1 : exec;
} finally {
if (ssh != null)
ssh.disconnect();
SshClient ssh = computeContext.utils().sshFactory().create(socket, node.getCredentials().identity,
node.getCredentials().credential.getBytes());
try {
ssh.connect();
ExecResponse exec = ssh.exec(cmd);
assert exec.getOutput().indexOf(expects) != -1 || exec.getError().indexOf(expects) != -1 : exec;
} finally {
if (ssh != null)
ssh.disconnect();
}
}
}

View File

@ -26,14 +26,19 @@ import static org.jclouds.io.Payloads.newStringPayload;
import java.util.Arrays;
import javax.annotation.Nullable;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.predicates.OperatingSystemPredicates;
import org.jclouds.io.Payload;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.domain.Statement;
/**
* Contains options supported in the {@code ComputeService#runNodesWithTag}
* operation. <h2>
* Usage</h2> The recommended way to instantiate a TemplateOptions object is to
* statically import TemplateOptions.* and invoke a static creation method
* followed by an instance mutator (if needed):
* Contains options supported in the {@code ComputeService#runNodesWithTag} operation. <h2>
* Usage</h2> The recommended way to instantiate a TemplateOptions object is to statically import
* TemplateOptions.* and invoke a static creation method followed by an instance mutator (if
* needed):
* <p/>
* <code>
* import static org.jclouds.compute.options.TemplateOptions.Builder.*;
@ -207,8 +212,8 @@ public class TemplateOptions {
}
/**
* This script will be executed as the root user upon system startup. This
* script gets a prologue, so no #!/bin/bash required, path set up, etc
* This script will be executed as the root user upon system startup. This script gets a
* prologue, so no #!/bin/bash required, path set up, etc
* <p/>
* please use alternative that uses the {@link org.jclouds.io.Payload} object
*
@ -220,19 +225,26 @@ public class TemplateOptions {
}
/**
* This script will be executed as the root user upon system startup. This
* script gets a prologue, so no #!/bin/bash required, path set up, etc
* This script will be executed as the root user upon system startup. This script gets a
* prologue, so no #!/bin/bash required, path set up, etc
*
* @see org.jclouds.io.Payloads
*/
public TemplateOptions runScript(Payload script) {
checkArgument(
checkNotNull(checkNotNull(script, "script").getContentLength(), "script.contentLength") <= 16 * 1024,
"script cannot be larger than 16kb");
checkNotNull(script, "script");
this.script = script;
return this;
}
public TemplateOptions runScript(Statement script, @Nullable OperatingSystem os) {
return runScript(newStringPayload(checkNotNull(script, "script").render(
os == null || OperatingSystemPredicates.isUnix().apply(os) ? OsFamily.UNIX : OsFamily.WINDOWS)));
}
public TemplateOptions runScript(Statement script) {
return runScript(script, null);
}
/**
* replaces the rsa ssh key used at login.
* <p/>
@ -243,7 +255,7 @@ public class TemplateOptions {
@Deprecated
public TemplateOptions installPrivateKey(String privateKey) {
checkArgument(checkNotNull(privateKey, "privateKey").startsWith("-----BEGIN RSA PRIVATE KEY-----"),
"key should start with -----BEGIN RSA PRIVATE KEY-----");
"key should start with -----BEGIN RSA PRIVATE KEY-----");
Payload payload = newStringPayload(privateKey);
payload.setContentType("text/plain");
return installPrivateKey(payload);
@ -265,8 +277,8 @@ public class TemplateOptions {
}
/**
* if true, return when node(s) are NODE_RUNNING, if false, return as soon as
* the server is provisioned.
* if true, return when node(s) are NODE_RUNNING, if false, return as soon as the server is
* provisioned.
* <p/>
* default is true
*/
@ -344,8 +356,7 @@ public class TemplateOptions {
}
/**
* please use alternative that uses the {@link org.jclouds.io.Payload}
* object
* please use alternative that uses the {@link org.jclouds.io.Payload} object
*
* @see org.jclouds.io.Payloads
* @see #runScript(Payload)
@ -366,8 +377,16 @@ public class TemplateOptions {
}
/**
* please use alternative that uses the {@link org.jclouds.io.Payload}
* object
* @see TemplateOptions#runScript
* @see org.jclouds.io.Payloads
*/
public static TemplateOptions runScript(Statement script) {
TemplateOptions options = new TemplateOptions();
return options.runScript(script);
}
/**
* please use alternative that uses the {@link org.jclouds.io.Payload} object
*
* @see org.jclouds.io.Payloads
* @see #installPrivateKey(Payload)
@ -388,8 +407,7 @@ public class TemplateOptions {
}
/**
* please use alternative that uses the {@link org.jclouds.io.Payload}
* object
* please use alternative that uses the {@link org.jclouds.io.Payload} object
*
* @see org.jclouds.io.Payloads
* @see #authorizePublicKey(Payload)
@ -419,9 +437,9 @@ public class TemplateOptions {
@Override
public String toString() {
return "TemplateOptions [inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null)
+ ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null) + ", blockUntilRunning="
+ blockUntilRunning + ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata
+ "]";
+ ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null) + ", blockUntilRunning="
+ blockUntilRunning + ", port:seconds=" + port + ":" + seconds + ", metadata/details: "
+ includeMetadata + "]";
}
@Override

View File

@ -34,6 +34,33 @@ import com.google.common.collect.ImmutableSet;
* @author Adrian Cole
*/
public class OperatingSystemPredicates {
/**
* evaluates true if the OperatingSystem is unix like
*
*/
public static Predicate<OperatingSystem> isUnix() {
return new Predicate<OperatingSystem>() {
@Override
public boolean apply(OperatingSystem os) {
if (os.getFamily() != null) {
switch (os.getFamily()) {
case WINDOWS:
return false;
}
}
for (String toMatch : ImmutableSet.of(os.getName(), os.getDescription()))
if (toMatch != null && toMatch.toLowerCase().indexOf("windows") != -1)
return false;
return true;
}
@Override
public String toString() {
return "isUnix()";
}
};
}
/**
* evaluates true if the OperatingSystem supports the apt installer
*

View File

@ -19,6 +19,12 @@
package org.jclouds.compute.util;
import static com.google.common.base.Throwables.getStackTraceAsString;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import static org.jclouds.scriptbuilder.domain.Statements.pipeHttpResponseToBash;
import java.net.URI;
import java.util.Formatter;
import java.util.Map;
import java.util.NoSuchElementException;
@ -38,15 +44,13 @@ import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpRequest;
import org.jclouds.logging.Logger;
import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.ssh.SshClient;
import org.jclouds.util.Utils;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
/**
*
@ -60,17 +64,25 @@ public class ComputeServiceUtils {
*
* @return a shell script that will invoke the http request
*/
public static String buildCurlsh(HttpRequest request) {
String headers = Joiner.on(' ').join(
Iterables.transform(request.getHeaders().entries(), new Function<Entry<String, String>, String>() {
public static Statement execHttpResponse(HttpRequest request) {
return pipeHttpResponseToBash(request.getMethod(), request.getEndpoint(), request.getHeaders());
}
@Override
public String apply(Entry<String, String> from) {
return String.format("-H \"%s: %s\"", from.getKey(), from.getValue());
}
public static Statement execHttpResponse(URI location) {
return execHttpResponse(new HttpRequest("GET", location));
}
}));
return String.format("curl -s --retry 20 %s %s |bash\n", headers, request.getEndpoint().toASCIIString());
/**
* build a shell script that invokes the contents of the http request in bash.
*
* @return a shell script that will invoke the http request
*/
public static Statement extractTargzIntoDirectory(HttpRequest targz, String directory) {
return Statements.extractTargzIntoDirectory(targz.getMethod(), targz.getEndpoint(), targz.getHeaders(), directory);
}
public static Statement extractTargzIntoDirectory(URI targz, String directory) {
return extractTargzIntoDirectory(new HttpRequest("GET", targz), directory);
}
public static String parseTagFromName(String from) {
@ -113,11 +125,11 @@ public class ComputeServiceUtils {
if (NAME_VERSION_MAP.containsKey(family)) {
CONTAINS_SUBSTRING contains = new CONTAINS_SUBSTRING(in.replace('-', '.'));
try {
String key = Iterables.find(NAME_VERSION_MAP.get(family).keySet(), contains);
String key = find(NAME_VERSION_MAP.get(family).keySet(), contains);
return NAME_VERSION_MAP.get(family).get(key);
} catch (NoSuchElementException e) {
try {
return Iterables.find(NAME_VERSION_MAP.get(family).values(), contains);
return find(NAME_VERSION_MAP.get(family).values(), contains);
} catch (NoSuchElementException e1) {
}
}
@ -140,7 +152,7 @@ public class ComputeServiceUtils {
int index = 1;
for (Entry<?, Exception> errorMessage : executionExceptions.entrySet()) {
fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue().getClass().getSimpleName(), errorMessage
.getKey(), Throwables.getStackTraceAsString(errorMessage.getValue()));
.getKey(), getStackTraceAsString(errorMessage.getValue()));
}
return fmt.format("%s error[s]", executionExceptions.size()).toString();
}
@ -150,14 +162,14 @@ public class ComputeServiceUtils {
int index = 1;
for (Entry<? extends NodeMetadata, ? extends Throwable> errorMessage : failedNodes.entrySet()) {
fmt.format("%s) %s on node %s:%n%s%n%n", index++, errorMessage.getValue().getClass().getSimpleName(),
errorMessage.getKey().getId(), Throwables.getStackTraceAsString(errorMessage.getValue()));
errorMessage.getKey().getId(), getStackTraceAsString(errorMessage.getValue()));
}
return fmt.format("%s error[s]", failedNodes.size()).toString();
}
public static Iterable<? extends ComputeMetadata> filterByName(Iterable<? extends ComputeMetadata> nodes,
final String name) {
return Iterables.filter(nodes, new Predicate<ComputeMetadata>() {
return filter(nodes, new Predicate<ComputeMetadata>() {
@Override
public boolean apply(ComputeMetadata input) {
return input.getName().equalsIgnoreCase(name);

View File

@ -24,6 +24,7 @@ import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.jclouds.http.HttpRequest;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
@ -38,14 +39,26 @@ import com.google.common.collect.ImmutableMultimap;
public class ComputeServiceUtilsTest {
@Test
public void testCurlSh() {
public void testExecHttpResponse() {
HttpRequest request = new HttpRequest("GET", URI.create("https://adriancolehappy.s3.amazonaws.com/java/install"),
ImmutableMultimap.of("Host", "adriancolehappy.s3.amazonaws.com", "Date",
"Sun, 12 Sep 2010 08:25:19 GMT", "Authorization", "AWS 0ASHDJAS82:JASHFDA="));
assertEquals(
ComputeServiceUtils.buildCurlsh(request),
"curl -s --retry 20 -H \"Host: adriancolehappy.s3.amazonaws.com\" -H \"Date: Sun, 12 Sep 2010 08:25:19 GMT\" -H \"Authorization: AWS 0ASHDJAS82:JASHFDA=\" https://adriancolehappy.s3.amazonaws.com/java/install |bash\n");
ComputeServiceUtils.execHttpResponse(request).render(OsFamily.UNIX),
"curl -X GET -s --retry 20 -H \"Host: adriancolehappy.s3.amazonaws.com\" -H \"Date: Sun, 12 Sep 2010 08:25:19 GMT\" -H \"Authorization: AWS 0ASHDJAS82:JASHFDA=\" https://adriancolehappy.s3.amazonaws.com/java/install |(bash)\n");
}
@Test
public void testTarxzpHttpResponse() {
HttpRequest request = new HttpRequest("GET", URI.create("https://adriancolehappy.s3.amazonaws.com/java/install"),
ImmutableMultimap.of("Host", "adriancolehappy.s3.amazonaws.com", "Date",
"Sun, 12 Sep 2010 08:25:19 GMT", "Authorization", "AWS 0ASHDJAS82:JASHFDA="));
assertEquals(
ComputeServiceUtils.extractTargzIntoDirectory(request, "/stage/").render(OsFamily.UNIX),
"curl -X GET -s --retry 20 -H \"Host: adriancolehappy.s3.amazonaws.com\" -H \"Date: Sun, 12 Sep 2010 08:25:19 GMT\" -H \"Authorization: AWS 0ASHDJAS82:JASHFDA=\" https://adriancolehappy.s3.amazonaws.com/java/install |(mkdir -p /stage/ &&cd /stage/ &&tar -xpzf -)\n");
}
}

View File

@ -0,0 +1,65 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.scriptbuilder.domain;
import static com.google.common.base.Preconditions.checkArgument;
import java.net.URI;
import java.util.Map.Entry;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
/**
* Pipes the content of the http response to a shell command that accepts input from stdin
*
* @author Adrian Cole
*/
public class PipeHttpResponseTo extends InterpretableStatement {
/**
*
* @param toExec
* what to invoke
* @param method
* http method: ex GET
* @param endpoint
* uri corresponding to the request
* @param headers
* request headers to send
*/
public PipeHttpResponseTo(Statement toExec, String method, URI endpoint, Multimap<String, String> headers) {
super(String.format("curl -X %s -s --retry 20 %s %s |(%s)\n", method, Joiner.on(' ').join(
Iterables.transform(headers.entries(), new Function<Entry<String, String>, String>() {
@Override
public String apply(Entry<String, String> from) {
return String.format("-H \"%s: %s\"", from.getKey(), from.getValue());
}
})), endpoint.toASCIIString(), toExec.render(OsFamily.UNIX)));
}
public String render(OsFamily family) {
checkArgument(family != OsFamily.WINDOWS, "windows not supported");
return super.render(family);
}
}

View File

@ -0,0 +1,46 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.scriptbuilder.domain;
import java.net.URI;
import com.google.common.collect.Multimap;
/**
* Pipes the content of the http response to bash
*
* @author Adrian Cole
*/
public class PipeHttpResponseToBash extends PipeHttpResponseTo {
/**
*
*
* @param method
* http method: ex GET
* @param endpoint
* uri corresponding to the request
* @param headers
* request headers to send
*/
public PipeHttpResponseToBash(String method, URI endpoint, Multimap<String, String> headers) {
super(Statements.interpret("bash"), method, endpoint, headers);
}
}

View File

@ -0,0 +1,47 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.scriptbuilder.domain;
import java.net.URI;
import com.google.common.collect.Multimap;
/**
* Pipes the content of the http response to tar -xpzf
*
* @author Adrian Cole
*/
public class PipeHttpResponseToTarxpzfIntoDirectory extends PipeHttpResponseTo {
/**
*
*
* @param method
* http method: ex GET
* @param endpoint
* uri corresponding to the request
* @param headers
* request headers to send
*/
public PipeHttpResponseToTarxpzfIntoDirectory(String method, URI endpoint, Multimap<String, String> headers,
String directory) {
super(Statements.interpret(String.format("{md} %s &&{cd} %s &&tar -xpzf -", directory, directory)), method,
endpoint, headers);
}
}

View File

@ -19,8 +19,11 @@
package org.jclouds.scriptbuilder.domain;
import java.net.URI;
import java.util.Map;
import com.google.common.collect.Multimap;
/**
* Statements used in shell scripts.
*
@ -97,7 +100,7 @@ public class Statements {
*
* @see ShellToken
*/
public static Statement interpret(String ... portableStatements) {
public static Statement interpret(String... portableStatements) {
return new InterpretableStatement(portableStatements);
}
@ -107,4 +110,33 @@ public class Statements {
public static Statement exec(String portableStatement) {
return interpret(portableStatement + "{lf}");
}
/**
* untar, ungzip the data received from the request parameters.
*
* @param method
* http method: ex GET
* @param endpoint
* uri corresponding to the request
* @param headers
* request headers to send
*/
public static Statement extractTargzIntoDirectory(String method, URI endpoint, Multimap<String, String> headers,
String directory) {
return new PipeHttpResponseToTarxpzfIntoDirectory( method, endpoint, headers,directory);
}
/**
* exec the data received from the request parameters.
*
* @param method
* http method: ex GET
* @param endpoint
* uri corresponding to the request
* @param headers
* request headers to send
*/
public static Statement pipeHttpResponseToBash(String method, URI endpoint, Multimap<String, String> headers) {
return new PipeHttpResponseToBash(method, endpoint, headers);
}
}

View File

@ -0,0 +1,76 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.scriptbuilder.domain;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "scriptbuilder.PipeHttpResponseToTest")
public class PipeHttpResponseToTest {
PipeHttpResponseTo bash = new PipeHttpResponseTo(Statements.interpret("bash"), "GET", URI
.create("https://adriancolehappy.s3.amazonaws.com/java/install"), ImmutableMultimap.of("Host",
"adriancolehappy.s3.amazonaws.com", "Date", "Sun, 12 Sep 2010 08:25:19 GMT", "Authorization",
"AWS 0ASHDJAS82:JASHFDA="));
PipeHttpResponseToBash bash2 = new PipeHttpResponseToBash("GET", URI
.create("https://adriancolehappy.s3.amazonaws.com/java/install"), ImmutableMultimap.of("Host",
"adriancolehappy.s3.amazonaws.com", "Date", "Sun, 12 Sep 2010 08:25:19 GMT", "Authorization",
"AWS 0ASHDJAS82:JASHFDA="));
public void testPipeHttpResponseToBashUNIX() {
assertEquals(
bash.render(OsFamily.UNIX),
"curl -X GET -s --retry 20 -H \"Host: adriancolehappy.s3.amazonaws.com\" -H \"Date: Sun, 12 Sep 2010 08:25:19 GMT\" -H \"Authorization: AWS 0ASHDJAS82:JASHFDA=\" https://adriancolehappy.s3.amazonaws.com/java/install |(bash)\n");
assertEquals(bash2.render(OsFamily.UNIX), bash.render(OsFamily.UNIX));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testPipeHttpResponseToBashWINDOWS() {
bash.render(OsFamily.WINDOWS);
}
PipeHttpResponseTo untar = new PipeHttpResponseTo(Statements
.interpret("{md} {root}stage{fs} &&{cd} {root}stage{fs} &&tar -xpzf -"), "GET", URI
.create("https://adriancolehappy.s3.amazonaws.com/java/install"), ImmutableMultimap.of("Host",
"adriancolehappy.s3.amazonaws.com", "Date", "Sun, 12 Sep 2010 08:25:19 GMT", "Authorization",
"AWS 0ASHDJAS82:JASHFDA="));
PipeHttpResponseTo untar2 = new PipeHttpResponseToTarxpzfIntoDirectory( "GET", URI
.create("https://adriancolehappy.s3.amazonaws.com/java/install"), ImmutableMultimap.of("Host",
"adriancolehappy.s3.amazonaws.com", "Date", "Sun, 12 Sep 2010 08:25:19 GMT", "Authorization",
"AWS 0ASHDJAS82:JASHFDA="),"{root}stage{fs}");
public void testPipeHttpResponseToUntarUNIX() {
assertEquals(
untar.render(OsFamily.UNIX),
"curl -X GET -s --retry 20 -H \"Host: adriancolehappy.s3.amazonaws.com\" -H \"Date: Sun, 12 Sep 2010 08:25:19 GMT\" -H \"Authorization: AWS 0ASHDJAS82:JASHFDA=\" https://adriancolehappy.s3.amazonaws.com/java/install |(mkdir -p /stage/ &&cd /stage/ &&tar -xpzf -)\n");
assertEquals(untar.render(OsFamily.UNIX), untar2.render(OsFamily.UNIX));
}
}