From 12d944692e6a2fcd49bc3953cb86fd1cb756802b Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 21 Sep 2010 16:01:03 -0700 Subject: [PATCH 1/6] fixed template builder problem where imageDescription wasn't matching --- .../compute/EC2TemplateBuilderLiveTest.java | 26 +++++++++++++++++++ .../domain/internal/TemplateBuilderImpl.java | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/EC2TemplateBuilderLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/EC2TemplateBuilderLiveTest.java index 24247292ff..c5f6ff2e15 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/EC2TemplateBuilderLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/EC2TemplateBuilderLiveTest.java @@ -74,6 +74,32 @@ public class EC2TemplateBuilderLiveTest { return overrides; } + @Test + public void testTemplateBuilderM1SMALLWithDescription() { + ComputeServiceContext newContext = null; + try { + newContext = new ComputeServiceContextFactory().createContext(provider, ImmutableSet + . of(new Log4JLoggingModule()), setupProperties()); + + Template template = newContext.getComputeService().templateBuilder().hardwareId(InstanceType.M1_SMALL) + .osVersionMatches("10.04").imageDescriptionMatches("ubuntu-images").osFamily(OsFamily.UBUNTU).build(); + + System.out.println(template.getHardware()); + assert (template.getImage().getProviderId().startsWith("ami-")) : template; + assertEquals(template.getImage().getOperatingSystem().getVersion(), "10.04"); + assertEquals(template.getImage().getOperatingSystem().is64Bit(), false); + assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); + assertEquals(template.getImage().getVersion(), "20100921"); + assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store"); + assertEquals(template.getLocation().getId(), "us-east-1"); + assertEquals(getCores(template.getHardware()), 1.0d); + assertEquals(template.getHardware().getId(), InstanceType.M1_SMALL); + } finally { + if (newContext != null) + newContext.close(); + } + } + @Test public void testTemplateBuilderCanUseImageIdAndhardwareId() { ComputeServiceContext newContext = null; diff --git a/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java index 53842fee08..5c0599b453 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java @@ -320,7 +320,7 @@ public class TemplateBuilderImpl implements TemplateBuilder { public boolean apply(Image input) { boolean returnVal = true; if (imageDescription != null) { - if (input.getName() == null) + if (input.getDescription() == null) returnVal = false; else returnVal = input.getDescription().equals(imageDescription) From cf5080b5507d7139b5f279466db02ee8f178cd26 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Wed, 22 Sep 2010 10:49:48 -0700 Subject: [PATCH 2/6] Issue 366: generated keypair will clash with existing keypairs in EC2 --- .../functions/CreateUniqueKeyPair.java | 11 +-- .../handlers/ParseAWSErrorFromXmlContent.java | 2 +- .../functions/CreateUniqueKeyPairTest.java | 98 +++++++++++++++++++ .../ParseAWSErrorFromXmlContentTest.java | 6 ++ 4 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/CreateUniqueKeyPairTest.java diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/CreateUniqueKeyPair.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/CreateUniqueKeyPair.java index 4dfe52808b..ce833df985 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/CreateUniqueKeyPair.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/CreateUniqueKeyPair.java @@ -26,13 +26,13 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.compute.domain.RegionAndName; import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.logging.Logger; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Supplier; @@ -59,7 +59,8 @@ public class CreateUniqueKeyPair implements Function { return createNewKeyPairInRegion(from.getRegion(), from.getName()); } - private KeyPair createNewKeyPairInRegion(String region, String tag) { + @VisibleForTesting + KeyPair createNewKeyPairInRegion(String region, String tag) { checkNotNull(region, "region"); checkNotNull(tag, "tag"); logger.debug(">> creating keyPair region(%s) tag(%s)", region, tag); @@ -68,10 +69,8 @@ public class CreateUniqueKeyPair implements Function { try { keyPair = ec2Client.getKeyPairServices().createKeyPairInRegion(region, getNextName(region, tag)); logger.debug("<< created keyPair(%s)", keyPair.getKeyName()); - } catch (AWSResponseException e) { - if (!e.getError().getCode().equals("InvalidKeyPair.Duplicate")) { - throw e; - } + } catch (IllegalStateException e) { + } } return keyPair; diff --git a/aws/core/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java b/aws/core/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java index a1f472d9d2..1ecc0d1fcc 100755 --- a/aws/core/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java +++ b/aws/core/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java @@ -94,7 +94,7 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler { && (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown"))) exception = new ResourceNotFoundException(message, exception); else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error - .getCode().equals("InvalidGroup.Duplicate"))) + .getCode().endsWith(".Duplicate"))) || (message != null && message.indexOf("already exists") != -1)) exception = new IllegalStateException(message, exception); else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure")) diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/CreateUniqueKeyPairTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/CreateUniqueKeyPairTest.java new file mode 100644 index 0000000000..edbc35ae5c --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/CreateUniqueKeyPairTest.java @@ -0,0 +1,98 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.aws.ec2.compute.functions; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import static org.testng.Assert.assertEquals; + +import java.net.UnknownHostException; + +import org.jclouds.aws.ec2.EC2Client; +import org.jclouds.aws.ec2.domain.KeyPair; +import org.jclouds.aws.ec2.services.KeyPairClient; +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ec2.CreateUniqueKeyPairTest") +public class CreateUniqueKeyPairTest { + @SuppressWarnings( { "unchecked" }) + @Test + public void testApply() throws UnknownHostException { + EC2Client client = createMock(EC2Client.class); + KeyPairClient keyClient = createMock(KeyPairClient.class); + Supplier uniqueIdSupplier = createMock(Supplier.class); + + KeyPair pair = createMock(KeyPair.class); + + expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce(); + + expect(uniqueIdSupplier.get()).andReturn("1"); + expect(keyClient.createKeyPairInRegion("region", "jclouds#tag#region#1")).andReturn(pair); + + replay(client); + replay(keyClient); + replay(uniqueIdSupplier); + + CreateUniqueKeyPair parser = new CreateUniqueKeyPair(client, uniqueIdSupplier); + + assertEquals(parser.createNewKeyPairInRegion("region", "tag"), pair); + + verify(client); + verify(keyClient); + verify(uniqueIdSupplier); + } + + @SuppressWarnings( { "unchecked" }) + @Test + public void testApplyWithIllegalStateException() throws UnknownHostException { + EC2Client client = createMock(EC2Client.class); + KeyPairClient keyClient = createMock(KeyPairClient.class); + Supplier uniqueIdSupplier = createMock(Supplier.class); + + KeyPair pair = createMock(KeyPair.class); + + expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce(); + + expect(uniqueIdSupplier.get()).andReturn("1"); + expect(keyClient.createKeyPairInRegion("region", "jclouds#tag#region#1")).andThrow(new IllegalStateException()); + expect(uniqueIdSupplier.get()).andReturn("2"); + expect(keyClient.createKeyPairInRegion("region", "jclouds#tag#region#2")).andReturn(pair); + + replay(client); + replay(keyClient); + replay(uniqueIdSupplier); + + CreateUniqueKeyPair parser = new CreateUniqueKeyPair(client, uniqueIdSupplier); + + assertEquals(parser.createNewKeyPairInRegion("region", "tag"), pair); + + verify(client); + verify(keyClient); + verify(uniqueIdSupplier); + + } +} diff --git a/aws/core/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java b/aws/core/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java index 3e9b212d70..221bea329d 100644 --- a/aws/core/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java @@ -75,6 +75,12 @@ public class ParseAWSErrorFromXmlContentTest { "InvalidGroup.Duplicate", IllegalStateException.class); } + @Test + public void test400WithInvalidKeyPairGroupDuplicateIllegalStateException() { + assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400,"Bad Request", "application/unknown", + "InvalidKeyPair.Duplicate", IllegalStateException.class); + } + @Test public void test400WithTextPlainIllegalArgumentException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "Bad Request", "text/plain", From 4dec489d421d174f20b134dd48928ec4122ae543 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Fri, 24 Sep 2010 11:39:45 -0700 Subject: [PATCH 3/6] Issue 339: refactor so that scripts can be named --- .../compute/options/EC2TemplateOptions.java | 78 ++++-- ...icationArchitecturesEC2ClientLiveTest.java | 2 +- .../aws/ec2/EBSBootEC2ClientLiveTest.java | 2 +- .../functions/RegionAndIdToImageTest.java | 4 +- .../RunningInstanceToNodeMetadataTest.java | 131 +++++----- .../options/EC2TemplateOptionsTest.java | 13 +- .../EC2RunNodesAndAddToSetStrategyTest.java | 2 +- .../PlacementGroupClientLiveTest.java | 7 +- .../aws/ec2/demos/createlamp/MainApp.java | 2 +- .../callables/AuthorizeRSAPublicKey.java | 71 ------ .../callables/InitAndStartScriptOnNode.java | 102 ++++++++ .../callables/InstallRSAPrivateKey.java | 68 ------ .../compute/callables/RunScriptOnNode.java | 93 +------ .../compute/internal/BaseComputeService.java | 89 ++++--- .../internal/ComputeServiceContextImpl.java | 2 +- .../compute/options/RunScriptOptions.java | 80 ++++++- .../compute/options/TemplateOptions.java | 226 +++++++++--------- .../StubComputeServiceContextBuilder.java | 2 +- .../StubComputeServiceClientModule.java | 2 +- .../StubComputeServiceContextModule.java | 2 +- .../compute/util/ComputeServiceUtils.java | 14 ++ .../jclouds/compute/util/ComputeUtils.java | 73 +++--- .../compute/BaseComputeServiceLiveTest.java | 9 +- .../StubComputeServiceIntegrationTest.java | 53 ++-- .../compute/options/TemplateOptionsTest.java | 13 +- .../test/resources/initscript_with_keys.sh | 136 +++++++++++ compute/src/test/resources/runscript.sh | 125 ++++++++++ .../jclouds/scriptbuilder/ScriptBuilder.java | 23 +- .../{CreateFile.java => AppendFile.java} | 7 +- .../domain/AuthorizeRSAPublicKey.java | 56 +++++ .../domain/InstallRSAPrivateKey.java | 57 +++++ .../domain/SaveHttpResponseTo.java | 59 +++++ .../scriptbuilder/domain/Statements.java | 43 +++- .../scriptbuilder/domain/SwitchArg.java | 2 +- .../UnzipHttpResponseIntoDirectory.java | 62 +++++ .../scriptbuilder/InitBuilderTest.java | 10 +- .../scriptbuilder/ScriptBuilderTest.java | 16 +- ...reateFileTest.java => AppendFileTest.java} | 16 +- .../CopyOfAuthorizeRSAPublicKeyTest.java | 43 ++++ .../domain/CreateRunScriptTest.java | 4 +- .../domain/InstallRSAPrivateKeyTest.java | 44 ++++ .../scriptbuilder/domain/SwitchArgTest.java | 6 +- .../UnzipHttpResponseIntoDirectoryToTest.java | 50 ++++ .../src/test/resources/client_rb.cmd | 1 - scriptbuilder/src/test/resources/client_rb.sh | 2 +- scriptbuilder/src/test/resources/test_init.sh | 2 +- .../src/test/resources/test_runrun.sh | 2 +- .../src/test/resources/test_script.cmd | 1 - .../src/test/resources/test_script.sh | 2 +- .../ant/taskdefs/compute/ComputeTask.java | 6 +- .../taskdefs/compute/ComputeTaskUtils.java | 30 ++- .../tools/ant/taskdefs/sshjava/SSHJava.java | 2 +- .../options/VCloudTemplateOptions.java | 4 +- .../options/VCloudTemplateOptionsTest.java | 13 +- .../TerremarkVCloudTemplateOptions.java | 29 +-- .../TerremarkVCloudTemplateOptionsTest.java | 13 +- 56 files changed, 1330 insertions(+), 676 deletions(-) delete mode 100644 compute/src/main/java/org/jclouds/compute/callables/AuthorizeRSAPublicKey.java create mode 100644 compute/src/main/java/org/jclouds/compute/callables/InitAndStartScriptOnNode.java delete mode 100644 compute/src/main/java/org/jclouds/compute/callables/InstallRSAPrivateKey.java create mode 100644 compute/src/test/resources/initscript_with_keys.sh create mode 100644 compute/src/test/resources/runscript.sh rename scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/{CreateFile.java => AppendFile.java} (93%) create mode 100644 scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java create mode 100644 scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java create mode 100644 scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SaveHttpResponseTo.java create mode 100644 scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectory.java rename scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/{CreateFileTest.java => AppendFileTest.java} (80%) create mode 100644 scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CopyOfAuthorizeRSAPublicKeyTest.java create mode 100644 scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKeyTest.java create mode 100644 scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectoryToTest.java diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/options/EC2TemplateOptions.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/options/EC2TemplateOptions.java index 62f5cc44c1..b09aa1726a 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/options/EC2TemplateOptions.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/options/EC2TemplateOptions.java @@ -26,8 +26,11 @@ import static com.google.common.base.Preconditions.checkState; import java.util.Arrays; import java.util.Set; +import org.jclouds.aws.cloudwatch.CloudWatchClient; import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Credentials; import org.jclouds.io.Payload; +import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.util.Utils; import com.google.common.collect.ImmutableSet; @@ -261,7 +264,7 @@ public class EC2TemplateOptions extends TemplateOptions { // methods that only facilitate returning the correct object type /** - * @see TemplateOptions#blockOnPort + * {@inheritDoc} */ @Override public EC2TemplateOptions blockOnPort(int port, int seconds) { @@ -269,12 +272,7 @@ public class EC2TemplateOptions extends TemplateOptions { } /** - * - * special thing is that we do assume if you are passing groups that you have everything you need - * already defined. for example, our option inboundPorts normally creates ingress rules - * accordingly but if we notice you've specified securityGroups, we do not mess with rules at all - * - * @see TemplateOptions#inboundPorts + * {@inheritDoc} */ @Override public EC2TemplateOptions inboundPorts(int... ports) { @@ -282,41 +280,41 @@ public class EC2TemplateOptions extends TemplateOptions { } /** - * @see TemplateOptions#authorizePublicKey(String) + * {@inheritDoc} */ @Override - @Deprecated public EC2TemplateOptions authorizePublicKey(String publicKey) { return EC2TemplateOptions.class.cast(super.authorizePublicKey(publicKey)); } /** - * @see TemplateOptions#authorizePublicKey(Payload) + * {@inheritDoc} */ @Override + @Deprecated public EC2TemplateOptions authorizePublicKey(Payload publicKey) { return EC2TemplateOptions.class.cast(super.authorizePublicKey(publicKey)); } /** - * @see TemplateOptions#installPrivateKey(String) + * {@inheritDoc} */ @Override - @Deprecated public EC2TemplateOptions installPrivateKey(String privateKey) { return EC2TemplateOptions.class.cast(super.installPrivateKey(privateKey)); } /** - * @see TemplateOptions#installPrivateKey(Payload) + * {@inheritDoc} */ @Override + @Deprecated public EC2TemplateOptions installPrivateKey(Payload privateKey) { return EC2TemplateOptions.class.cast(super.installPrivateKey(privateKey)); } /** - * @see TemplateOptions#runScript(Payload) + * {@inheritDoc} */ @Override public EC2TemplateOptions runScript(Payload script) { @@ -324,7 +322,7 @@ public class EC2TemplateOptions extends TemplateOptions { } /** - * @see TemplateOptions#runScript(byte[]) + * {@inheritDoc} */ @Override @Deprecated @@ -333,13 +331,61 @@ public class EC2TemplateOptions extends TemplateOptions { } /** - * @see TemplateOptions#withMetadata + * {@inheritDoc} */ @Override public EC2TemplateOptions withMetadata() { return EC2TemplateOptions.class.cast(super.withMetadata()); } + /** + * {@inheritDoc} + */ + @Override + public EC2TemplateOptions blockUntilRunning(boolean blockUntilRunning) { + return EC2TemplateOptions.class.cast(super.blockUntilRunning(blockUntilRunning)); + } + + /** + * {@inheritDoc} + */ + @Override + public EC2TemplateOptions dontAuthorizePublicKey() { + return EC2TemplateOptions.class.cast(super.dontAuthorizePublicKey()); + } + + /** + * {@inheritDoc} + */ + @Override + public EC2TemplateOptions nameTask(String name) { + return EC2TemplateOptions.class.cast(super.nameTask(name)); + } + + /** + * {@inheritDoc} + */ + @Override + public EC2TemplateOptions runAsRoot(boolean runAsRoot) { + return EC2TemplateOptions.class.cast(super.runAsRoot(runAsRoot)); + } + + /** + * {@inheritDoc} + */ + @Override + public EC2TemplateOptions runScript(Statement script) { + return EC2TemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Override + public EC2TemplateOptions withOverridingCredentials(Credentials overridingCredentials) { + return EC2TemplateOptions.class.cast(super.withOverridingCredentials(overridingCredentials)); + } + /** * @return groupIds the user specified to run instances with, or zero length set to create an * implicit group diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java index af4f7591b9..4850106f0a 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java @@ -172,7 +172,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest { String script = new ScriptBuilder() // lamp install script .addStatement(exec("runurl run.alestic.com/apt/upgrade"))// .addStatement(exec("runurl run.alestic.com/install/lamp"))// - .build(OsFamily.UNIX); + .render(OsFamily.UNIX); RunningInstance instance = null; while (instance == null) { diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/EBSBootEC2ClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/EBSBootEC2ClientLiveTest.java index 98cccd579d..6ed2e2fab2 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/EBSBootEC2ClientLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/EBSBootEC2ClientLiveTest.java @@ -299,7 +299,7 @@ public class EBSBootEC2ClientLiveTest { "du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source", "du -sk {varl}IMAGE_DIR{varr}", "rm -rf {varl}IMAGE_DIR{varr}/*", "umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END))) - .build(OsFamily.UNIX); + .render(OsFamily.UNIX); } @Test(enabled = false, dependsOnMethods = "testCreateAndAttachVolume") diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RegionAndIdToImageTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RegionAndIdToImageTest.java index b6688353e0..1af311ef28 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RegionAndIdToImageTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RegionAndIdToImageTest.java @@ -44,7 +44,7 @@ import com.google.common.collect.ImmutableSet; @Test(groups = "unit", testName = "ec2.RegionAndIdToImageTest") public class RegionAndIdToImageTest { - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked"}) @Test public void testApply() { @@ -76,7 +76,7 @@ public class RegionAndIdToImageTest { } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked"}) @Test public void testApplyNotFound() { diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java index ea9455026c..041a707e21 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java @@ -83,7 +83,7 @@ public class RunningInstanceToNodeMetadataTest { DateService dateService = new SimpleDateFormatDateService(); - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings( { "unchecked" }) @Test public void testApplyWithEBSWhenBootIsInstanceStoreAndAvailabilityZoneNotFound() throws UnknownHostException { EC2Client client = createMock(EC2Client.class); @@ -92,7 +92,7 @@ public class RunningInstanceToNodeMetadataTest { Map credentialsMap = createMock(Map.class); ConcurrentMap imageMap = createMock(ConcurrentMap.class); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M1_SMALL)); + . of(EC2Hardware.M1_SMALL)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); Image image = createMock(Image.class); @@ -104,7 +104,7 @@ public class RunningInstanceToNodeMetadataTest { Location location = new LocationImpl(LocationScope.ZONE, "us-east-1d", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(location)); + . of(location)); org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); expect(instance.getIpAddress()).andReturn("174.129.1.50"); @@ -118,24 +118,21 @@ public class RunningInstanceToNodeMetadataTest { expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage); expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn( - (Set) ImmutableSet. of(image)); + (Set) ImmutableSet. of(image)); expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "jclouds#tag#us-east-1#50"))).andReturn( - new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass")); + new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass")); expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); expect(instance.getInstanceType()).andReturn(InstanceType.M1_SMALL).atLeastOnce(); expect(instance.getEbsBlockDevices()).andReturn( - ImmutableMap. of( - "/dev/sdg", - new EbsBlockDevice("vol-1f20d376", Attachment.Status.ATTACHED, dateService - .iso8601DateParse("2009-12-11T16:32:46.000Z"), false), - "/dev/sdj", - new EbsBlockDevice("vol-c0eb78aa", Attachment.Status.ATTACHED, dateService - .iso8601DateParse("2010-06-17T10:43:28.000Z"), false))); + ImmutableMap. of("/dev/sdg", new EbsBlockDevice("vol-1f20d376", + Attachment.Status.ATTACHED, dateService.iso8601DateParse("2009-12-11T16:32:46.000Z"), false), + "/dev/sdj", new EbsBlockDevice("vol-c0eb78aa", Attachment.Status.ATTACHED, dateService + .iso8601DateParse("2010-06-17T10:43:28.000Z"), false))); expect(instance.getRootDeviceType()).andReturn(RootDeviceType.INSTANCE_STORE); expect(instance.getRootDeviceName()).andReturn(null).atLeastOnce(); @@ -148,7 +145,7 @@ public class RunningInstanceToNodeMetadataTest { replay(jcImage); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); @@ -160,11 +157,11 @@ public class RunningInstanceToNodeMetadataTest { assertEquals(metadata.getHardware().getProviderId(), "m1.small"); assertEquals(metadata.getHardware().getProcessors(), ImmutableList. of(new Processor(1.0, 1.0))); assertEquals(metadata.getHardware().getRam(), 1740); - assertEquals(metadata.getHardware().getVolumes(), - ImmutableList. of(new VolumeImpl(null, Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),// - new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false),// - new VolumeImpl("vol-1f20d376", Volume.Type.SAN, null, "/dev/sdg", false, true),// - new VolumeImpl("vol-c0eb78aa", Volume.Type.SAN, null, "/dev/sdj", false, true))); + assertEquals(metadata.getHardware().getVolumes(), ImmutableList. of(new VolumeImpl(null, + Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),// + new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false),// + new VolumeImpl("vol-1f20d376", Volume.Type.SAN, null, "/dev/sdg", false, true),// + new VolumeImpl("vol-c0eb78aa", Volume.Type.SAN, null, "/dev/sdj", false, true))); assertEquals(metadata.getCredentials(), new Credentials("user", "pass")); @@ -178,7 +175,7 @@ public class RunningInstanceToNodeMetadataTest { } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings( { "unchecked" }) @Test public void testApplyForNovaWhereNullAvailabilityZoneIpAddressNoGroups() throws UnknownHostException { EC2Client client = createMock(EC2Client.class); @@ -187,7 +184,7 @@ public class RunningInstanceToNodeMetadataTest { Map credentialsMap = createMock(Map.class); ConcurrentMap imageMap = createMock(ConcurrentMap.class); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M1_SMALL)); + . of(EC2Hardware.M1_SMALL)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); Image image = createMock(Image.class); @@ -199,7 +196,7 @@ public class RunningInstanceToNodeMetadataTest { Location region = new LocationImpl(LocationScope.REGION, "us-east-1", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(region)); + . of(region)); org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); expect(instance.getIpAddress()).andReturn(null); @@ -213,7 +210,7 @@ public class RunningInstanceToNodeMetadataTest { expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage); expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn( - (Set) ImmutableSet. of(image)); + (Set) ImmutableSet. of(image)); expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); @@ -234,7 +231,7 @@ public class RunningInstanceToNodeMetadataTest { replay(jcImage); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); @@ -246,9 +243,9 @@ public class RunningInstanceToNodeMetadataTest { assertEquals(metadata.getHardware().getProviderId(), "m1.small"); assertEquals(metadata.getHardware().getProcessors(), ImmutableList. of(new Processor(1.0, 1.0))); assertEquals(metadata.getHardware().getRam(), 1740); - assertEquals(metadata.getHardware().getVolumes(), - ImmutableList. of(new VolumeImpl(null, Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),// - new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false))); + assertEquals(metadata.getHardware().getVolumes(), ImmutableList. of(new VolumeImpl(null, + Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),// + new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false))); assertEquals(metadata.getCredentials(), new Credentials("user", null)); @@ -262,7 +259,7 @@ public class RunningInstanceToNodeMetadataTest { } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings( { "unchecked" }) @Test public void testApplyWhereUnknownInstanceType() throws UnknownHostException { EC2Client client = createMock(EC2Client.class); @@ -271,7 +268,7 @@ public class RunningInstanceToNodeMetadataTest { Map credentialsMap = createMock(Map.class); ConcurrentMap imageMap = createMock(ConcurrentMap.class); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M1_SMALL)); + . of(EC2Hardware.M1_SMALL)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); Image image = createMock(Image.class); @@ -283,7 +280,7 @@ public class RunningInstanceToNodeMetadataTest { Location region = new LocationImpl(LocationScope.REGION, "us-east-1", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(region)); + . of(region)); org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); expect(instance.getIpAddress()).andReturn(null); @@ -297,7 +294,7 @@ public class RunningInstanceToNodeMetadataTest { expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage); expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn( - (Set) ImmutableSet. of(image)); + (Set) ImmutableSet. of(image)); expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); @@ -316,7 +313,7 @@ public class RunningInstanceToNodeMetadataTest { replay(jcImage); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); @@ -337,7 +334,7 @@ public class RunningInstanceToNodeMetadataTest { } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings( { "unchecked" }) @Test public void testApplyForNovaWhereImageNotFound() throws UnknownHostException { EC2Client client = createMock(EC2Client.class); @@ -346,7 +343,7 @@ public class RunningInstanceToNodeMetadataTest { Map credentialsMap = createMock(Map.class); ConcurrentMap imageMap = createMock(ConcurrentMap.class); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M1_SMALL)); + . of(EC2Hardware.M1_SMALL)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); @@ -357,7 +354,7 @@ public class RunningInstanceToNodeMetadataTest { Location region = new LocationImpl(LocationScope.REGION, "us-east-1", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(region)); + . of(region)); org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); expect(instance.getIpAddress()).andReturn(null); @@ -371,7 +368,7 @@ public class RunningInstanceToNodeMetadataTest { expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage); expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn( - (Set) ImmutableSet. of()); + (Set) ImmutableSet. of()); expect(credentialProvider.execute(null)).andReturn(new Credentials("root", null)); @@ -392,7 +389,7 @@ public class RunningInstanceToNodeMetadataTest { replay(jcImage); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); @@ -404,9 +401,9 @@ public class RunningInstanceToNodeMetadataTest { assertEquals(metadata.getHardware().getProviderId(), "m1.small"); assertEquals(metadata.getHardware().getProcessors(), ImmutableList. of(new Processor(1.0, 1.0))); assertEquals(metadata.getHardware().getRam(), 1740); - assertEquals(metadata.getHardware().getVolumes(), - ImmutableList. of(new VolumeImpl(null, Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),// - new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false))); + assertEquals(metadata.getHardware().getVolumes(), ImmutableList. of(new VolumeImpl(null, + Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),// + new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false))); assertEquals(metadata.getCredentials(), new Credentials("root", null)); @@ -433,9 +430,9 @@ public class RunningInstanceToNodeMetadataTest { Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(location)); + . of(location)); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M2_4XLARGE)); + . of(EC2Hardware.M2_4XLARGE)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); @@ -465,7 +462,7 @@ public class RunningInstanceToNodeMetadataTest { replay(instance); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); assertEquals(metadata.getLocation(), locations.get().iterator().next()); @@ -494,9 +491,9 @@ public class RunningInstanceToNodeMetadataTest { Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(location)); + . of(location)); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M2_4XLARGE)); + . of(EC2Hardware.M2_4XLARGE)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); @@ -514,7 +511,7 @@ public class RunningInstanceToNodeMetadataTest { expect(instance.getRegion()).andReturn("us-east-1").atLeastOnce(); expect(imageMap.get(new RegionAndName("us-east-1", "imageId"))).andThrow(new NullPointerException()) - .atLeastOnce(); + .atLeastOnce(); expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); @@ -527,7 +524,7 @@ public class RunningInstanceToNodeMetadataTest { replay(instance); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); assertEquals(metadata.getLocation(), locations.get().iterator().next()); @@ -556,9 +553,9 @@ public class RunningInstanceToNodeMetadataTest { Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(location)); + . of(location)); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M2_4XLARGE)); + . of(EC2Hardware.M2_4XLARGE)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); @@ -593,7 +590,7 @@ public class RunningInstanceToNodeMetadataTest { replay(instance); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); assertEquals(metadata.getLocation(), locations.get().iterator().next()); @@ -623,9 +620,9 @@ public class RunningInstanceToNodeMetadataTest { Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(location)); + . of(location)); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M2_4XLARGE)); + . of(EC2Hardware.M2_4XLARGE)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); @@ -656,7 +653,7 @@ public class RunningInstanceToNodeMetadataTest { replay(instance); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); assertEquals(metadata.getLocation(), locations.get().iterator().next()); @@ -684,9 +681,9 @@ public class RunningInstanceToNodeMetadataTest { Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(location)); + . of(location)); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M2_4XLARGE)); + . of(EC2Hardware.M2_4XLARGE)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); @@ -717,7 +714,7 @@ public class RunningInstanceToNodeMetadataTest { replay(instance); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); assertEquals(metadata.getLocation(), locations.get().iterator().next()); @@ -734,7 +731,7 @@ public class RunningInstanceToNodeMetadataTest { verify(instance); } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings( { "unchecked" }) @Test public void testApplyWithKeyPairCreatesTagOfParsedSecurityGroupAndCredentialsBasedOnIt() throws UnknownHostException { EC2Client client = createMock(EC2Client.class); @@ -743,7 +740,7 @@ public class RunningInstanceToNodeMetadataTest { Map credentialsMap = createMock(Map.class); ConcurrentMap imageMap = createMock(ConcurrentMap.class); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M2_4XLARGE)); + . of(EC2Hardware.M2_4XLARGE)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); Image image = createMock(Image.class); @@ -755,7 +752,7 @@ public class RunningInstanceToNodeMetadataTest { Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(location)); + . of(location)); org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); expect(instance.getIpAddress()).andReturn("127.0.0.1"); @@ -769,12 +766,12 @@ public class RunningInstanceToNodeMetadataTest { expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "imageId"))).andReturn(jcImage); expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("imageId"))).andReturn( - (Set) ImmutableSet. of(image)); + (Set) ImmutableSet. of(image)); expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "jclouds#tag#us-east-1#50"))).andReturn( - new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass")); + new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass")); expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); @@ -789,7 +786,7 @@ public class RunningInstanceToNodeMetadataTest { replay(jcImage); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); assertEquals(metadata.getTag(), "tag"); @@ -808,7 +805,7 @@ public class RunningInstanceToNodeMetadataTest { } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings( { "unchecked" }) @Test public void testApplyWithTwoSecurityGroups() throws UnknownHostException { EC2Client client = createMock(EC2Client.class); @@ -817,7 +814,7 @@ public class RunningInstanceToNodeMetadataTest { Map credentialsMap = createMock(Map.class); ConcurrentMap imageMap = createMock(ConcurrentMap.class); Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet - . of(EC2Hardware.M2_4XLARGE)); + . of(EC2Hardware.M2_4XLARGE)); PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); RunningInstance instance = createMock(RunningInstance.class); Image image = createMock(Image.class); @@ -829,7 +826,7 @@ public class RunningInstanceToNodeMetadataTest { Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); Supplier> locations = Suppliers.> ofInstance(ImmutableSet - . of(location)); + . of(location)); org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); expect(instance.getIpAddress()).andReturn("127.0.0.1"); @@ -843,12 +840,12 @@ public class RunningInstanceToNodeMetadataTest { expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "imageId"))).andReturn(jcImage); expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("imageId"))).andReturn( - (Set) ImmutableSet. of(image)); + (Set) ImmutableSet. of(image)); expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "jclouds#tag#us-east-1#50"))).andReturn( - new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass")); + new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass")); expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); @@ -863,7 +860,7 @@ public class RunningInstanceToNodeMetadataTest { replay(jcImage); RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(client, credentialsMap, - credentialProvider, imageMap, locations, hardwares); + credentialProvider, imageMap, locations, hardwares); NodeMetadata metadata = parser.apply(instance); diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/options/EC2TemplateOptionsTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/options/EC2TemplateOptionsTest.java index 1b1fb852fc..52f9d25089 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/options/EC2TemplateOptionsTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/options/EC2TemplateOptionsTest.java @@ -32,7 +32,6 @@ import static org.testng.Assert.assertEquals; import java.io.IOException; import org.jclouds.compute.options.TemplateOptions; -import org.jclouds.util.Utils; import org.testng.annotations.Test; import com.google.common.collect.ImmutableSet; @@ -194,19 +193,17 @@ public class EC2TemplateOptionsTest { } // superclass tests - @SuppressWarnings("deprecation") @Test(expectedExceptions = IllegalArgumentException.class) public void testinstallPrivateKeyBadFormat() { EC2TemplateOptions options = new EC2TemplateOptions(); options.installPrivateKey("whompy"); } - @SuppressWarnings("deprecation") @Test public void testinstallPrivateKey() throws IOException { EC2TemplateOptions options = new EC2TemplateOptions(); options.installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); - assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); } @Test @@ -218,7 +215,7 @@ public class EC2TemplateOptionsTest { @Test public void testinstallPrivateKeyStatic() throws IOException { EC2TemplateOptions options = installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); - assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); } @Test(expectedExceptions = NullPointerException.class) @@ -226,19 +223,17 @@ public class EC2TemplateOptionsTest { installPrivateKey(null); } - @SuppressWarnings("deprecation") @Test(expectedExceptions = IllegalArgumentException.class) public void testauthorizePublicKeyBadFormat() { EC2TemplateOptions options = new EC2TemplateOptions(); options.authorizePublicKey("whompy"); } - @SuppressWarnings("deprecation") @Test public void testauthorizePublicKey() throws IOException { EC2TemplateOptions options = new EC2TemplateOptions(); options.authorizePublicKey("ssh-rsa"); - assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); } @Test @@ -250,7 +245,7 @@ public class EC2TemplateOptionsTest { @Test public void testauthorizePublicKeyStatic() throws IOException { EC2TemplateOptions options = authorizePublicKey("ssh-rsa"); - assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); } @Test(expectedExceptions = NullPointerException.class) diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java index 3e4f5dba14..df0ecfbd59 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java @@ -90,7 +90,7 @@ public class EC2RunNodesAndAddToSetStrategyTest { return null; } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked"}) private void assertRegionAndZoneForLocation(Location location, String region, String zone) { String imageId = "ami1"; String instanceCreatedId = "instance1"; diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java index e0cbcb8276..fb25ba9e7a 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java @@ -192,9 +192,10 @@ public class PlacementGroupClientLiveTest { assertEquals(template.getHardware().getProviderId(), InstanceType.CC1_4XLARGE); assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17"); - template.getOptions().installPrivateKey(newStringPayload(keyPair.get("private"))).authorizePublicKey( - newStringPayload(keyPair.get("public"))).runScript( - newStringPayload(BaseComputeServiceLiveTest.buildScript(template.getImage().getOperatingSystem()))); + template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public")) + .runScript( + newStringPayload(BaseComputeServiceLiveTest.buildScript(template.getImage() + .getOperatingSystem()))); String tag = PREFIX + "cccluster"; context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); diff --git a/aws/demos/createlamp/src/main/java/org/jclouds/aws/ec2/demos/createlamp/MainApp.java b/aws/demos/createlamp/src/main/java/org/jclouds/aws/ec2/demos/createlamp/MainApp.java index 4796f5bc35..be7089718c 100755 --- a/aws/demos/createlamp/src/main/java/org/jclouds/aws/ec2/demos/createlamp/MainApp.java +++ b/aws/demos/createlamp/src/main/java/org/jclouds/aws/ec2/demos/createlamp/MainApp.java @@ -160,7 +160,7 @@ public class MainApp { .addStatement(exec("runurl run.alestic.com/apt/upgrade"))// .addStatement(exec("runurl run.alestic.com/install/lamp"))// .addStatement(exec("apt-get -y install openjdk-6-jdk"))// no license agreement! - .build(OsFamily.UNIX); + .render(OsFamily.UNIX); System.out.printf("%d: running instance%n", System.currentTimeMillis()); Reservation reservation = client.getInstanceServices().runInstancesInRegion(null, null, // allow diff --git a/compute/src/main/java/org/jclouds/compute/callables/AuthorizeRSAPublicKey.java b/compute/src/main/java/org/jclouds/compute/callables/AuthorizeRSAPublicKey.java deleted file mode 100644 index f4dc9db4ca..0000000000 --- a/compute/src/main/java/org/jclouds/compute/callables/AuthorizeRSAPublicKey.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.jclouds.compute.callables; - -import static com.google.common.base.Preconditions.checkNotNull; - -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.util.ComputeServiceUtils.SshCallable; -import org.jclouds.io.Payload; -import org.jclouds.logging.Logger; -import org.jclouds.ssh.ExecResponse; -import org.jclouds.ssh.SshClient; - -import com.google.common.collect.Iterables; - -/** - * - * @author Adrian Cole - */ -public class AuthorizeRSAPublicKey implements SshCallable { - private SshClient ssh; - private final NodeMetadata node; - private final Payload publicKey; - - private Logger logger = Logger.NULL; - - public AuthorizeRSAPublicKey(NodeMetadata node, Payload publicKey) { - this.node = checkNotNull(node, "node"); - this.publicKey = checkNotNull(publicKey, "publicKey"); - } - - @Override - public ExecResponse call() throws Exception { - ssh.exec("mkdir .ssh"); - ssh.put(".ssh/id_rsa.pub", publicKey); - logger.debug(">> authorizing rsa public key for %s@%s", node.getCredentials().identity, Iterables.get(node - .getPublicAddresses(), 0)); - ExecResponse returnVal = ssh.exec("cat .ssh/id_rsa.pub >> .ssh/authorized_keys"); - returnVal = ssh.exec("chmod 600 .ssh/authorized_keys"); - logger.debug("<< complete(%d)", returnVal.getExitCode()); - return returnVal; - } - - @Override - public void setConnection(SshClient ssh, Logger logger) { - this.logger = checkNotNull(logger, "logger"); - this.ssh = checkNotNull(ssh, "ssh"); - } - - @Override - public NodeMetadata getNode() { - return node; - } -} \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/callables/InitAndStartScriptOnNode.java b/compute/src/main/java/org/jclouds/compute/callables/InitAndStartScriptOnNode.java new file mode 100644 index 0000000000..50d916a702 --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/callables/InitAndStartScriptOnNode.java @@ -0,0 +1,102 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.compute.callables; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.util.ComputeServiceUtils; +import org.jclouds.compute.util.ComputeServiceUtils.SshCallable; +import org.jclouds.io.Payloads; +import org.jclouds.logging.Logger; +import org.jclouds.scriptbuilder.domain.OsFamily; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.ssh.ExecResponse; +import org.jclouds.ssh.SshClient; + +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +public class InitAndStartScriptOnNode implements SshCallable { + protected SshClient ssh; + protected final NodeMetadata node; + protected final String scriptName; + protected final Statement script; + protected final boolean runAsRoot; + protected Logger logger = Logger.NULL; + + public InitAndStartScriptOnNode(NodeMetadata node, String scriptName, Statement script, boolean runAsRoot) { + this.node = checkNotNull(node, "node"); + this.scriptName = checkNotNull(scriptName, "scriptName"); + this.script = checkNotNull(script, "script"); + this.runAsRoot = runAsRoot; + } + + @Override + public ExecResponse call() { + ssh.put(scriptName, Payloads.newPayload(script.render(OsFamily.UNIX))); + ExecResponse returnVal = ssh.exec("chmod 755 " + scriptName); + returnVal = ssh.exec("./" + scriptName + " init"); + logger.debug("<< initialized(%d)", returnVal.getExitCode()); + + String command = (runAsRoot) ? startScriptAsRoot() : startScriptAsDefaultUser(); + returnVal = runCommand(command); + logger.debug("<< start(%d)", returnVal.getExitCode()); + return returnVal; + } + + protected ExecResponse runCommand(String command) { + ExecResponse returnVal; + logger.debug(">> running [%s] as %s@%s", command.replace(node.getCredentials().credential, "XXXXX"), node + .getCredentials().identity, Iterables.get(node.getPublicAddresses(), 0)); + returnVal = ssh.exec(command); + return returnVal; + } + + @Override + public void setConnection(SshClient ssh, Logger logger) { + this.logger = checkNotNull(logger, "logger"); + this.ssh = checkNotNull(ssh, "ssh"); + } + + protected String startScriptAsRoot() { + String command; + if (node.getCredentials().identity.equals("root")) { + command = "./" + scriptName + " start"; + } else if (ComputeServiceUtils.isKeyAuth(node)) { + command = "sudo ./" + scriptName + " start"; + } else { + command = String.format("echo '%s'|sudo -S ./%s", node.getCredentials().credential, scriptName + " start"); + } + return command; + } + + protected String startScriptAsDefaultUser() { + return "./" + scriptName + " start"; + } + + @Override + public NodeMetadata getNode() { + return node; + } +} \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/callables/InstallRSAPrivateKey.java b/compute/src/main/java/org/jclouds/compute/callables/InstallRSAPrivateKey.java deleted file mode 100644 index 4440406da1..0000000000 --- a/compute/src/main/java/org/jclouds/compute/callables/InstallRSAPrivateKey.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.jclouds.compute.callables; - -import static com.google.common.base.Preconditions.checkNotNull; - -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.util.ComputeServiceUtils.SshCallable; -import org.jclouds.io.Payload; -import org.jclouds.logging.Logger; -import org.jclouds.ssh.ExecResponse; -import org.jclouds.ssh.SshClient; - -import com.google.common.collect.Iterables; - -/** - * - * @author Adrian Cole - */ -public class InstallRSAPrivateKey implements SshCallable { - private SshClient ssh; - private final NodeMetadata node; - private final Payload privateKey; - - private Logger logger = Logger.NULL; - - public InstallRSAPrivateKey(NodeMetadata node, Payload privateKey) { - this.node = checkNotNull(node, "node"); - this.privateKey = checkNotNull(privateKey, "privateKey"); - } - - @Override - public ExecResponse call() throws Exception { - ssh.exec("mkdir .ssh"); - ssh.put(".ssh/id_rsa", privateKey); - logger.debug(">> installing rsa key for %s@%s", node.getCredentials().identity, Iterables.get(node - .getPublicAddresses(), 0)); - return ssh.exec("chmod 600 .ssh/id_rsa"); - } - - @Override - public void setConnection(SshClient ssh, Logger logger) { - this.logger = checkNotNull(logger, "logger"); - this.ssh = checkNotNull(ssh, "ssh"); - } - - @Override - public NodeMetadata getNode() { - return node; - } -} \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java b/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java index db0d446e36..19b864c939 100644 --- a/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java +++ b/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java @@ -19,86 +19,46 @@ package org.jclouds.compute.callables; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.IOException; import java.util.Collections; import javax.inject.Named; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; -import org.jclouds.compute.util.ComputeServiceUtils; -import org.jclouds.compute.util.ComputeServiceUtils.SshCallable; -import org.jclouds.io.Payload; -import org.jclouds.io.Payloads; -import org.jclouds.logging.Logger; import org.jclouds.scriptbuilder.InitBuilder; -import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.Statement; -import org.jclouds.scriptbuilder.domain.Statements; import org.jclouds.ssh.ExecResponse; -import org.jclouds.ssh.SshClient; -import org.jclouds.util.Utils; import com.google.common.base.Predicate; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; /** * * @author Adrian Cole */ -public class RunScriptOnNode implements SshCallable { - private SshClient ssh; +public class RunScriptOnNode extends InitAndStartScriptOnNode { protected final Predicate runScriptNotRunning; - private final NodeMetadata node; - private final String scriptName; - private final Payload script; - private final boolean runAsRoot; - private Logger logger = Logger.NULL; public RunScriptOnNode(@Named("SCRIPT_COMPLETE") Predicate runScriptNotRunning, - NodeMetadata node, String scriptName, Payload script) { + NodeMetadata node, String scriptName, Statement script) { this(runScriptNotRunning, node, scriptName, script, true); } public RunScriptOnNode(@Named("SCRIPT_COMPLETE") Predicate runScriptNotRunning, - NodeMetadata node, String scriptName, Payload script, boolean runAsRoot) { + NodeMetadata node, String scriptName, Statement script, boolean runAsRoot) { + super(node, scriptName, createInitScript(scriptName, script), runAsRoot); this.runScriptNotRunning = runScriptNotRunning; - this.node = checkNotNull(node, "node"); - this.scriptName = checkNotNull(scriptName, "scriptName"); - this.script = createRunScript(scriptName, script); - this.runAsRoot = runAsRoot; } - public static Payload createRunScript(String scriptName, Payload script) { + public static Statement createInitScript(String scriptName, Statement script) { String path = "/tmp/" + scriptName; - InitBuilder initBuilder = new InitBuilder(scriptName, path, path, Collections. emptyMap(), - ImmutableList. of(Statements.interpret(splitOnNewlines(script)))); - return Payloads.newByteArrayPayload(initBuilder.build(OsFamily.UNIX).getBytes()); - } - - static String[] splitOnNewlines(Payload script) { - try { - String asString = Utils.toStringAndClose(checkNotNull(script, "script").getInput()); - return Iterables.toArray(Splitter.on("\n").split(asString), String.class); - } catch (IOException e) { - throw new RuntimeException(e); - } + return new InitBuilder(scriptName, path, path, Collections. emptyMap(), Collections + .singleton(script)); } @Override - public ExecResponse call() throws Exception { - ssh.put(scriptName, script); - ExecResponse returnVal = ssh.exec("chmod 755 " + scriptName); - returnVal = ssh.exec("./" + scriptName + " init"); - logger.debug("<< initialized(%d)", returnVal.getExitCode()); - - String command = (runAsRoot) ? runScriptAsRoot() : runScriptAsDefaultUser(); - returnVal = runCommand(command); - logger.debug("<< start(%d)", returnVal.getExitCode()); + public ExecResponse call() { + ExecResponse returnVal = super.call(); boolean complete = runScriptNotRunning.apply(new CommandUsingClient("./" + scriptName + " status", ssh)); logger.debug("<< complete(%s)", complete); @@ -110,39 +70,4 @@ public class RunScriptOnNode implements SshCallable { } return returnVal; } - - private ExecResponse runCommand(String command) { - ExecResponse returnVal; - logger.debug(">> running [%s] as %s@%s", command.replace(node.getCredentials().credential, "XXXXX"), node - .getCredentials().identity, Iterables.get(node.getPublicAddresses(), 0)); - returnVal = ssh.exec(command); - return returnVal; - } - - @Override - public void setConnection(SshClient ssh, Logger logger) { - this.logger = checkNotNull(logger, "logger"); - this.ssh = checkNotNull(ssh, "ssh"); - } - - private String runScriptAsRoot() { - String command; - if (node.getCredentials().identity.equals("root")) { - command = "./" + scriptName + " start"; - } else if (ComputeServiceUtils.isKeyAuth(node)) { - command = "sudo ./" + scriptName + " start"; - } else { - command = String.format("echo '%s'|sudo -S ./%s", node.getCredentials().credential, scriptName + " start"); - } - return command; - } - - private String runScriptAsDefaultUser() { - return "./" + scriptName + " start"; - } - - @Override - public NodeMetadata getNode() { - return node; - } } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java index ec289f72df..7c91fedef4 100755 --- a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java @@ -45,7 +45,6 @@ import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.RunNodesException; import org.jclouds.compute.RunScriptOnNodesException; -import org.jclouds.compute.callables.RunScriptOnNode; import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; @@ -63,12 +62,14 @@ import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; import org.jclouds.compute.util.ComputeUtils; +import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; import org.jclouds.io.Payload; import org.jclouds.logging.Logger; import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.scriptbuilder.domain.Statements; import org.jclouds.ssh.ExecResponse; -import org.jclouds.ssh.SshClient; +import org.jclouds.util.Utils; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -151,6 +152,8 @@ public class BaseComputeService implements ComputeService { throws RunNodesException { checkArgument(tag.indexOf('-') == -1, "tag cannot contain hyphens"); checkNotNull(template.getLocation(), "location"); + if (template.getOptions().getTaskName() == null && template.getOptions().getRunScript() != null) + template.getOptions().nameTask("bootstrap"); logger.debug(">> running %d node%s tag(%s) location(%s) image(%s) hardwareProfile(%s) options(%s)", count, count > 1 ? "s" : "", tag, template.getLocation().getId(), template.getImage().getId(), template .getHardware().getId(), template.getOptions()); @@ -350,14 +353,19 @@ public class BaseComputeService implements ComputeService { @Override public Map runScriptOnNodesMatching(Predicate filter, final Payload runScript, @Nullable final RunScriptOptions options) throws RunScriptOnNodesException { - Iterable nodes = verifyParametersAndListNodes(filter, runScript, (options != null) ? options - : RunScriptOptions.NONE); + + checkNotNull(filter, "Filter must be provided"); + checkNotNull(runScript, "runScript"); + checkNotNull(options, "options"); + if (options.getTaskName() == null) + options.nameTask("jclouds-script-" + System.currentTimeMillis()); + + Iterable nodes = Iterables.filter(detailsOnAllNodes(), filter); final Map execs = Maps.newHashMap(); - + final Map> responses = Maps.newHashMap(); final Map badNodes = Maps.newLinkedHashMap(); - - Map> responses = Maps.newHashMap(); + nodes = filterNodesWhoCanRunScripts(nodes, badNodes, options.getOverrideCredentials()); for (final NodeMetadata node : nodes) { @@ -365,66 +373,53 @@ public class BaseComputeService implements ComputeService { @Override public Void call() throws Exception { try { - RunScriptOnNode callable; - if (options.isRunAsRoot()) - callable = utils.runScriptOnNode(node, "computeserv", runScript); - else - callable = utils.runScriptOnNodeAsDefaultUser(node, "computeserv", runScript); - SshClient ssh = utils.createSshClientOncePortIsListeningOnNode(node); - try { - ssh.connect(); - callable.setConnection(ssh, logger); - execs.put(node, callable.call()); - } finally { - if (ssh != null) - ssh.disconnect(); - } + ExecResponse response = utils.runScriptOnNode(node, Statements.exec(Utils.toStringAndClose(runScript + .getInput())), options); + if (response != null) + execs.put(node, response); } catch (Exception e) { badNodes.put(node, e); - } return null; } + })); } - Map exceptions = awaitCompletion(responses, executor, null, logger, "starting nodes"); + Map exceptions = awaitCompletion(responses, executor, null, logger, "running script on nodes"); if (exceptions.size() > 0 || badNodes.size() > 0) { throw new RunScriptOnNodesException(runScript, options, execs, exceptions, badNodes); } + return execs; } - private Iterable verifyParametersAndListNodes(Predicate filter, Payload runScript, - final RunScriptOptions options) { - checkNotNull(filter, "Filter must be provided"); - checkNotNull(runScript, "The script (represented by bytes array - use \"script\".getBytes() must be provided"); - checkNotNull(options, "options"); - - Iterable nodes = Iterables.filter(detailsOnAllNodes(), filter); - // TODO parallel - return Iterables.transform(nodes, new Function() { + private Iterable filterNodesWhoCanRunScripts(Iterable nodes, + final Map badNodes, final @Nullable Credentials overridingCredentials) { + nodes = Iterables.filter(Iterables.transform(nodes, new Function() { @Override public NodeMetadata apply(NodeMetadata node) { - - checkArgument(node.getPublicAddresses().size() > 0, "no public ip addresses on node: " + node); - if (options.getOverrideCredentials() != null) { - // override the credentials with provided to this - // method - node = installNewCredentials(node, options.getOverrideCredentials()); - } else { - // don't override - checkNotNull(node.getCredentials(), "If the default credentials need to be used, they can't be null"); - checkNotNull(node.getCredentials().identity, "Account name for ssh authentication must be " - + "specified. Try passing RunScriptOptions with new credentials"); - checkNotNull(node.getCredentials().credential, "Key or password for ssh authentication must be " - + "specified. Try passing RunScriptOptions with new credentials"); + try { + checkArgument(node.getPublicAddresses().size() > 0, "no public ip addresses on node: " + node); + if (overridingCredentials != null) { + node = installNewCredentials(node, overridingCredentials); + } else { + checkNotNull(node.getCredentials(), "If the default credentials need to be used, they can't be null"); + checkNotNull(node.getCredentials().identity, "Account name for ssh authentication must be " + + "specified. Try passing RunScriptOptions with new credentials"); + checkNotNull(node.getCredentials().credential, "Key or password for ssh authentication must be " + + "specified. Try passing RunScriptOptions with new credentials"); + } + return node; + } catch (Exception e) { + badNodes.put(node, e); + return null; } - return node; } - }); + }), Predicates.notNull()); + return nodes; } private Set detailsOnAllNodes() { diff --git a/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java b/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java index b8219ad2b3..6c5701da87 100644 --- a/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java +++ b/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java @@ -41,7 +41,7 @@ public class ComputeServiceContextImpl implements ComputeServiceContext { private final RestContext providerSpecificContext; private final Utils utils; - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked" }) @Inject public ComputeServiceContextImpl(ComputeService computeService, Utils utils, @Nullable LoadBalancerService loadBalancerService, RestContext providerSpecificContext) { diff --git a/compute/src/main/java/org/jclouds/compute/options/RunScriptOptions.java b/compute/src/main/java/org/jclouds/compute/options/RunScriptOptions.java index 664a55c541..2b4b2e2776 100644 --- a/compute/src/main/java/org/jclouds/compute/options/RunScriptOptions.java +++ b/compute/src/main/java/org/jclouds/compute/options/RunScriptOptions.java @@ -19,6 +19,7 @@ package org.jclouds.compute.options; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import org.jclouds.domain.Credentials; @@ -74,10 +75,37 @@ public class RunScriptOptions { throw new IllegalArgumentException("overridingCredentials is immutable"); } + @Override + public String getTaskName() { + return delegate.getTaskName(); + } + + @Override + public RunScriptOptions nameTask(String name) { + throw new IllegalArgumentException("taskName is immutable"); + } + + @Override + public RunScriptOptions blockOnPort(int port, int seconds) { + throw new IllegalArgumentException("port, seconds are immutable"); + } + + @Override + public int getPort() { + return delegate.getPort(); + } + + @Override + public int getSeconds() { + return delegate.getSeconds(); + } } - private Credentials overridingCredentials; - private boolean runAsRoot = true; + protected int port = -1; + protected int seconds = -1; + protected String taskName; + protected Credentials overridingCredentials; + protected boolean runAsRoot = true; public RunScriptOptions withOverridingCredentials(Credentials overridingCredentials) { checkNotNull(overridingCredentials, "overridingCredentials"); @@ -86,11 +114,43 @@ public class RunScriptOptions { this.overridingCredentials = overridingCredentials; return this; } + /** + * @return What to call the task relating to this script; default {@code + * jclouds-script-timestamp} where timestamp is millis since epoch + * + */ + public RunScriptOptions nameTask(String name) { + this.taskName = name; + return this; + } public RunScriptOptions runAsRoot(boolean runAsRoot) { this.runAsRoot = runAsRoot; return this; } + /** + * When the node is started, wait until the following port is active + */ + public RunScriptOptions blockOnPort(int port, int seconds) { + checkArgument(port > 0 && port < 65536, "port must be a positive integer < 65535"); + checkArgument(seconds > 0, "seconds must be a positive integer"); + this.port = port; + this.seconds = seconds; + return this; + } + + public String getTaskName() { + return taskName; + } + + + public int getPort() { + return port; + } + + public int getSeconds() { + return seconds; + } /** * Whether to override the credentials with ones supplied in call to @@ -113,6 +173,11 @@ public class RunScriptOptions { public static class Builder { + public static RunScriptOptions nameTask(String name) { + RunScriptOptions options = new RunScriptOptions(); + return options.nameTask(name); + } + public static RunScriptOptions overrideCredentialsWith(Credentials credentials) { RunScriptOptions options = new RunScriptOptions(); return options.withOverridingCredentials(credentials); @@ -122,13 +187,20 @@ public class RunScriptOptions { RunScriptOptions options = new RunScriptOptions(); return options.runAsRoot(value); } + + /** + * @see RunScriptOptions#blockOnPort + */ + public static RunScriptOptions blockOnPort(int port, int seconds) { + RunScriptOptions options = new RunScriptOptions(); + return options.blockOnPort(port, seconds); + } } @Override public String toString() { - return "RunScriptOptions [overridingCredentials=" + (overridingCredentials != null) - + ", runAsRoot=" + runAsRoot + "]"; + return "[overridingCredentials=" + (overridingCredentials != null) + ", port:seconds=" + port + ":" + seconds + ", runAsRoot=" + runAsRoot + "]"; } } diff --git a/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java b/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java index a11b507c95..990367cba0 100644 --- a/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java +++ b/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java @@ -21,18 +21,17 @@ package org.jclouds.compute.options; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.io.Payloads.newByteArrayPayload; -import static org.jclouds.io.Payloads.newStringPayload; +import java.io.IOException; import java.util.Arrays; -import javax.annotation.Nullable; - -import org.jclouds.compute.domain.OperatingSystem; -import org.jclouds.compute.predicates.OperatingSystemPredicates; +import org.jclouds.domain.Credentials; import org.jclouds.io.Payload; -import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.scriptbuilder.domain.Statements; +import org.jclouds.util.Utils; + +import com.google.common.base.Throwables; /** * Contains options supported in the {@code ComputeService#runNodesWithTag} operation.

@@ -50,7 +49,7 @@ import org.jclouds.scriptbuilder.domain.Statement; * * @author Adrian Cole */ -public class TemplateOptions { +public class TemplateOptions extends RunScriptOptions { public static final TemplateOptions NONE = new ImmutableTemplateOptions(new TemplateOptions()); @@ -81,41 +80,26 @@ public class TemplateOptions { throw new IllegalArgumentException("blockUntilRunning is immutable"); } - @Override - public TemplateOptions blockOnPort(int port, int seconds) { - throw new IllegalArgumentException("port, seconds are immutable"); - } - @Override public int[] getInboundPorts() { return delegate.getInboundPorts(); } @Override - public int getPort() { - return delegate.getPort(); - } - - @Override - public Payload getPrivateKey() { + public String getPrivateKey() { return delegate.getPrivateKey(); } @Override - public Payload getPublicKey() { + public String getPublicKey() { return delegate.getPublicKey(); } @Override - public Payload getRunScript() { + public Statement getRunScript() { return delegate.getRunScript(); } - @Override - public int getSeconds() { - return delegate.getSeconds(); - } - @Override public boolean shouldBlockUntilRunning() { return delegate.shouldBlockUntilRunning(); @@ -150,41 +134,29 @@ public class TemplateOptions { protected int[] inboundPorts = new int[] { 22 }; - protected Payload script; + protected Statement script; - protected Payload privateKey; + protected String privateKey; - protected Payload publicKey; - - protected int port = -1; - - protected int seconds = -1; + protected String publicKey; protected boolean includeMetadata; protected boolean blockUntilRunning = true; - public int getPort() { - return port; - } - - public int getSeconds() { - return seconds; - } - public int[] getInboundPorts() { return inboundPorts; } - public Payload getRunScript() { + public Statement getRunScript() { return script; } - public Payload getPrivateKey() { + public String getPrivateKey() { return privateKey; } - public Payload getPublicKey() { + public String getPublicKey() { return publicKey; } @@ -200,28 +172,17 @@ public class TemplateOptions { return clazz.cast(this); } - /** - * When the node is started, wait until the following port is active - */ - public TemplateOptions blockOnPort(int port, int seconds) { - checkArgument(port > 0 && port < 65536, "port must be a positive integer < 65535"); - checkArgument(seconds > 0, "seconds must be a positive integer"); - this.port = port; - this.seconds = seconds; - return this; - } - /** * 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 *

- * please use alternative that uses the {@link org.jclouds.io.Payload} object + * please use alternative that uses the {@link org.jclouds.scriptbuilder.domain.Statement} object * * @see org.jclouds.io.Payloads */ @Deprecated public TemplateOptions runScript(byte[] script) { - return runScript(newByteArrayPayload(checkNotNull(script, "script"))); + return runScript(Statements.exec(new String(checkNotNull(script, "script")))); } /** @@ -231,44 +192,44 @@ public class TemplateOptions { * @see org.jclouds.io.Payloads */ public TemplateOptions runScript(Payload script) { - 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))); + try { + return runScript(Statements.exec(Utils.toStringAndClose(checkNotNull(script, "script").getInput()))); + } catch (IOException e) { + Throwables.propagate(e); + return this; + } } public TemplateOptions runScript(Statement script) { - return runScript(script, null); + this.script = checkNotNull(script, "script"); + return this; + } + + /** + * replaces the rsa ssh key used at login. + */ + public TemplateOptions installPrivateKey(String privateKey) { + checkArgument(checkNotNull(privateKey, "privateKey").startsWith("-----BEGIN RSA PRIVATE KEY-----"), + "key should start with -----BEGIN RSA PRIVATE KEY-----"); + this.privateKey = privateKey; + return this; } /** * replaces the rsa ssh key used at login. *

- * please use alternative that uses the {@link org.jclouds.io.Payload} object + * please use alternative that uses {@link java.lang.String} * * @see org.jclouds.io.Payloads */ @Deprecated - public TemplateOptions installPrivateKey(String privateKey) { - checkArgument(checkNotNull(privateKey, "privateKey").startsWith("-----BEGIN RSA PRIVATE KEY-----"), - "key should start with -----BEGIN RSA PRIVATE KEY-----"); - Payload payload = newStringPayload(privateKey); - payload.getContentMetadata().setContentType("text/plain"); - return installPrivateKey(payload); - } - - /** - * replaces the rsa ssh key used at login. - * - * @see org.jclouds.io.Payloads - */ public TemplateOptions installPrivateKey(Payload privateKey) { - this.privateKey = checkNotNull(privateKey, "privateKey"); - return this; + try { + return installPrivateKey(Utils.toStringAndClose(checkNotNull(privateKey, "privateKey").getInput())); + } catch (IOException e) { + Throwables.propagate(e); + return this; + } } public TemplateOptions dontAuthorizePublicKey() { @@ -277,41 +238,29 @@ public class TemplateOptions { } /** - * if true, return when node(s) are NODE_RUNNING, if false, return as soon as the server is - * provisioned. - *

- * default is true + * authorize an rsa ssh key. */ - public TemplateOptions blockUntilRunning(boolean blockUntilRunning) { - this.blockUntilRunning = blockUntilRunning; - if (!blockUntilRunning) - port = seconds = -1; + public TemplateOptions authorizePublicKey(String publicKey) { + checkArgument(checkNotNull(publicKey, "publicKey").startsWith("ssh-rsa"), "key should start with ssh-rsa"); + this.publicKey = publicKey; return this; } /** * authorize an rsa ssh key. *

- * please use alternative that uses the {@link org.jclouds.io.Payload} object + * please use alternative that uses {@link java.lang.String} * * @see org.jclouds.io.Payloads */ @Deprecated - public TemplateOptions authorizePublicKey(String publicKey) { - checkArgument(checkNotNull(publicKey, "publicKey").startsWith("ssh-rsa"), "key should start with ssh-rsa"); - Payload payload = newStringPayload(publicKey); - payload.getContentMetadata().setContentType("text/plain"); - return authorizePublicKey(payload); - } - - /** - * authorize an rsa ssh key. - * - * @see org.jclouds.io.Payloads - */ public TemplateOptions authorizePublicKey(Payload publicKey) { - this.publicKey = checkNotNull(publicKey, "publicKey"); - return this; + try { + return authorizePublicKey(Utils.toStringAndClose(checkNotNull(publicKey, "publicKey").getInput())); + } catch (IOException e) { + Throwables.propagate(e); + return this; + } } /** @@ -329,7 +278,30 @@ public class TemplateOptions { return this; } - public static class Builder { + public static class Builder extends org.jclouds.compute.options.RunScriptOptions.Builder { + + public static TemplateOptions nameTask(String name) { + TemplateOptions options = new TemplateOptions(); + return options.nameTask(name); + } + + public static TemplateOptions overrideCredentialsWith(Credentials credentials) { + TemplateOptions options = new TemplateOptions(); + return options.withOverridingCredentials(credentials); + } + + public static TemplateOptions runAsRoot(boolean value) { + TemplateOptions options = new TemplateOptions(); + return options.runAsRoot(value); + } + + /** + * @see TemplateOptions#blockOnPort + */ + public static TemplateOptions blockOnPort(int port, int seconds) { + TemplateOptions options = new TemplateOptions(); + return options.blockOnPort(port, seconds); + } /** * @see TemplateOptions#inboundPorts @@ -339,14 +311,6 @@ public class TemplateOptions { return options.inboundPorts(ports); } - /** - * @see TemplateOptions#port - */ - public static TemplateOptions blockOnPort(int port, int seconds) { - TemplateOptions options = new TemplateOptions(); - return options.blockOnPort(port, seconds); - } - /** * @see TemplateOptions#blockUntilRunning */ @@ -436,10 +400,16 @@ 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 + "]"; + return "[inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey=" + + (publicKey != null) + ", runScript=" + (script != null) + ", blockUntilRunning=" + blockUntilRunning + + ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata + "]"; + } + + public TemplateOptions blockUntilRunning(boolean blockUntilRunning) { + this.blockUntilRunning = blockUntilRunning; + if (!blockUntilRunning) + port = seconds = -1; + return this; } @Override @@ -493,4 +463,24 @@ public class TemplateOptions { return false; return true; } + + @Override + public TemplateOptions blockOnPort(int port, int seconds) { + return TemplateOptions.class.cast(super.blockOnPort(port, seconds)); + } + + @Override + public TemplateOptions nameTask(String name) { + return TemplateOptions.class.cast(super.nameTask(name)); + } + + @Override + public TemplateOptions runAsRoot(boolean runAsRoot) { + return TemplateOptions.class.cast(super.runAsRoot(runAsRoot)); + } + + @Override + public TemplateOptions withOverridingCredentials(Credentials overridingCredentials) { + return TemplateOptions.class.cast(super.withOverridingCredentials(overridingCredentials)); + } } diff --git a/compute/src/main/java/org/jclouds/compute/stub/StubComputeServiceContextBuilder.java b/compute/src/main/java/org/jclouds/compute/stub/StubComputeServiceContextBuilder.java index 332f8e5561..bf71988c23 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/StubComputeServiceContextBuilder.java +++ b/compute/src/main/java/org/jclouds/compute/stub/StubComputeServiceContextBuilder.java @@ -33,7 +33,7 @@ import com.google.inject.Module; * * @author Adrian Cole */ -@SuppressWarnings("rawtypes") +@SuppressWarnings("unchecked") public class StubComputeServiceContextBuilder extends ComputeServiceContextBuilder { public StubComputeServiceContextBuilder(Properties props) { diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceClientModule.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceClientModule.java index 5f9ce9f3f8..7b856d6a48 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceClientModule.java +++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceClientModule.java @@ -25,7 +25,7 @@ import org.jclouds.http.RequiresHttp; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.RestClientModule; -@SuppressWarnings("rawtypes") +@SuppressWarnings("unchecked") @ConfiguresRestClient @RequiresHttp public class StubComputeServiceClientModule extends RestClientModule { diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java index cf4722921c..e14ad735f7 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java @@ -158,7 +158,7 @@ public class StubComputeServiceContextModule extends BaseComputeServiceContextMo } - @SuppressWarnings( { "rawtypes" }) + @SuppressWarnings("unchecked") @Override protected void configure() { bind(new TypeLiteral() { diff --git a/compute/src/main/java/org/jclouds/compute/util/ComputeServiceUtils.java b/compute/src/main/java/org/jclouds/compute/util/ComputeServiceUtils.java index 4dfc2f7d54..4ef27221cb 100644 --- a/compute/src/main/java/org/jclouds/compute/util/ComputeServiceUtils.java +++ b/compute/src/main/java/org/jclouds/compute/util/ComputeServiceUtils.java @@ -87,6 +87,20 @@ public class ComputeServiceUtils { return extractTargzIntoDirectory(new HttpRequest("GET", targz), directory); } + /** + * 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 extractZipIntoDirectory(HttpRequest zip, String directory) { + return Statements + .extractZipIntoDirectory(zip.getMethod(), zip.getEndpoint(), zip.getHeaders(), directory); + } + + public static Statement extractZipIntoDirectory(URI zip, String directory) { + return extractZipIntoDirectory(new HttpRequest("GET", zip), directory); + } + public static String parseTagFromName(String from) { Matcher matcher = DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX.matcher(from); return matcher.find() ? matcher.group(1) : "NOTAG-" + from; diff --git a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java index a87adaa868..4c2f0e0af6 100644 --- a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java +++ b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java @@ -40,20 +40,23 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.Constants; -import org.jclouds.compute.callables.AuthorizeRSAPublicKey; -import org.jclouds.compute.callables.InstallRSAPrivateKey; import org.jclouds.compute.callables.RunScriptOnNode; import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.options.RunScriptOptions; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.util.ComputeServiceUtils.SshCallable; -import org.jclouds.io.Payload; import org.jclouds.logging.Logger; import org.jclouds.net.IPSocket; import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey; +import org.jclouds.scriptbuilder.domain.InstallRSAPrivateKey; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.scriptbuilder.domain.StatementList; +import org.jclouds.ssh.ExecResponse; import org.jclouds.ssh.SshClient; import com.google.common.base.Predicate; @@ -136,35 +139,49 @@ public class ComputeUtils { throw new IllegalStateException(String.format( "node didn't achieve the state running on node %s within %d seconds, final state: %s", node.getId(), timeouts.nodeRunning / 1000, node.getState())); + List bootstrap = Lists.newArrayList(); + if (options.getRunScript() != null) + bootstrap.add(options.getRunScript()); + if (options.getPublicKey() != null) + bootstrap.add(new AuthorizeRSAPublicKey(options.getPublicKey())); + if (options.getPrivateKey() != null) + bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey())); + if (bootstrap.size() >0) + runScriptOnNode(node, new StatementList(bootstrap), options); + return node; + } - List> callables = Lists.newArrayList(); - if (options.getRunScript() != null) { - callables.add(runScriptOnNode(node, "runscript", options.getRunScript())); - } - if (options.getPublicKey() != null) { - callables.add(authorizeKeyOnNode(node, options.getPublicKey())); - } + public void checkNodeHasPublicIps(NodeMetadata node) { + checkState(node.getPublicAddresses().size() > 0, "node does not have IP addresses configured: " + node); + } - // changing the key "MUST" come last or else the other commands may - // fail. - if (callables.size() > 0 || options.getPrivateKey() != null) { - runCallablesOnNode(node, callables, options.getPrivateKey() != null ? installKeyOnNode(node, options - .getPrivateKey()) : null); + public ExecResponse runScriptOnNode(NodeMetadata node, Statement runScript, RunScriptOptions options) + { + RunScriptOnNode callable; + String taskName = options.getTaskName(); + ExecResponse response; + if (options.isRunAsRoot()) { + callable = runScriptOnNode(node, taskName, runScript); + } else + callable = runScriptOnNodeAsDefaultUser(node, taskName, runScript); + SshClient ssh = createSshClientOncePortIsListeningOnNode(node); + try { + ssh.connect(); + callable.setConnection(ssh, logger); + response = callable.call(); + } finally { + if (ssh != null) + ssh.disconnect(); } - if (options.getPort() > 0) { checkNodeHasPublicIps(node); blockUntilPortIsListeningOnPublicIp(options.getPort(), options.getSeconds(), Iterables.get(node .getPublicAddresses(), 0)); } - return node; + return response; } - private void checkNodeHasPublicIps(NodeMetadata node) { - checkState(node.getPublicAddresses().size() > 0, "node does not have IP addresses configured: " + node); - } - - private void blockUntilPortIsListeningOnPublicIp(int port, int seconds, String inetAddress) { + public void blockUntilPortIsListeningOnPublicIp(int port, int seconds, String inetAddress) { logger.debug(">> blocking on port %s:%d for %d seconds", inetAddress, port, seconds); RetryablePredicate tester = new RetryablePredicate(socketTester, seconds, 1, TimeUnit.SECONDS); IPSocket socket = new IPSocket(inetAddress, port); @@ -175,19 +192,11 @@ public class ComputeUtils { logger.warn("<< port %s:%d didn't open after %d seconds", inetAddress, port, seconds); } - public InstallRSAPrivateKey installKeyOnNode(NodeMetadata node, Payload privateKey) { - return new InstallRSAPrivateKey(node, privateKey); - } - - public AuthorizeRSAPublicKey authorizeKeyOnNode(NodeMetadata node, Payload publicKey) { - return new AuthorizeRSAPublicKey(node, publicKey); - } - - public RunScriptOnNode runScriptOnNode(NodeMetadata node, String scriptName, Payload script) { + public RunScriptOnNode runScriptOnNode(NodeMetadata node, String scriptName, Statement script) { return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script); } - public RunScriptOnNode runScriptOnNodeAsDefaultUser(NodeMetadata node, String scriptName, Payload script) { + public RunScriptOnNode runScriptOnNodeAsDefaultUser(NodeMetadata node, String scriptName, Statement script) { return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script, false); } diff --git a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java index 300de6c21a..6bd4dbe28e 100755 --- a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java @@ -320,9 +320,8 @@ public abstract class BaseComputeServiceLiveTest { private void refreshTemplate() { template = buildTemplate(client.templateBuilder()); - template.getOptions().installPrivateKey(newStringPayload(keyPair.get("private"))).authorizePublicKey( - newStringPayload(keyPair.get("public"))).runScript( - newStringPayload(buildScript(template.getImage().getOperatingSystem()))); + template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public")) + .runScript(newStringPayload(buildScript(template.getImage().getOperatingSystem()))); } protected void checkImageIdMatchesTemplate(NodeMetadata node) { @@ -362,7 +361,7 @@ public abstract class BaseComputeServiceLiveTest { Credentials creds) throws RunScriptOnNodesException { try { return client.runScriptOnNodesMatching(runningWithTag(tag), newStringPayload(buildScript(os)), - overrideCredentialsWith(creds)); + overrideCredentialsWith(creds).nameTask("runScriptWithCreds")); } catch (SshException e) { throw e; } @@ -606,7 +605,7 @@ public abstract class BaseComputeServiceLiveTest { ExecResponse hello = ssh.exec("echo hello"); assertEquals(hello.getOutput().trim(), "hello"); ExecResponse exec = ssh.exec("java -version"); - assert exec.getError().indexOf("OpenJDK") != -1 : exec; + assert exec.getError().indexOf("OpenJDK") != -1 || exec.getOutput().indexOf("OpenJDK") != -1 : exec; } finally { if (ssh != null) ssh.disconnect(); diff --git a/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java b/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java index ddb1417c22..603bd33232 100644 --- a/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java +++ b/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java @@ -19,7 +19,6 @@ package org.jclouds.compute; -import static com.google.common.base.Preconditions.checkNotNull; import static org.easymock.EasyMock.aryEq; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; @@ -48,9 +47,6 @@ import org.jclouds.net.IPSocket; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.SocketOpen; import org.jclouds.rest.RestContext; -import org.jclouds.scriptbuilder.InitBuilder; -import org.jclouds.scriptbuilder.domain.Statement; -import org.jclouds.scriptbuilder.domain.Statements; import org.jclouds.ssh.ExecResponse; import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshException; @@ -58,11 +54,8 @@ import org.jclouds.util.Utils; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import com.google.common.base.Splitter; import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; import com.google.inject.AbstractModule; import com.google.inject.Module; @@ -127,7 +120,12 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes .atLeastOnce(); client1.connect(); - runScript(client1, "computeserv", 1); + try { + runScript(client1, "runScriptWithCreds", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class + .getResourceAsStream("/runscript.sh")), 1); + } catch (IOException e) { + Throwables.propagate(e); + } client1.disconnect(); expect(factory.create(new IPSocket("144.175.1.2", 22), "root", "password2")).andReturn(client2) @@ -137,9 +135,9 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes expect(factory.create(new IPSocket("144.175.1.4", 22), "root", "password4")).andReturn(client4) .atLeastOnce(); - runScriptAndInstallSsh(client2, "runscript", 2); - runScriptAndInstallSsh(client3, "runscript", 3); - runScriptAndInstallSsh(client4, "runscript", 4); + runScriptAndInstallSsh(client2, "bootstrap", 2); + runScriptAndInstallSsh(client3, "bootstrap", 3); + runScriptAndInstallSsh(client4, "bootstrap", 4); expect( factory.create(eq(new IPSocket("144.175.1.1", 22)), eq("root"), aryEq(keyPair.get("private") @@ -171,24 +169,19 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes private void runScriptAndInstallSsh(SshClient client, String scriptName, int nodeId) { client.connect(); - runScript(client, scriptName, nodeId); - - expect(client.exec("mkdir .ssh")).andReturn(EXEC_GOOD); - expect(client.exec("cat .ssh/id_rsa.pub >> .ssh/authorized_keys")).andReturn(EXEC_GOOD); - expect(client.exec("chmod 600 .ssh/authorized_keys")).andReturn(EXEC_GOOD); - client.put(eq(".ssh/id_rsa.pub"), payloadEq(keyPair.get("public"))); - - expect(client.exec("mkdir .ssh")).andReturn(EXEC_GOOD); - client.put(eq(".ssh/id_rsa"), payloadEq(keyPair.get("private"))); - expect(client.exec("chmod 600 .ssh/id_rsa")).andReturn(EXEC_GOOD); + try { + runScript(client, scriptName, Utils.toStringAndClose(StubComputeServiceIntegrationTest.class + .getResourceAsStream("/initscript_with_keys.sh")), nodeId); + } catch (IOException e) { + Throwables.propagate(e); + } client.disconnect(); } - private void runScript(SshClient client, String scriptName, int nodeId) { - client.put(eq("" + scriptName + ""), payloadEq(initScript(scriptName, - BaseComputeServiceLiveTest.APT_RUN_SCRIPT))); + private void runScript(SshClient client, String scriptName, String script, int nodeId) { + client.put(eq("" + scriptName + ""), payloadEq(script)); expect(client.exec("chmod 755 " + scriptName + "")).andReturn(EXEC_GOOD); expect(client.getUsername()).andReturn("root").atLeastOnce(); expect(client.getHostAddress()).andReturn(nodeId + "").atLeastOnce(); @@ -223,13 +216,6 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes // TODO: this fails so we override it. } - public static String initScript(String scriptName, String script) { - return new InitBuilder(scriptName, "/tmp/" + scriptName, "/tmp/" + scriptName, - ImmutableMap. of(), ImmutableList. of(Statements.interpret(Iterables.toArray( - Splitter.on("\n").split(new String(checkNotNull(script, "script"))), String.class)))) - .build(org.jclouds.scriptbuilder.domain.OsFamily.UNIX); - } - public static Payload payloadEq(String value) { reportMatcher(new PayloadEquals(value)); return null; @@ -257,10 +243,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes } try { String real = Utils.toStringAndClose(((Payload) actual).getInput()); - if (!expected.equals(real)) { - System.err.println(real); - return false; - } + assertEquals(real, expected); return true; } catch (IOException e) { Throwables.propagate(e); diff --git a/compute/src/test/java/org/jclouds/compute/options/TemplateOptionsTest.java b/compute/src/test/java/org/jclouds/compute/options/TemplateOptionsTest.java index 2c6f1c21bb..eb22319bd5 100755 --- a/compute/src/test/java/org/jclouds/compute/options/TemplateOptionsTest.java +++ b/compute/src/test/java/org/jclouds/compute/options/TemplateOptionsTest.java @@ -28,7 +28,6 @@ import static org.testng.Assert.assertEquals; import java.io.IOException; -import org.jclouds.util.Utils; import org.testng.annotations.Test; /** @@ -37,19 +36,17 @@ import org.testng.annotations.Test; * @author Adrian Cole */ public class TemplateOptionsTest { - @SuppressWarnings("deprecation") @Test(expectedExceptions = IllegalArgumentException.class) public void testinstallPrivateKeyBadFormat() { TemplateOptions options = new TemplateOptions(); options.installPrivateKey("whompy"); } - @SuppressWarnings("deprecation") @Test public void testinstallPrivateKey() throws IOException { TemplateOptions options = new TemplateOptions(); options.installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); - assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); } @Test @@ -62,7 +59,7 @@ public class TemplateOptionsTest { @Test public void testinstallPrivateKeyStatic() throws IOException { TemplateOptions options = installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); - assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); } @SuppressWarnings("deprecation") @@ -71,7 +68,6 @@ public class TemplateOptionsTest { installPrivateKey((String) null); } - @SuppressWarnings("deprecation") @Test(expectedExceptions = IllegalArgumentException.class) public void testauthorizePublicKeyBadFormat() { TemplateOptions options = new TemplateOptions(); @@ -79,11 +75,10 @@ public class TemplateOptionsTest { } @Test - @SuppressWarnings("deprecation") public void testauthorizePublicKey() throws IOException { TemplateOptions options = new TemplateOptions(); options.authorizePublicKey("ssh-rsa"); - assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); } @Test @@ -96,7 +91,7 @@ public class TemplateOptionsTest { @Test public void testauthorizePublicKeyStatic() throws IOException { TemplateOptions options = authorizePublicKey("ssh-rsa"); - assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); } @SuppressWarnings("deprecation") diff --git a/compute/src/test/resources/initscript_with_keys.sh b/compute/src/test/resources/initscript_with_keys.sh new file mode 100644 index 0000000000..ac11ffa738 --- /dev/null +++ b/compute/src/test/resources/initscript_with_keys.sh @@ -0,0 +1,136 @@ +#!/bin/bash +set +u +shopt -s xpg_echo +shopt -s expand_aliases +unset PATH JAVA_HOME LD_LIBRARY_PATH +function abort { + echo "aborting: $@" 1>&2 + exit 1 +} +function default { + export INSTANCE_NAME="bootstrap" +export INSTANCE_HOME="/tmp/bootstrap" +export LOG_DIR="/tmp/bootstrap" + return 0 +} +function bootstrap { + return 0 +} +function findPid { + unset FOUND_PID; + [ $# -eq 1 ] || { + abort "findPid requires a parameter of pattern to match" + return 1 + } + local PATTERN="$1"; shift + local _FOUND=`ps auxwww|grep "$PATTERN"|grep -v " $0"|grep -v grep|awk '{print $2}'` + [ -n "$_FOUND" ] && { + export FOUND_PID=$_FOUND + return 0 + } || { + return 1 + } +} +function forget { + unset FOUND_PID; + [ $# -eq 3 ] || { + abort "forget requires parameters INSTANCE_NAME SCRIPT LOG_DIR" + return 1 + } + local INSTANCE_NAME="$1"; shift + local SCRIPT="$1"; shift + local LOG_DIR="$1"; shift + mkdir -p $LOG_DIR + findPid $INSTANCE_NAME + [ -n "$FOUND_PID" ] && { + echo $INSTANCE_NAME already running pid [$FOUND_PID] + } || { + nohup $SCRIPT >$LOG_DIR/stdout.log 2>$LOG_DIR/stderr.log & + sleep 1 + findPid $INSTANCE_NAME + [ -n "$FOUND_PID" ] || abort "$INSTANCE_NAME did not start" + } + return 0 +} +export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin +case $1 in +init) + default || exit 1 + bootstrap || exit 1 + mkdir -p $INSTANCE_HOME + + # create runscript header + cat > $INSTANCE_HOME/bootstrap.sh <> $INSTANCE_HOME/bootstrap.sh <<'END_OF_SCRIPT' +cd $INSTANCE_HOME +echo nameserver 208.67.222.222 >> /etc/resolv.conf +cp /etc/apt/sources.list /etc/apt/sources.list.old +sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list +apt-get update +apt-get install -f -y --force-yes openjdk-6-jdk + +mkdir -p .ssh +cat >> .ssh/authorized_keys <<'END_OF_FILE' +ssh-rsa +END_OF_FILE +chmod 600 .ssh/authorized_keys +mkdir -p .ssh +rm .ssh/id_rsa +cat >> .ssh/id_rsa <<'END_OF_FILE' +-----BEGIN RSA PRIVATE KEY----- +END_OF_FILE +chmod 600 .ssh/id_rsa + +END_OF_SCRIPT + + # add runscript footer + cat >> $INSTANCE_HOME/bootstrap.sh <<'END_OF_SCRIPT' +exit 0 +END_OF_SCRIPT + + chmod u+x $INSTANCE_HOME/bootstrap.sh + ;; +status) + default || exit 1 + findPid $INSTANCE_NAME || exit 1 + echo [$FOUND_PID] + ;; +stop) + default || exit 1 + findPid $INSTANCE_NAME || exit 1 + [ -n "$FOUND_PID" ] && { + echo stopping $FOUND_PID + kill -9 $FOUND_PID + } + ;; +start) + default || exit 1 + forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1 + ;; +tail) + default || exit 1 + tail $LOG_DIR/stdout.log + ;; +tailerr) + default || exit 1 + tail $LOG_DIR/stderr.log + ;; +run) + default || exit 1 + $INSTANCE_HOME/$INSTANCE_NAME.sh + ;; +esac +exit 0 diff --git a/compute/src/test/resources/runscript.sh b/compute/src/test/resources/runscript.sh new file mode 100644 index 0000000000..a23d1c38fd --- /dev/null +++ b/compute/src/test/resources/runscript.sh @@ -0,0 +1,125 @@ +#!/bin/bash +set +u +shopt -s xpg_echo +shopt -s expand_aliases +unset PATH JAVA_HOME LD_LIBRARY_PATH +function abort { + echo "aborting: $@" 1>&2 + exit 1 +} +function default { + export INSTANCE_NAME="runScriptWithCreds" +export INSTANCE_HOME="/tmp/runScriptWithCreds" +export LOG_DIR="/tmp/runScriptWithCreds" + return 0 +} +function runScriptWithCreds { + return 0 +} +function findPid { + unset FOUND_PID; + [ $# -eq 1 ] || { + abort "findPid requires a parameter of pattern to match" + return 1 + } + local PATTERN="$1"; shift + local _FOUND=`ps auxwww|grep "$PATTERN"|grep -v " $0"|grep -v grep|awk '{print $2}'` + [ -n "$_FOUND" ] && { + export FOUND_PID=$_FOUND + return 0 + } || { + return 1 + } +} +function forget { + unset FOUND_PID; + [ $# -eq 3 ] || { + abort "forget requires parameters INSTANCE_NAME SCRIPT LOG_DIR" + return 1 + } + local INSTANCE_NAME="$1"; shift + local SCRIPT="$1"; shift + local LOG_DIR="$1"; shift + mkdir -p $LOG_DIR + findPid $INSTANCE_NAME + [ -n "$FOUND_PID" ] && { + echo $INSTANCE_NAME already running pid [$FOUND_PID] + } || { + nohup $SCRIPT >$LOG_DIR/stdout.log 2>$LOG_DIR/stderr.log & + sleep 1 + findPid $INSTANCE_NAME + [ -n "$FOUND_PID" ] || abort "$INSTANCE_NAME did not start" + } + return 0 +} +export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin +case $1 in +init) + default || exit 1 + runScriptWithCreds || exit 1 + mkdir -p $INSTANCE_HOME + + # create runscript header + cat > $INSTANCE_HOME/runScriptWithCreds.sh <> $INSTANCE_HOME/runScriptWithCreds.sh <<'END_OF_SCRIPT' +cd $INSTANCE_HOME +echo nameserver 208.67.222.222 >> /etc/resolv.conf +cp /etc/apt/sources.list /etc/apt/sources.list.old +sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list +apt-get update +apt-get install -f -y --force-yes openjdk-6-jdk + + +END_OF_SCRIPT + + # add runscript footer + cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<'END_OF_SCRIPT' +exit 0 +END_OF_SCRIPT + + chmod u+x $INSTANCE_HOME/runScriptWithCreds.sh + ;; +status) + default || exit 1 + findPid $INSTANCE_NAME || exit 1 + echo [$FOUND_PID] + ;; +stop) + default || exit 1 + findPid $INSTANCE_NAME || exit 1 + [ -n "$FOUND_PID" ] && { + echo stopping $FOUND_PID + kill -9 $FOUND_PID + } + ;; +start) + default || exit 1 + forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1 + ;; +tail) + default || exit 1 + tail $LOG_DIR/stdout.log + ;; +tailerr) + default || exit 1 + tail $LOG_DIR/stderr.log + ;; +run) + default || exit 1 + $INSTANCE_HOME/$INSTANCE_NAME.sh + ;; +esac +exit 0 diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/ScriptBuilder.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/ScriptBuilder.java index 0e67755181..ce892106d4 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/ScriptBuilder.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/ScriptBuilder.java @@ -32,6 +32,7 @@ import org.jclouds.scriptbuilder.util.Utils; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -41,7 +42,7 @@ import com.google.common.collect.Maps; * * @author Adrian Cole */ -public class ScriptBuilder { +public class ScriptBuilder implements Statement { @VisibleForTesting List statements = Lists.newArrayList(); @@ -69,8 +70,7 @@ public class ScriptBuilder { * Exports a variable inside the script */ public ScriptBuilder addEnvironmentVariableScope(String scopeName, Map variables) { - variableScopes - .put(checkNotNull(scopeName, "scopeName"), checkNotNull(variables, "variables")); + variableScopes.put(checkNotNull(scopeName, "scopeName"), checkNotNull(variables, "variables")); return this; } @@ -85,19 +85,21 @@ public class ScriptBuilder { * @param osFamily * whether to write a cmd or bash script. */ - public String build(final OsFamily osFamily) { + + @Override + public String render(OsFamily osFamily) { Map functions = Maps.newLinkedHashMap(); functions.put("abort", Utils.writeFunctionFromResource("abort", osFamily)); for (Entry> entry : variableScopes.entrySet()) { - functions.put(entry.getKey(), Utils.writeFunction(entry.getKey(), Utils - .writeVariableExporters(entry.getValue()))); + functions.put(entry.getKey(), Utils.writeFunction(entry.getKey(), Utils.writeVariableExporters(entry + .getValue()))); } final Map tokenValueMap = ShellToken.tokenValueMap(osFamily); StringBuilder builder = new StringBuilder(); builder.append(ShellToken.BEGIN_SCRIPT.to(osFamily)); - builder.append(Utils.writeUnsetVariables(Lists.newArrayList(Iterables.transform( - variablesToUnset, new Function() { + builder.append(Utils.writeUnsetVariables(Lists.newArrayList(Iterables.transform(variablesToUnset, + new Function() { @Override public String apply(String from) { if (tokenValueMap.containsKey(from + "Variable")) @@ -141,4 +143,9 @@ public class ScriptBuilder { functions.put(functionName, Utils.writeFunctionFromResource(functionName, osFamily)); } } + + @Override + public Iterable functionDependecies(OsFamily family) { + return ImmutableSet. of(); + } } \ No newline at end of file diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateFile.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AppendFile.java similarity index 93% rename from scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateFile.java rename to scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AppendFile.java index bb4606f928..c97009eaaa 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateFile.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AppendFile.java @@ -39,12 +39,12 @@ import com.google.common.collect.Maps; * * @author Adrian Cole */ -public class CreateFile implements Statement { +public class AppendFile implements Statement { public final static String MARKER = "END_OF_FILE"; final String path; final Iterable lines; - public CreateFile(String path, Iterable lines) {// TODO: convert so + public AppendFile(String path, Iterable lines) {// TODO: convert so this.path = checkNotNull(path, "path"); this.lines = checkNotNull(lines, "lines"); checkState(Iterables.size(lines) > 0, "you must pass something to execute"); @@ -77,7 +77,6 @@ public class CreateFile implements Statement { hereFile(path, builder); statements.add(interpret(builder.toString())); } else { - statements.add(interpret(String.format("{rm} %s 2{closeFd}{lf}", path))); for (String line : lines) { statements.add(appendToFile(line, path, family)); } @@ -86,7 +85,7 @@ public class CreateFile implements Statement { } private void hereFile(String path, StringBuilder builder) { - builder.append("cat > ").append(path).append(" <<'").append(MARKER).append("'\n"); + builder.append("cat >> ").append(path).append(" <<'").append(MARKER).append("'\n"); for (String line : lines) { builder.append(line).append("\n"); } diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java new file mode 100644 index 0000000000..dbcc168b7a --- /dev/null +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java @@ -0,0 +1,56 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.scriptbuilder.domain; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.scriptbuilder.domain.Statements.appendFile; +import static org.jclouds.scriptbuilder.domain.Statements.exec; + +import java.util.Collections; + +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; + +/** + * + * @author Adrian Cole + */ +public class AuthorizeRSAPublicKey implements Statement { + + private final String publicKey; + + public AuthorizeRSAPublicKey(String publicKey) { + this.publicKey = checkNotNull(publicKey, "publicKey"); + } + + @Override + public Iterable functionDependecies(OsFamily family) { + return Collections.emptyList(); + } + + @Override + public String render(OsFamily family) { + checkNotNull(family, "family"); + if (family == OsFamily.WINDOWS) + throw new UnsupportedOperationException("windows not yet implemented"); + return new StatementList(ImmutableList.of(exec("{md} .ssh"), appendFile(".ssh/authorized_keys", Splitter.on('\n') + .split(publicKey)), exec("chmod 600 .ssh/authorized_keys"))).render(family); + } +} \ No newline at end of file diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java new file mode 100644 index 0000000000..78763e5ec2 --- /dev/null +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java @@ -0,0 +1,57 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.scriptbuilder.domain; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.scriptbuilder.domain.Statements.appendFile; +import static org.jclouds.scriptbuilder.domain.Statements.exec; +import static org.jclouds.scriptbuilder.domain.Statements.rm; + +import java.util.Collections; + +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; + +/** + * + * @author Adrian Cole + */ +public class InstallRSAPrivateKey implements Statement { + + private final String privateKey; + + public InstallRSAPrivateKey(String privateKey) { + this.privateKey = checkNotNull(privateKey, "privateKey"); + } + + @Override + public Iterable functionDependecies(OsFamily family) { + return Collections.emptyList(); + } + + @Override + public String render(OsFamily family) { + checkNotNull(family, "family"); + if (family == OsFamily.WINDOWS) + throw new UnsupportedOperationException("windows not yet implemented"); + return new StatementList(ImmutableList.of(exec("{md} .ssh"), rm(".ssh/id_rsa"), appendFile(".ssh/id_rsa", Splitter.on('\n') + .split(privateKey)), exec("chmod 600 .ssh/id_rsa"))).render(family); + } +} \ No newline at end of file diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SaveHttpResponseTo.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SaveHttpResponseTo.java new file mode 100644 index 0000000000..0e56dcf611 --- /dev/null +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SaveHttpResponseTo.java @@ -0,0 +1,59 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.scriptbuilder.domain; + +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; + +/** + * saves the content of the http response to a file + * + * @author Adrian Cole + */ +public class SaveHttpResponseTo extends InterpretableStatement { + /** + * + * @param dir + * location to save file + * @param method + * http method: ex GET + * @param endpoint + * uri corresponding to the request + * @param headers + * request headers to send + */ + public SaveHttpResponseTo(String dir, String file, String method, URI endpoint, Multimap headers) { + super(String.format("({md} %s &&{cd} %s &&curl -X %s -s --retry 20 %s %s >%s\n", dir, dir, method, Joiner.on(' ') + .join(Iterables.transform(headers.entries(), new Function, String>() { + + @Override + public String apply(Entry from) { + return String.format("-H \"%s: %s\"", from.getKey(), from.getValue()); + } + + })), endpoint.toASCIIString(), file)); + } + +} \ No newline at end of file diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/Statements.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/Statements.java index ebf7207d73..63d856745d 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/Statements.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/Statements.java @@ -22,6 +22,7 @@ package org.jclouds.scriptbuilder.domain; import java.net.URI; import java.util.Map; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; /** @@ -40,12 +41,31 @@ public class Statements { return new SwitchArg(arg, valueToActions); } + public static Statement rm(final String path) { + return new Statement() { + + @Override + public Iterable functionDependecies(OsFamily family) { + return ImmutableList.of(); + } + + @Override + public String render(OsFamily family) { + if (family == OsFamily.WINDOWS) + return exec(String.format("{rm} %s 2{closeFd}", path)).render(family); + else + return exec(String.format("{rm} %s", path)).render(family); + } + + }; + } + public static Statement call(String function, String... args) { return new Call(function, args); } - public static Statement createFile(String path, Iterable lines) { - return new CreateFile(path, lines); + public static Statement appendFile(String path, Iterable lines) { + return new AppendFile(path, lines); } public static Statement createRunScript(String instanceName, Iterable exports, String pwd, @@ -120,10 +140,27 @@ public class Statements { * uri corresponding to the request * @param headers * request headers to send + * @param directory */ public static Statement extractTargzIntoDirectory(String method, URI endpoint, Multimap headers, String directory) { - return new PipeHttpResponseToTarxpzfIntoDirectory( method, endpoint, headers,directory); + return new PipeHttpResponseToTarxpzfIntoDirectory(method, endpoint, headers, directory); + } + + /** + * unzip 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 + * @param directory + */ + public static Statement extractZipIntoDirectory(String method, URI endpoint, Multimap headers, + String directory) { + return new UnzipHttpResponseIntoDirectory(method, endpoint, headers, directory); } /** diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SwitchArg.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SwitchArg.java index abf59d0648..3abca9a381 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SwitchArg.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SwitchArg.java @@ -99,7 +99,7 @@ public class SwitchArg implements Statement { inRunScript = inRunScript ? false : true; } - if (line.indexOf(CreateFile.MARKER) != -1) { + if (line.indexOf(AppendFile.MARKER) != -1) { inCreateFile = inCreateFile ? false : true; } shouldIndent = !inCreateFile && !inRunScript; diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectory.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectory.java new file mode 100644 index 0000000000..fe89f829cc --- /dev/null +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectory.java @@ -0,0 +1,62 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.scriptbuilder.domain; + +import static com.google.common.collect.Iterables.transform; +import static java.lang.String.format; + +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.Multimap; + +/** + * unzips the content into a directory + * + * @author Adrian Cole + */ +public class UnzipHttpResponseIntoDirectory extends InterpretableStatement { + /** + * + * + * @param method + * http method: ex GET + * @param endpoint + * uri corresponding to the request + * @param headers + * request headers to send + */ + public UnzipHttpResponseIntoDirectory(String method, URI endpoint, Multimap headers, String dir) { + super( + format( + "({md} %s &&{cd} %s &&curl -X %s -s --retry 20 %s %s >extract.zip && unzip -qq extract.zip&& rm extract.zip)\n", + dir, dir, method, Joiner.on(' ').join( + transform(headers.entries(), new Function, String>() { + + @Override + public String apply(Entry from) { + return String.format("-H \"%s: %s\"", from.getKey(), from.getValue()); + } + + })), endpoint.toASCIIString())); + } +} \ No newline at end of file diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/InitBuilderTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/InitBuilderTest.java index dc2f90c824..e7535692cf 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/InitBuilderTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/InitBuilderTest.java @@ -20,7 +20,7 @@ package org.jclouds.scriptbuilder; import static org.jclouds.scriptbuilder.domain.Statements.call; -import static org.jclouds.scriptbuilder.domain.Statements.createFile; +import static org.jclouds.scriptbuilder.domain.Statements.appendFile; import static org.testng.Assert.assertEquals; import java.io.IOException; @@ -47,17 +47,17 @@ public class InitBuilderTest { InitBuilder testInitBuilder = new InitBuilder("mkebsboot", "/mnt/tmp", "/mnt/tmp", ImmutableMap.of("tmpDir", "/mnt/tmp"), ImmutableList. of( - createFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", ImmutableList. of("hello world")), call("find /"))); + appendFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", ImmutableList. of("hello world")), call("find /"))); @Test public void testBuildSimpleWindows() throws MalformedURLException, IOException { - assertEquals(testInitBuilder.build(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier(Resources + assertEquals(testInitBuilder.render(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier(Resources .getResource("test_init." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); } @Test public void testBuildSimpleUNIX() throws MalformedURLException, IOException { - assertEquals(testInitBuilder.build(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources + assertEquals(testInitBuilder.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources .getResource("test_init." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } @@ -87,7 +87,7 @@ public class InitBuilderTest { "tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}", "echo size of ebs", "du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source", "du -sk {varl}IMAGE_DIR{varr}", "rm -rf {varl}IMAGE_DIR{varr}/*", "umount {varl}EBS_MOUNT_POINT{varr}", "echo ----COMPLETE----") - )).build(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources + )).render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources .getResource("test_ebs." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } } diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/ScriptBuilderTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/ScriptBuilderTest.java index 9fea9578ba..31f05f6911 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/ScriptBuilderTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/ScriptBuilderTest.java @@ -20,7 +20,7 @@ package org.jclouds.scriptbuilder; import static org.jclouds.scriptbuilder.domain.Statements.call; -import static org.jclouds.scriptbuilder.domain.Statements.createFile; +import static org.jclouds.scriptbuilder.domain.Statements.appendFile; import static org.jclouds.scriptbuilder.domain.Statements.findPid; import static org.jclouds.scriptbuilder.domain.Statements.interpret; import static org.jclouds.scriptbuilder.domain.Statements.kill; @@ -65,19 +65,19 @@ public class ScriptBuilderTest { interpret("echo stop {varl}RUNTIME{varr}{lf}")), "status", newStatementList( - createFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", + appendFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", ImmutableList. of("hello world")), interpret("echo {vq}the following should be []: [{varl}RUNTIME{varr}]{vq}{lf}"))))); @Test public void testBuildSimpleWindows() throws MalformedURLException, IOException { - assertEquals(testScriptBuilder.build(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier( + assertEquals(testScriptBuilder.render(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier( Resources.getResource("test_script." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); } @Test public void testBuildSimpleUNIX() throws MalformedURLException, IOException { - assertEquals(testScriptBuilder.build(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources + assertEquals(testScriptBuilder.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources .getResource("test_script." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } @@ -86,13 +86,13 @@ public class ScriptBuilderTest { @Test public void testFindPidWindows() throws MalformedURLException, IOException { - assertEquals(findPidBuilder.build(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier(Resources + assertEquals(findPidBuilder.render(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier(Resources .getResource("test_find_pid." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); } @Test public void testFindPidUNIX() throws MalformedURLException, IOException { - assertEquals(findPidBuilder.build(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources + assertEquals(findPidBuilder.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources .getResource("test_find_pid." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } @@ -100,13 +100,13 @@ public class ScriptBuilderTest { @Test public void testSeekAndDestroyWindows() throws MalformedURLException, IOException { - assertEquals(seekAndDestroyBuilder.build(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier( + assertEquals(seekAndDestroyBuilder.render(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier( Resources.getResource("test_seek_and_destroy." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); } @Test public void testSeekAndDestroyUNIX() throws MalformedURLException, IOException { - assertEquals(seekAndDestroyBuilder.build(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier( + assertEquals(seekAndDestroyBuilder.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier( Resources.getResource("test_seek_and_destroy." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateFileTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/AppendFileTest.java similarity index 80% rename from scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateFileTest.java rename to scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/AppendFileTest.java index 463e8d68e0..bc37c12165 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateFileTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/AppendFileTest.java @@ -19,7 +19,7 @@ package org.jclouds.scriptbuilder.domain; -import static org.jclouds.scriptbuilder.domain.Statements.createFile; +import static org.jclouds.scriptbuilder.domain.Statements.appendFile; import static org.testng.Assert.assertEquals; import java.io.IOException; @@ -34,9 +34,9 @@ import com.google.common.io.Resources; /** * @author Adrian Cole */ -@Test(groups = "unit", testName = "scriptbuilder.CreateFileTest") -public class CreateFileTest { - Statement statement = createFile("{root}etc{fs}chef{fs}client.rb", ImmutableList.of("log_level :info", +@Test(groups = "unit", testName = "scriptbuilder.AppendFileTest") +public class AppendFileTest { + Statement statement = appendFile("{root}etc{fs}chef{fs}client.rb", ImmutableList.of("log_level :info", "log_location STDOUT", String.format("chef_server_url \"%s\"", "http://localhost:4000"))); public void testUNIX() throws IOException { @@ -50,10 +50,10 @@ public class CreateFileTest { } public void testRedirectGuard() { - assertEquals(CreateFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo>>"), "foo>>"); - assertEquals(CreateFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo0>>"), "foo0 >>"); - assertEquals(CreateFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo1>>"), "foo1 >>"); - assertEquals(CreateFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo2>>"), "foo2 >>"); + assertEquals(AppendFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo>>"), "foo>>"); + assertEquals(AppendFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo0>>"), "foo0 >>"); + assertEquals(AppendFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo1>>"), "foo1 >>"); + assertEquals(AppendFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo2>>"), "foo2 >>"); } } diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CopyOfAuthorizeRSAPublicKeyTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CopyOfAuthorizeRSAPublicKeyTest.java new file mode 100644 index 0000000000..68b6d4a35f --- /dev/null +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CopyOfAuthorizeRSAPublicKeyTest.java @@ -0,0 +1,43 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.scriptbuilder.domain; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "scriptbuilder.AuthorizeRSAPublicKeyTest") +public class CopyOfAuthorizeRSAPublicKeyTest { + + AuthorizeRSAPublicKey auth = new AuthorizeRSAPublicKey("ssh-dss AAAAB"); + + public void testAuthorizeRSAPublicKeyUNIX() { + assertEquals( + auth.render(OsFamily.UNIX), + "mkdir -p .ssh\ncat >> .ssh/authorized_keys <<'END_OF_FILE'\nssh-dss AAAAB\nEND_OF_FILE\nchmod 600 .ssh/authorized_keys\n"); } + + @Test(expectedExceptions = UnsupportedOperationException.class) + public void testAuthorizeRSAPublicKeyWINDOWS() { + auth.render(OsFamily.WINDOWS); + } +} diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateRunScriptTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateRunScriptTest.java index 9f5817deba..beccda495d 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateRunScriptTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateRunScriptTest.java @@ -20,7 +20,7 @@ package org.jclouds.scriptbuilder.domain; import static org.jclouds.scriptbuilder.domain.Statements.call; -import static org.jclouds.scriptbuilder.domain.Statements.createFile; +import static org.jclouds.scriptbuilder.domain.Statements.appendFile; import static org.jclouds.scriptbuilder.domain.Statements.createRunScript; import static org.testng.Assert.assertEquals; @@ -45,7 +45,7 @@ public class CreateRunScriptTest { ImmutableList . of( call("echo hello"), - createFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", ImmutableList + appendFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", ImmutableList . of("hello world")), call("echo {varl}JAVA_HOME{varr}{fs}bin{fs}java -DinstanceName={varl}INSTANCE_NAME{varr} myServer.Main"))); diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKeyTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKeyTest.java new file mode 100644 index 0000000000..9775282f4a --- /dev/null +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKeyTest.java @@ -0,0 +1,44 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.scriptbuilder.domain; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "scriptbuilder.InstallRSAPrivateKeyTest") +public class InstallRSAPrivateKeyTest { + + InstallRSAPrivateKey key = new InstallRSAPrivateKey("-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n"); + + public void testInstallRSAPrivateKeyUNIX() { + assertEquals( + key.render(OsFamily.UNIX), + "mkdir -p .ssh\nrm .ssh/id_rsa\ncat >> .ssh/id_rsa <<'END_OF_FILE'\n-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n\nEND_OF_FILE\nchmod 600 .ssh/id_rsa\n"); + } + + @Test(expectedExceptions = UnsupportedOperationException.class) + public void testInstallRSAPrivateKeyWINDOWS() { + key.render(OsFamily.WINDOWS); + } +} diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/SwitchArgTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/SwitchArgTest.java index 616a8dd9b0..bf19331232 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/SwitchArgTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/SwitchArgTest.java @@ -19,7 +19,7 @@ package org.jclouds.scriptbuilder.domain; -import static org.jclouds.scriptbuilder.domain.Statements.createFile; +import static org.jclouds.scriptbuilder.domain.Statements.appendFile; import static org.jclouds.scriptbuilder.domain.Statements.interpret; import static org.jclouds.scriptbuilder.domain.Statements.newStatementList; import static org.testng.Assert.assertEquals; @@ -37,10 +37,10 @@ import com.google.common.collect.ImmutableMap; public class SwitchArgTest { public void testSwitchArgUNIX() { - assertEquals(new SwitchArg(1, ImmutableMap.of("0", newStatementList(createFile( + assertEquals(new SwitchArg(1, ImmutableMap.of("0", newStatementList(appendFile( "{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", Collections.singleton("hello world")), interpret("echo hello zero{lf}")), "1", interpret("echo hello one{lf}"))).render(OsFamily.UNIX), - "case $1 in\n0)\n cat > /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE'\nhello world\nEND_OF_FILE\n echo hello zero\n ;;\n1)\n echo hello one\n ;;\nesac\n"); + "case $1 in\n0)\n cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE'\nhello world\nEND_OF_FILE\n echo hello zero\n ;;\n1)\n echo hello one\n ;;\nesac\n"); } public void testSwitchArgWindows() { diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectoryToTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectoryToTest.java new file mode 100644 index 0000000000..63afb46cf7 --- /dev/null +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectoryToTest.java @@ -0,0 +1,50 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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.UnzipHttpResponseIntoDirectoryToTest") +public class UnzipHttpResponseIntoDirectoryToTest { + + UnzipHttpResponseIntoDirectory jboss = new UnzipHttpResponseIntoDirectory( + "GET", + URI + .create("http://superb-sea2.dl.sourceforge.net/project/jboss/JBoss/JBoss-5.0.0.CR2/jboss-5.0.0.CR2-jdk6.zip"), + ImmutableMultimap. of(), "/tmp"); + + public void testUnzipHttpResponseIntoDirectoryUNIX() { + assertEquals( + jboss.render(OsFamily.UNIX), + "(mkdir -p /tmp &&cd /tmp &&curl -X GET -s --retry 20 http://superb-sea2.dl.sourceforge.net/project/jboss/JBoss/JBoss-5.0.0.CR2/jboss-5.0.0.CR2-jdk6.zip >extract.zip && unzip -qq extract.zip&& rm extract.zip)\n"); + } + public void testUnzipHttpResponseIntoDirectoryWINDOWS() { + + jboss.render(OsFamily.WINDOWS); } +} diff --git a/scriptbuilder/src/test/resources/client_rb.cmd b/scriptbuilder/src/test/resources/client_rb.cmd index b3a2b4aa03..d7bd4e6ddf 100644 --- a/scriptbuilder/src/test/resources/client_rb.cmd +++ b/scriptbuilder/src/test/resources/client_rb.cmd @@ -1,4 +1,3 @@ -del c:\etc\chef\client.rb 2>NUL echo log_level :info>>c:\etc\chef\client.rb echo log_location STDOUT>>c:\etc\chef\client.rb echo chef_server_url "http://localhost:4000">>c:\etc\chef\client.rb diff --git a/scriptbuilder/src/test/resources/client_rb.sh b/scriptbuilder/src/test/resources/client_rb.sh index cca52f5638..f0522fbfa9 100755 --- a/scriptbuilder/src/test/resources/client_rb.sh +++ b/scriptbuilder/src/test/resources/client_rb.sh @@ -1,4 +1,4 @@ -cat > /etc/chef/client.rb <<'END_OF_FILE' +cat >> /etc/chef/client.rb <<'END_OF_FILE' log_level :info log_location STDOUT chef_server_url "http://localhost:4000" diff --git a/scriptbuilder/src/test/resources/test_init.sh b/scriptbuilder/src/test/resources/test_init.sh index 87d5738697..049824a311 100755 --- a/scriptbuilder/src/test/resources/test_init.sh +++ b/scriptbuilder/src/test/resources/test_init.sh @@ -78,7 +78,7 @@ END_OF_SCRIPT # add desired commands from the user cat >> $INSTANCE_HOME/mkebsboot.sh <<'END_OF_SCRIPT' cd $INSTANCE_HOME -cat > /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE' +cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE' hello world END_OF_FILE diff --git a/scriptbuilder/src/test/resources/test_runrun.sh b/scriptbuilder/src/test/resources/test_runrun.sh index 1ec3307e46..54ce111083 100644 --- a/scriptbuilder/src/test/resources/test_runrun.sh +++ b/scriptbuilder/src/test/resources/test_runrun.sh @@ -17,7 +17,7 @@ cat >> /tmp/$USER/scripttest/yahooprod.sh <<'END_OF_SCRIPT' cd /tmp/$USER/scripttest echo hello || return 1 -cat > /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE' +cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE' hello world END_OF_FILE diff --git a/scriptbuilder/src/test/resources/test_script.cmd b/scriptbuilder/src/test/resources/test_script.cmd index b69d2518c3..0c20094c76 100644 --- a/scriptbuilder/src/test/resources/test_script.cmd +++ b/scriptbuilder/src/test/resources/test_script.cmd @@ -28,7 +28,6 @@ goto CASE_%1 echo stop %RUNTIME% GOTO END_SWITCH :CASE_status - del %TEMP%\%USERNAME%\scripttest\temp.txt 2>NUL echo hello world>>%TEMP%\%USERNAME%\scripttest\temp.txt echo the following should be []: [%RUNTIME%] GOTO END_SWITCH diff --git a/scriptbuilder/src/test/resources/test_script.sh b/scriptbuilder/src/test/resources/test_script.sh index 97a4422dc5..5fde6790b1 100644 --- a/scriptbuilder/src/test/resources/test_script.sh +++ b/scriptbuilder/src/test/resources/test_script.sh @@ -22,7 +22,7 @@ stop) echo stop $RUNTIME ;; status) - cat > /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE' + cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE' hello world END_OF_FILE echo "the following should be []: [$RUNTIME]" diff --git a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java index 7754296c82..357b1a8cb0 100644 --- a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java +++ b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java @@ -98,6 +98,8 @@ public class ComputeTask extends Task { invokeActionOnService(act, context.getComputeService()); } catch (RunNodesException e) { throw new BuildException(e); + } catch (IOException e) { + throw new BuildException(e); } } } finally { @@ -105,7 +107,7 @@ public class ComputeTask extends Task { } } - private void invokeActionOnService(Action action, ComputeService computeService) throws RunNodesException { + private void invokeActionOnService(Action action, ComputeService computeService) throws RunNodesException, IOException { switch (action) { case CREATE: case GET: @@ -191,7 +193,7 @@ public class ComputeTask extends Task { } } - private void create(ComputeService computeService) throws RunNodesException { + private void create(ComputeService computeService) throws RunNodesException, IOException { String tag = nodeElement.getTag(); log(String.format("create tag: %s, count: %d, hardware: %s, os: %s", tag, nodeElement.getCount(), nodeElement diff --git a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java index 9267d43a13..4d6f19a33c 100644 --- a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java +++ b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java @@ -21,6 +21,7 @@ package org.jclouds.tools.ant.taskdefs.compute; import static org.jclouds.rest.RestContextFactory.getPropertiesFromResource; +import java.io.IOException; import java.net.URI; import java.util.Map; import java.util.NoSuchElementException; @@ -42,11 +43,13 @@ import org.jclouds.io.Payloads; 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.Function; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.MapMaker; +import com.google.common.io.Files; import com.google.inject.Module; import com.google.inject.Provider; @@ -58,12 +61,12 @@ public class ComputeTaskUtils { /** * - * Creates a Map that associates a uri with a live connection to the compute - * provider. This is done on-demand. + * 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. + * allows access to the ant project to retrieve default properties needed for compute + * providers. */ static Map buildComputeMap(final Provider projectProvider) { return new MapMaker().makeComputingMap(new Function() { @@ -78,8 +81,8 @@ public class ComputeTaskUtils { String provider = from.getHost(); Credentials creds = Credentials.parse(from); return new ComputeServiceContextFactory(props).createContext(provider, creds.identity, creds.credential, - ImmutableSet.of((Module) new AntLoggingModule(projectProvider.get(), - ComputeServiceConstants.COMPUTE_LOGGER), new JschSshClientModule()), props); + ImmutableSet.of((Module) new AntLoggingModule(projectProvider.get(), + ComputeServiceConstants.COMPUTE_LOGGER), new JschSshClientModule()), props); } @@ -87,7 +90,7 @@ public class ComputeTaskUtils { } - static Template createTemplateFromElement(NodeElement nodeElement, ComputeService computeService) { + static Template createTemplateFromElement(NodeElement nodeElement, ComputeService computeService) throws IOException { TemplateBuilder templateBuilder = computeService.templateBuilder(); if (nodeElement.getLocation() != null && !"".equals(nodeElement.getLocation())) templateBuilder.locationId(nodeElement.getLocation()); @@ -116,11 +119,11 @@ public class ComputeTaskUtils { template.biggest(); } else { throw new BuildException("size: " + nodeElement.getHardware() - + " not supported. valid sizes are smallest, fastest, biggest"); + + " not supported. valid sizes are smallest, fastest, biggest"); } } - static TemplateOptions getNodeOptionsFromElement(NodeElement nodeElement) { + static TemplateOptions getNodeOptionsFromElement(NodeElement nodeElement) throws IOException { TemplateOptions options = new TemplateOptions().inboundPorts(getPortsToOpenFromElement(nodeElement)); addRunScriptToOptionsIfPresentInNodeElement(nodeElement, options); addPrivateKeyToOptionsIfPresentInNodeElement(nodeElement, options); @@ -133,14 +136,15 @@ public class ComputeTaskUtils { options.runScript(Payloads.newFilePayload(nodeElement.getRunscript())); } - static void addPrivateKeyToOptionsIfPresentInNodeElement(NodeElement nodeElement, TemplateOptions options) { + static void addPrivateKeyToOptionsIfPresentInNodeElement(NodeElement nodeElement, TemplateOptions options) + throws IOException { if (nodeElement.getPrivatekeyfile() != null) - options.installPrivateKey(Payloads.newFilePayload(nodeElement.getPrivatekeyfile())); + options.installPrivateKey(Files.toString(nodeElement.getPrivatekeyfile(), Charsets.UTF_8)); } - static void addPublicKeyToOptionsIfPresentInNodeElement(NodeElement nodeElement, TemplateOptions options) { + static void addPublicKeyToOptionsIfPresentInNodeElement(NodeElement nodeElement, TemplateOptions options) throws IOException { if (nodeElement.getPrivatekeyfile() != null) - options.authorizePublicKey(Payloads.newFilePayload(nodeElement.getPublickeyfile())); + options.authorizePublicKey(Files.toString(nodeElement.getPublickeyfile(), Charsets.UTF_8)); } static String ipOrEmptyString(Set set) { diff --git a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJava.java b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJava.java index f9b4ecf8c0..aaaced9c3a 100644 --- a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJava.java +++ b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/sshjava/SSHJava.java @@ -376,7 +376,7 @@ public class SSHJava extends Java { InitBuilder testInitBuilder = new InitBuilder(id, basedir, basedir, envVariables, ImmutableList. of(Statements.interpret( commandBuilder.toString()))); - return testInitBuilder.build(osFamily); + return testInitBuilder.render(osFamily); } @Override diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java index 8a9758caba..76795d1ad3 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java @@ -152,7 +152,6 @@ public class VCloudTemplateOptions extends TemplateOptions { * @see TemplateOptions#authorizePublicKey(String) */ @Override - @Deprecated public VCloudTemplateOptions authorizePublicKey(String publicKey) { return VCloudTemplateOptions.class.cast(super.authorizePublicKey(publicKey)); } @@ -161,6 +160,7 @@ public class VCloudTemplateOptions extends TemplateOptions { * @see TemplateOptions#authorizePublicKey(Payload) */ @Override + @Deprecated public VCloudTemplateOptions authorizePublicKey(Payload publicKey) { return VCloudTemplateOptions.class.cast(super.authorizePublicKey(publicKey)); } @@ -169,7 +169,6 @@ public class VCloudTemplateOptions extends TemplateOptions { * @see TemplateOptions#installPrivateKey(String) */ @Override - @Deprecated public VCloudTemplateOptions installPrivateKey(String privateKey) { return VCloudTemplateOptions.class.cast(super.installPrivateKey(privateKey)); } @@ -178,6 +177,7 @@ public class VCloudTemplateOptions extends TemplateOptions { * @see TemplateOptions#installPrivateKey(Payload) */ @Override + @Deprecated public VCloudTemplateOptions installPrivateKey(Payload privateKey) { return VCloudTemplateOptions.class.cast(super.installPrivateKey(privateKey)); } diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java index 1883ae17d8..d1c4333234 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java @@ -30,7 +30,6 @@ import java.io.IOException; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.io.Payloads; -import org.jclouds.util.Utils; import org.testng.annotations.Test; /** @@ -78,8 +77,8 @@ public class VCloudTemplateOptionsTest { @Test public void testinstallPrivateKey() throws IOException { VCloudTemplateOptions options = new VCloudTemplateOptions(); - options.installPrivateKey(Payloads.newPayload("-----BEGIN RSA PRIVATE KEY-----")); - assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----"); + options.installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); } @Test @@ -91,7 +90,7 @@ public class VCloudTemplateOptionsTest { @Test public void testinstallPrivateKeyStatic() throws IOException { VCloudTemplateOptions options = installPrivateKey(Payloads.newPayload("-----BEGIN RSA PRIVATE KEY-----")); - assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); } @Test(expectedExceptions = NullPointerException.class) @@ -102,8 +101,8 @@ public class VCloudTemplateOptionsTest { @Test public void testauthorizePublicKey() throws IOException { VCloudTemplateOptions options = new VCloudTemplateOptions(); - options.authorizePublicKey(Payloads.newPayload("ssh-rsa")); - assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + options.authorizePublicKey("ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); } @Test @@ -115,7 +114,7 @@ public class VCloudTemplateOptionsTest { @Test public void testauthorizePublicKeyStatic() throws IOException { VCloudTemplateOptions options = authorizePublicKey(Payloads.newPayload("ssh-rsa")); - assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); } @Test(expectedExceptions = NullPointerException.class) diff --git a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/options/TerremarkVCloudTemplateOptions.java b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/options/TerremarkVCloudTemplateOptions.java index b275f54e96..271adea0e4 100644 --- a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/options/TerremarkVCloudTemplateOptions.java +++ b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/options/TerremarkVCloudTemplateOptions.java @@ -29,11 +29,10 @@ import org.jclouds.io.Payload; import org.jclouds.util.Utils; /** - * Contains options supported in the {@code ComputeService#runNode} operation on - * the "trmk-vcloudexpress" provider.

- * Usage

The recommended way to instantiate a - * TerremarkVCloudTemplateOptions object is to statically import - * TerremarkVCloudTemplateOptions.* and invoke a static creation method followed + * Contains options supported in the {@code ComputeService#runNode} operation on the + * "trmk-vcloudexpress" provider.

+ * Usage

The recommended way to instantiate a TerremarkVCloudTemplateOptions object is to + * statically import TerremarkVCloudTemplateOptions.* and invoke a static creation method followed * by an instance mutator (if needed): *

* @@ -162,10 +161,9 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions { /** * - * special thing is that we do assume if you are passing groups that you have - * everything you need already defined. for example, our option inboundPorts - * normally creates ingress rules accordingly but if we notice you've - * specified securityGroups, we do not mess with rules at all + * special thing is that we do assume if you are passing groups that you have everything you need + * already defined. for example, our option inboundPorts normally creates ingress rules + * accordingly but if we notice you've specified securityGroups, we do not mess with rules at all * * @see TemplateOptions#inboundPorts */ @@ -178,7 +176,6 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions { * @see TemplateOptions#authorizePublicKey(String) */ @Override - @Deprecated public TerremarkVCloudTemplateOptions authorizePublicKey(String publicKey) { return TerremarkVCloudTemplateOptions.class.cast(super.authorizePublicKey(publicKey)); } @@ -187,6 +184,7 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions { * @see TemplateOptions#authorizePublicKey(Payload) */ @Override + @Deprecated public TerremarkVCloudTemplateOptions authorizePublicKey(Payload publicKey) { return TerremarkVCloudTemplateOptions.class.cast(super.authorizePublicKey(publicKey)); } @@ -195,7 +193,6 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions { * @see TemplateOptions#installPrivateKey(String) */ @Override - @Deprecated public TerremarkVCloudTemplateOptions installPrivateKey(String privateKey) { return TerremarkVCloudTemplateOptions.class.cast(super.installPrivateKey(privateKey)); } @@ -204,6 +201,7 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions { * @see TemplateOptions#installPrivateKey(Payload) */ @Override + @Deprecated public TerremarkVCloudTemplateOptions installPrivateKey(Payload privateKey) { return TerremarkVCloudTemplateOptions.class.cast(super.installPrivateKey(privateKey)); } @@ -234,8 +232,7 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions { } /** - * @return keyPair to use when running the instance or null, to generate a - * keypair. + * @return keyPair to use when running the instance or null, to generate a keypair. */ public String getSshKeyFingerprint() { return keyPair; @@ -279,9 +276,9 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions { @Override public String toString() { return "TerremarkVCloudTemplateOptions [keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", inboundPorts=" - + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey=" - + (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port + ":" + seconds - + ", metadata/details: " + includeMetadata + "]"; + + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey=" + + (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port + ":" + seconds + + ", metadata/details: " + includeMetadata + "]"; } } diff --git a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudTemplateOptionsTest.java b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudTemplateOptionsTest.java index 5163af627d..a00a168e38 100644 --- a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudTemplateOptionsTest.java +++ b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudTemplateOptionsTest.java @@ -30,7 +30,6 @@ import static org.testng.Assert.assertEquals; import java.io.IOException; import org.jclouds.compute.options.TemplateOptions; -import org.jclouds.util.Utils; import org.jclouds.vcloud.terremark.compute.options.TerremarkVCloudTemplateOptions; import org.testng.annotations.Test; @@ -114,19 +113,17 @@ public class TerremarkVCloudTemplateOptionsTest { } // superclass tests - @SuppressWarnings("deprecation") @Test(expectedExceptions = IllegalArgumentException.class) public void testinstallPrivateKeyBadFormat() { TerremarkVCloudTemplateOptions options = new TerremarkVCloudTemplateOptions(); options.installPrivateKey("whompy"); } - @SuppressWarnings("deprecation") @Test public void testinstallPrivateKey() throws IOException { TerremarkVCloudTemplateOptions options = new TerremarkVCloudTemplateOptions(); options.installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); - assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); } @Test @@ -138,7 +135,7 @@ public class TerremarkVCloudTemplateOptionsTest { @Test public void testinstallPrivateKeyStatic() throws IOException { TerremarkVCloudTemplateOptions options = installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); - assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); } @Test(expectedExceptions = NullPointerException.class) @@ -146,19 +143,17 @@ public class TerremarkVCloudTemplateOptionsTest { installPrivateKey(null); } - @SuppressWarnings("deprecation") @Test(expectedExceptions = IllegalArgumentException.class) public void testauthorizePublicKeyBadFormat() { TerremarkVCloudTemplateOptions options = new TerremarkVCloudTemplateOptions(); options.authorizePublicKey("whompy"); } - @SuppressWarnings("deprecation") @Test public void testauthorizePublicKey() throws IOException { TerremarkVCloudTemplateOptions options = new TerremarkVCloudTemplateOptions(); options.authorizePublicKey("ssh-rsa"); - assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); } @Test @@ -170,7 +165,7 @@ public class TerremarkVCloudTemplateOptionsTest { @Test public void testauthorizePublicKeyStatic() throws IOException { TerremarkVCloudTemplateOptions options = authorizePublicKey("ssh-rsa"); - assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); } @Test(expectedExceptions = NullPointerException.class) From 0738d1cd5a3104dbb874f7aff01445b26a640bea Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Fri, 24 Sep 2010 16:07:51 -0700 Subject: [PATCH 4/6] added example of how to start a service --- .../callables/InitAndStartScriptOnNode.java | 47 +++--- .../compute/callables/RunScriptOnNode.java | 26 +--- .../compute/internal/BaseComputeService.java | 6 +- .../compute/options/RunScriptOptions.java | 50 +++++-- .../compute/options/TemplateOptions.java | 13 +- .../jclouds/compute/util/ComputeUtils.java | 25 ++-- .../main/java/org/jclouds/ssh/SshClient.java | 2 + .../compute/BaseComputeServiceLiveTest.java | 68 +++++---- .../org/jclouds/compute/RunScriptData.java | 109 ++++++++++++++ .../StubComputeServiceIntegrationTest.java | 59 ++++++-- ...t_with_keys.sh => initscript_with_java.sh} | 20 +-- .../test/resources/initscript_with_jboss.sh | 137 ++++++++++++++++++ compute/src/test/resources/runscript.sh | 6 +- .../org/jclouds/ssh/jsch/JschSshClient.java | 34 +++-- .../ssh/jsch/JschSshClientLiveTest.java | 11 +- .../jclouds/scriptbuilder/InitBuilder.java | 73 +++++++++- .../domain/AuthorizeRSAPublicKey.java | 4 +- .../domain/InstallRSAPrivateKey.java | 4 +- .../UnzipHttpResponseIntoDirectory.java | 2 +- ...st.java => AuthorizeRSAPublicKeyTest.java} | 4 +- .../domain/InstallRSAPrivateKeyTest.java | 2 +- .../UnzipHttpResponseIntoDirectoryToTest.java | 2 +- 22 files changed, 553 insertions(+), 151 deletions(-) create mode 100644 compute/src/test/java/org/jclouds/compute/RunScriptData.java rename compute/src/test/resources/{initscript_with_keys.sh => initscript_with_java.sh} (89%) create mode 100644 compute/src/test/resources/initscript_with_jboss.sh rename scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/{CopyOfAuthorizeRSAPublicKeyTest.java => AuthorizeRSAPublicKeyTest.java} (87%) diff --git a/compute/src/main/java/org/jclouds/compute/callables/InitAndStartScriptOnNode.java b/compute/src/main/java/org/jclouds/compute/callables/InitAndStartScriptOnNode.java index 50d916a702..ab4d575da2 100644 --- a/compute/src/main/java/org/jclouds/compute/callables/InitAndStartScriptOnNode.java +++ b/compute/src/main/java/org/jclouds/compute/callables/InitAndStartScriptOnNode.java @@ -21,11 +21,13 @@ package org.jclouds.compute.callables; import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Collections; + import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.util.ComputeServiceUtils; import org.jclouds.compute.util.ComputeServiceUtils.SshCallable; -import org.jclouds.io.Payloads; import org.jclouds.logging.Logger; +import org.jclouds.scriptbuilder.InitBuilder; import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.ssh.ExecResponse; @@ -40,28 +42,36 @@ import com.google.common.collect.Iterables; public class InitAndStartScriptOnNode implements SshCallable { protected SshClient ssh; protected final NodeMetadata node; - protected final String scriptName; - protected final Statement script; + protected final InitBuilder init; protected final boolean runAsRoot; protected Logger logger = Logger.NULL; - public InitAndStartScriptOnNode(NodeMetadata node, String scriptName, Statement script, boolean runAsRoot) { + public InitAndStartScriptOnNode(NodeMetadata node, String name, Statement script, boolean runAsRoot) { this.node = checkNotNull(node, "node"); - this.scriptName = checkNotNull(scriptName, "scriptName"); - this.script = checkNotNull(script, "script"); + this.init = checkNotNull(script, "script") instanceof InitBuilder ? InitBuilder.class.cast(script) + : createInitScript(checkNotNull(name, "name"), script); this.runAsRoot = runAsRoot; } + public static InitBuilder createInitScript(String name, Statement script) { + String path = "/tmp/" + name; + return new InitBuilder(name, path, path, Collections. emptyMap(), Collections.singleton(script)); + } + @Override public ExecResponse call() { - ssh.put(scriptName, Payloads.newPayload(script.render(OsFamily.UNIX))); - ExecResponse returnVal = ssh.exec("chmod 755 " + scriptName); - returnVal = ssh.exec("./" + scriptName + " init"); - logger.debug("<< initialized(%d)", returnVal.getExitCode()); + ssh.put(init.getInstanceName(), init.render(OsFamily.UNIX)); + ssh.exec("chmod 755 " + init.getInstanceName()); + runAction("init"); + return runAction("start"); + } - String command = (runAsRoot) ? startScriptAsRoot() : startScriptAsDefaultUser(); + private ExecResponse runAction(String action) { + ExecResponse returnVal; + String command = (runAsRoot) ? execScriptAsRoot(action) : execScriptAsDefaultUser(action); returnVal = runCommand(command); - logger.debug("<< start(%d)", returnVal.getExitCode()); + logger.debug("<< %s(%d)", action, returnVal.getExitCode()); + logger.trace("<< %s[%s]", action, returnVal); return returnVal; } @@ -79,20 +89,21 @@ public class InitAndStartScriptOnNode implements SshCallable { this.ssh = checkNotNull(ssh, "ssh"); } - protected String startScriptAsRoot() { + protected String execScriptAsRoot(String action) { String command; if (node.getCredentials().identity.equals("root")) { - command = "./" + scriptName + " start"; + command = "./" + init.getInstanceName() + " " + action; } else if (ComputeServiceUtils.isKeyAuth(node)) { - command = "sudo ./" + scriptName + " start"; + command = "sudo ./" + init.getInstanceName() + " " + action; } else { - command = String.format("echo '%s'|sudo -S ./%s", node.getCredentials().credential, scriptName + " start"); + command = String.format("echo '%s'|sudo -S ./%s %s", node.getCredentials().credential, init.getInstanceName(), + action); } return command; } - protected String startScriptAsDefaultUser() { - return "./" + scriptName + " start"; + protected String execScriptAsDefaultUser(String action) { + return "./" + init.getInstanceName() + " " + action; } @Override diff --git a/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java b/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java index 19b864c939..214dc4d9ec 100644 --- a/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java +++ b/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java @@ -19,13 +19,10 @@ package org.jclouds.compute.callables; -import java.util.Collections; - import javax.inject.Named; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; -import org.jclouds.scriptbuilder.InitBuilder; import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.ssh.ExecResponse; @@ -39,34 +36,23 @@ import com.google.common.collect.Iterables; public class RunScriptOnNode extends InitAndStartScriptOnNode { protected final Predicate runScriptNotRunning; - public RunScriptOnNode(@Named("SCRIPT_COMPLETE") Predicate runScriptNotRunning, - NodeMetadata node, String scriptName, Statement script) { - this(runScriptNotRunning, node, scriptName, script, true); - } - public RunScriptOnNode(@Named("SCRIPT_COMPLETE") Predicate runScriptNotRunning, NodeMetadata node, String scriptName, Statement script, boolean runAsRoot) { - super(node, scriptName, createInitScript(scriptName, script), runAsRoot); + super(node, scriptName, script, runAsRoot); this.runScriptNotRunning = runScriptNotRunning; } - public static Statement createInitScript(String scriptName, Statement script) { - String path = "/tmp/" + scriptName; - return new InitBuilder(scriptName, path, path, Collections. emptyMap(), Collections - .singleton(script)); - } @Override public ExecResponse call() { ExecResponse returnVal = super.call(); - - boolean complete = runScriptNotRunning.apply(new CommandUsingClient("./" + scriptName + " status", ssh)); + boolean complete = runScriptNotRunning.apply(new CommandUsingClient("./" + init.getInstanceName() + " status", ssh)); logger.debug("<< complete(%s)", complete); if (logger.isDebugEnabled() || returnVal.getExitCode() != 0) { - logger.debug("<< stdout from %s as %s@%s\n%s", scriptName, node.getCredentials().identity, Iterables.get(node - .getPublicAddresses(), 0), ssh.exec("./" + scriptName + " tail").getOutput()); - logger.debug("<< stderr from %s as %s@%s\n%s", scriptName, node.getCredentials().identity, Iterables.get(node - .getPublicAddresses(), 0), ssh.exec("./" + scriptName + " tailerr").getOutput()); + logger.debug("<< stdout from %s as %s@%s\n%s", init.getInstanceName(), node.getCredentials().identity, Iterables.get(node + .getPublicAddresses(), 0), ssh.exec("./" + init.getInstanceName() + " tail").getOutput()); + logger.debug("<< stderr from %s as %s@%s\n%s", init.getInstanceName(), node.getCredentials().identity, Iterables.get(node + .getPublicAddresses(), 0), ssh.exec("./" + init.getInstanceName() + " tailerr").getOutput()); } return returnVal; } diff --git a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java index 7c91fedef4..e250685ab0 100755 --- a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java @@ -67,6 +67,7 @@ import org.jclouds.domain.Location; import org.jclouds.io.Payload; import org.jclouds.logging.Logger; import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.scriptbuilder.InitBuilder; import org.jclouds.scriptbuilder.domain.Statements; import org.jclouds.ssh.ExecResponse; import org.jclouds.util.Utils; @@ -152,7 +153,8 @@ public class BaseComputeService implements ComputeService { throws RunNodesException { checkArgument(tag.indexOf('-') == -1, "tag cannot contain hyphens"); checkNotNull(template.getLocation(), "location"); - if (template.getOptions().getTaskName() == null && template.getOptions().getRunScript() != null) + if (template.getOptions().getTaskName() == null && template.getOptions().getRunScript() != null + && !(template.getOptions().getRunScript() instanceof InitBuilder)) template.getOptions().nameTask("bootstrap"); logger.debug(">> running %d node%s tag(%s) location(%s) image(%s) hardwareProfile(%s) options(%s)", count, count > 1 ? "s" : "", tag, template.getLocation().getId(), template.getImage().getId(), template @@ -359,7 +361,7 @@ public class BaseComputeService implements ComputeService { checkNotNull(options, "options"); if (options.getTaskName() == null) options.nameTask("jclouds-script-" + System.currentTimeMillis()); - + Iterable nodes = Iterables.filter(detailsOnAllNodes(), filter); final Map execs = Maps.newHashMap(); diff --git a/compute/src/main/java/org/jclouds/compute/options/RunScriptOptions.java b/compute/src/main/java/org/jclouds/compute/options/RunScriptOptions.java index 2b4b2e2776..d271ca0349 100644 --- a/compute/src/main/java/org/jclouds/compute/options/RunScriptOptions.java +++ b/compute/src/main/java/org/jclouds/compute/options/RunScriptOptions.java @@ -60,8 +60,8 @@ public class RunScriptOptions { } @Override - public boolean isRunAsRoot() { - return delegate.isRunAsRoot(); + public boolean shouldRunAsRoot() { + return delegate.shouldRunAsRoot(); } @@ -70,6 +70,17 @@ public class RunScriptOptions { throw new IllegalArgumentException("runAsRoot is immutable"); } + @Override + public boolean shouldBlockOnComplete() { + return delegate.shouldBlockOnComplete(); + + } + + @Override + public RunScriptOptions blockOnComplete(boolean blockOnComplete) { + throw new IllegalArgumentException("blockOnComplete is immutable"); + } + @Override public RunScriptOptions withOverridingCredentials(Credentials overridingCredentials) { throw new IllegalArgumentException("overridingCredentials is immutable"); @@ -106,6 +117,7 @@ public class RunScriptOptions { protected String taskName; protected Credentials overridingCredentials; protected boolean runAsRoot = true; + protected boolean blockOnComplete = true; public RunScriptOptions withOverridingCredentials(Credentials overridingCredentials) { checkNotNull(overridingCredentials, "overridingCredentials"); @@ -114,6 +126,7 @@ public class RunScriptOptions { this.overridingCredentials = overridingCredentials; return this; } + /** * @return What to call the task relating to this script; default {@code * jclouds-script-timestamp} where timestamp is millis since epoch @@ -128,6 +141,12 @@ public class RunScriptOptions { this.runAsRoot = runAsRoot; return this; } + + public RunScriptOptions blockOnComplete(boolean blockOnComplete) { + this.blockOnComplete = blockOnComplete; + return this; + } + /** * When the node is started, wait until the following port is active */ @@ -138,12 +157,11 @@ public class RunScriptOptions { this.seconds = seconds; return this; } - + public String getTaskName() { return taskName; } - public int getPort() { return port; } @@ -167,10 +185,19 @@ public class RunScriptOptions { * * @return value */ - public boolean isRunAsRoot() { + public boolean shouldRunAsRoot() { return runAsRoot; } + /** + * Whether to wait until the script has completed. By default, true. + * + * @return value + */ + public boolean shouldBlockOnComplete() { + return blockOnComplete; + } + public static class Builder { public static RunScriptOptions nameTask(String name) { @@ -187,10 +214,12 @@ public class RunScriptOptions { RunScriptOptions options = new RunScriptOptions(); return options.runAsRoot(value); } - - /** - * @see RunScriptOptions#blockOnPort - */ + + public static RunScriptOptions blockOnComplete(boolean value) { + RunScriptOptions options = new RunScriptOptions(); + return options.blockOnComplete(value); + } + public static RunScriptOptions blockOnPort(int port, int seconds) { RunScriptOptions options = new RunScriptOptions(); return options.blockOnPort(port, seconds); @@ -200,7 +229,8 @@ public class RunScriptOptions { @Override public String toString() { - return "[overridingCredentials=" + (overridingCredentials != null) + ", port:seconds=" + port + ":" + seconds + ", runAsRoot=" + runAsRoot + "]"; + return "[overridingCredentials=" + (overridingCredentials != null) + ", port:seconds=" + port + ":" + seconds + + ", runAsRoot=" + runAsRoot + ", blockOnComplete=" + blockOnComplete + "]"; } } diff --git a/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java b/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java index 990367cba0..78d02af5d5 100644 --- a/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java +++ b/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java @@ -396,13 +396,19 @@ public class TemplateOptions extends RunScriptOptions { return options.withMetadata(); } + public static TemplateOptions blockOnComplete(boolean value) { + TemplateOptions options = new TemplateOptions(); + return options.blockOnComplete(value); + } + } @Override public String toString() { return "[inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null) + ", blockUntilRunning=" + blockUntilRunning - + ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata + "]"; + + ", blockOnComplete=" + blockOnComplete + ", port:seconds=" + port + ":" + seconds + + ", metadata/details: " + includeMetadata + "]"; } public TemplateOptions blockUntilRunning(boolean blockUntilRunning) { @@ -483,4 +489,9 @@ public class TemplateOptions extends RunScriptOptions { public TemplateOptions withOverridingCredentials(Credentials overridingCredentials) { return TemplateOptions.class.cast(super.withOverridingCredentials(overridingCredentials)); } + + @Override + public TemplateOptions blockOnComplete(boolean blockOnComplete) { + return TemplateOptions.class.cast(super.blockOnComplete(blockOnComplete)); + } } diff --git a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java index 4c2f0e0af6..e09cbf509e 100644 --- a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java +++ b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java @@ -40,6 +40,7 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.Constants; +import org.jclouds.compute.callables.InitAndStartScriptOnNode; import org.jclouds.compute.callables.RunScriptOnNode; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.options.RunScriptOptions; @@ -146,8 +147,8 @@ public class ComputeUtils { bootstrap.add(new AuthorizeRSAPublicKey(options.getPublicKey())); if (options.getPrivateKey() != null) bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey())); - if (bootstrap.size() >0) - runScriptOnNode(node, new StatementList(bootstrap), options); + if (bootstrap.size() >= 1) + runScriptOnNode(node, bootstrap.size() == 1 ? bootstrap.get(0) : new StatementList(bootstrap), options); return node; } @@ -155,15 +156,9 @@ public class ComputeUtils { checkState(node.getPublicAddresses().size() > 0, "node does not have IP addresses configured: " + node); } - public ExecResponse runScriptOnNode(NodeMetadata node, Statement runScript, RunScriptOptions options) - { - RunScriptOnNode callable; - String taskName = options.getTaskName(); + public ExecResponse runScriptOnNode(NodeMetadata node, Statement runScript, RunScriptOptions options) { + InitAndStartScriptOnNode callable = generateScript(node, runScript, options); ExecResponse response; - if (options.isRunAsRoot()) { - callable = runScriptOnNode(node, taskName, runScript); - } else - callable = runScriptOnNodeAsDefaultUser(node, taskName, runScript); SshClient ssh = createSshClientOncePortIsListeningOnNode(node); try { ssh.connect(); @@ -192,12 +187,10 @@ public class ComputeUtils { logger.warn("<< port %s:%d didn't open after %d seconds", inetAddress, port, seconds); } - public RunScriptOnNode runScriptOnNode(NodeMetadata node, String scriptName, Statement script) { - return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script); - } - - public RunScriptOnNode runScriptOnNodeAsDefaultUser(NodeMetadata node, String scriptName, Statement script) { - return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script, false); + public InitAndStartScriptOnNode generateScript(NodeMetadata node, Statement script, RunScriptOptions options) { + return options.shouldBlockOnComplete() ? new RunScriptOnNode(runScriptNotRunning, node, options.getTaskName(), + script, options.shouldRunAsRoot()) : new InitAndStartScriptOnNode(node, options.getTaskName(), script, + options.shouldRunAsRoot()); } public Map, ?> runCallablesOnNode(NodeMetadata node, Iterable> parallel, diff --git a/compute/src/main/java/org/jclouds/ssh/SshClient.java b/compute/src/main/java/org/jclouds/ssh/SshClient.java index b0a907b5e2..ca9c82b99d 100644 --- a/compute/src/main/java/org/jclouds/ssh/SshClient.java +++ b/compute/src/main/java/org/jclouds/ssh/SshClient.java @@ -52,4 +52,6 @@ public interface SshClient { @PreDestroy void disconnect(); + void put(String path, String contents); + } \ No newline at end of file diff --git a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java index 6bd4dbe28e..dc39ce9404 100755 --- a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java @@ -30,7 +30,8 @@ import static com.google.common.collect.Maps.newLinkedHashMap; import static com.google.common.collect.Maps.uniqueIndex; import static com.google.common.collect.Sets.filter; import static com.google.common.collect.Sets.newTreeSet; -import static org.jclouds.compute.options.RunScriptOptions.Builder.overrideCredentialsWith; +import static org.jclouds.compute.options.TemplateOptions.Builder.blockOnComplete; +import static org.jclouds.compute.options.TemplateOptions.Builder.overrideCredentialsWith; import static org.jclouds.compute.predicates.NodePredicates.TERMINATED; import static org.jclouds.compute.predicates.NodePredicates.all; import static org.jclouds.compute.predicates.NodePredicates.runningWithTag; @@ -43,6 +44,7 @@ import static org.testng.Assert.assertNotNull; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.net.URI; import java.util.Collection; import java.util.Map; import java.util.NoSuchElementException; @@ -96,33 +98,6 @@ import com.google.inject.Module; */ @Test(groups = { "integration", "live" }, sequential = true, testName = "compute.ComputeServiceLiveTest") public abstract class BaseComputeServiceLiveTest { - public static final String APT_RUN_SCRIPT = new StringBuilder()// - .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")// - .append("cp /etc/apt/sources.list /etc/apt/sources.list.old\n")// - .append( - "sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list\n")// - .append("apt-get update\n")// - .append("apt-get install -f -y --force-yes openjdk-6-jdk\n")// - .toString(); - - public static final String YUM_RUN_SCRIPT = new StringBuilder() - .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n") - // - .append("echo \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n") - // - .append("echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n") - // - .append( - "echo \"baseurl=http://ec2-us-east-mirror.rightscale.com/epel/5/i386/\" >> /etc/yum.repos.d/CentOS-Base.repo\n")// - .append("echo \"enabled=1\" >> /etc/yum.repos.d/CentOS-Base.repo\n")// - .append("yum --nogpgcheck -y install java-1.6.0-openjdk\n")// - .append("echo \"export PATH=\\\"/usr/lib/jvm/jre-1.6.0-openjdk/bin/:\\$PATH\\\"\" >> /root/.bashrc\n")// - .toString(); - - public static final String ZYPPER_RUN_SCRIPT = new StringBuilder()// - .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")// - .append("sudo zypper install java-1.6.0-openjdk-devl\n")// - .toString(); public void setServiceDefaults() { @@ -289,6 +264,37 @@ public abstract class BaseComputeServiceLiveTest { } @Test(enabled = true, dependsOnMethods = "testCompareSizes") + public void testCreateAndRunAService() throws Exception { + + String tag = this.tag + "service"; + try { + client.destroyNodesMatching(withTag(tag)); + } catch (Exception e) { + + } + + template = client.templateBuilder().options(blockOnComplete(false).blockOnPort(8080, 300).inboundPorts(22, 8080)) + .build(); + // note this is a dependency on the template resolution + template.getOptions().runScript( + RunScriptData.createScriptInstallAndStartJBoss(keyPair.get("public"), template.getImage() + .getOperatingSystem())); + try { + TreeSet nodes = newTreeSet(client.runNodesWithTag(tag, 1, template)); + + checkHttpGet(nodes); + } finally { + client.destroyNodesMatching(withTag(tag)); + } + + } + + protected void checkHttpGet(TreeSet nodes) { + assert context.utils().http().get( + URI.create(String.format("http://%s:8080", get(nodes.last().getPublicAddresses(), 0)))) != null; + } + + @Test(enabled = true, dependsOnMethods = "testCreateAndRunAService") public void testCreateTwoNodesWithRunScript() throws Exception { try { client.destroyNodesMatching(withTag(tag)); @@ -389,11 +395,11 @@ public abstract class BaseComputeServiceLiveTest { public static String buildScript(OperatingSystem os) { if (OperatingSystemPredicates.supportsApt().apply(os)) - return APT_RUN_SCRIPT; + return RunScriptData.APT_RUN_SCRIPT; else if (OperatingSystemPredicates.supportsYum().apply(os)) - return YUM_RUN_SCRIPT; + return RunScriptData.YUM_RUN_SCRIPT; else if (OperatingSystemPredicates.supportsZypper().apply(os)) - return ZYPPER_RUN_SCRIPT; + return RunScriptData.ZYPPER_RUN_SCRIPT; else throw new IllegalArgumentException("don't know how to handle" + os.toString()); } diff --git a/compute/src/test/java/org/jclouds/compute/RunScriptData.java b/compute/src/test/java/org/jclouds/compute/RunScriptData.java new file mode 100644 index 0000000000..ec7a3326d9 --- /dev/null +++ b/compute/src/test/java/org/jclouds/compute/RunScriptData.java @@ -0,0 +1,109 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.compute; + +import static org.jclouds.compute.util.ComputeServiceUtils.extractZipIntoDirectory; +import static org.jclouds.scriptbuilder.domain.Statements.exec; +import static org.jclouds.scriptbuilder.domain.Statements.interpret; + +import java.net.URI; +import java.util.Map; + +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.predicates.OperatingSystemPredicates; +import org.jclouds.scriptbuilder.InitBuilder; +import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey; +import org.jclouds.scriptbuilder.domain.Statement; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +/** + * + * @author Adrian Cole + */ +public class RunScriptData { + private static String jbossVersion = "5.0.0.CR2"; + private static String jboss = String.format("jboss-%s-jdk6", jbossVersion); + private static String jbossHome = "/usr/local/jboss"; + + public static String createScriptInstallBase(OperatingSystem os) { + if (os == null || OperatingSystemPredicates.supportsApt().apply(os)) + return APT_RUN_SCRIPT; + else if (OperatingSystemPredicates.supportsYum().apply(os)) + return YUM_RUN_SCRIPT; + else if (OperatingSystemPredicates.supportsZypper().apply(os)) + return ZYPPER_RUN_SCRIPT; + else + throw new IllegalArgumentException("don't know how to handle" + os.toString()); + } + + public static Statement createScriptInstallAndStartJBoss(String publicKey, OperatingSystem os) { + Map envVariables = ImmutableMap.of("jbossHome", jbossHome); + Statement toReturn = new InitBuilder( + "jboss", + jbossHome, + jbossHome, + envVariables, + ImmutableList. of(new AuthorizeRSAPublicKey(publicKey), exec(createScriptInstallBase(os)), + extractZipIntoDirectory(URI.create(String.format( + "http://superb-sea2.dl.sourceforge.net/project/jboss/JBoss/JBoss-%s/%s.zip", + jbossVersion, jboss)), "/usr/local"), exec("{md} " + jbossHome), + exec("mv /usr/local/jboss-" + jbossVersion + "/* " + jbossHome)), + ImmutableList + . of(interpret("java -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.endorsed.dirs=lib/endorsed -Djboss.bind.address=0.0.0.0 -classpath bin/run.jar org.jboss.Main"))); + return toReturn; + } + + public static final String APT_RUN_SCRIPT = new StringBuilder()// + .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")// + .append("cp /etc/apt/sources.list /etc/apt/sources.list.old\n")// + .append( + "sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list\n")// + .append("apt-get update -y -qq\n")// + .append("apt-get install -f -y -qq --force-yes curl\n")// + .append("apt-get install -f -y -qq --force-yes unzip\n")// + .append("apt-get install -f -y -qq --force-yes openjdk-6-jdk\n")// + .toString(); + + public static final String YUM_RUN_SCRIPT = new StringBuilder() + .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n") + // + .append("echo \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n") + // + .append("echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n") + // + .append( + "echo \"baseurl=http://ec2-us-east-mirror.rightscale.com/epel/5/i386/\" >> /etc/yum.repos.d/CentOS-Base.repo\n")// + .append("echo \"enabled=1\" >> /etc/yum.repos.d/CentOS-Base.repo\n")// + .append("yum --nogpgcheck -y install unzip\n")// + .append("yum --nogpgcheck -y install curl\n")// + .append("yum --nogpgcheck -y install java-1.6.0-openjdk\n")// + .append("echo \"export PATH=\\\"/usr/lib/jvm/jre-1.6.0-openjdk/bin/:\\$PATH\\\"\" >> /root/.bashrc\n")// + .toString(); + + public static final String ZYPPER_RUN_SCRIPT = new StringBuilder()// + .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")// + .append("sudo zypper install unzip\n")// + .append("sudo zypper install curl\n")// + .append("sudo zypper install java-1.6.0-openjdk-devl\n")// + .toString(); + +} diff --git a/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java b/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java index 603bd33232..8830b4b14c 100644 --- a/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java +++ b/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java @@ -32,6 +32,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.Serializable; import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -96,12 +97,18 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes expect(socketOpen.apply(new IPSocket("144.175.1.2", 22))).andReturn(true); expect(socketOpen.apply(new IPSocket("144.175.1.3", 22))).andReturn(true); expect(socketOpen.apply(new IPSocket("144.175.1.4", 22))).andReturn(true); + expect(socketOpen.apply(new IPSocket("144.175.1.5", 22))).andReturn(true); replay(socketOpen); socketTester = new RetryablePredicate(socketOpen, 60, 1, TimeUnit.SECONDS); } + @Override + protected void checkHttpGet(TreeSet nodes) { + + } + @Override protected Module getSshModule() { return new AbstractModule() { @@ -113,31 +120,36 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes SshClient client2 = createMock(SshClient.class); SshClient client3 = createMock(SshClient.class); SshClient client4 = createMock(SshClient.class); + SshClient client5 = createMock(SshClient.class); - expect(factory.create(new IPSocket("144.175.1.1", 22), "root", "romeo")).andThrow( - new SshException("Auth fail")); expect(factory.create(new IPSocket("144.175.1.1", 22), "root", "password1")).andReturn(client1) .atLeastOnce(); + runScriptAndService(client1, 1); - client1.connect(); + expect(factory.create(new IPSocket("144.175.1.2", 22), "root", "romeo")).andThrow( + new SshException("Auth fail")); + expect(factory.create(new IPSocket("144.175.1.2", 22), "root", "password2")).andReturn(client2) + .atLeastOnce(); + + client2.connect(); try { - runScript(client1, "runScriptWithCreds", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class - .getResourceAsStream("/runscript.sh")), 1); + runScript(client2, "runScriptWithCreds", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class + .getResourceAsStream("/runscript.sh")), 2); } catch (IOException e) { Throwables.propagate(e); } - client1.disconnect(); + client2.disconnect(); - expect(factory.create(new IPSocket("144.175.1.2", 22), "root", "password2")).andReturn(client2) - .atLeastOnce(); expect(factory.create(new IPSocket("144.175.1.3", 22), "root", "password3")).andReturn(client3) .atLeastOnce(); expect(factory.create(new IPSocket("144.175.1.4", 22), "root", "password4")).andReturn(client4) .atLeastOnce(); + expect(factory.create(new IPSocket("144.175.1.5", 22), "root", "password5")).andReturn(client5) + .atLeastOnce(); - runScriptAndInstallSsh(client2, "bootstrap", 2); runScriptAndInstallSsh(client3, "bootstrap", 3); runScriptAndInstallSsh(client4, "bootstrap", 4); + runScriptAndInstallSsh(client5, "bootstrap", 5); expect( factory.create(eq(new IPSocket("144.175.1.1", 22)), eq("root"), aryEq(keyPair.get("private") @@ -151,27 +163,45 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes expect( factory.create(eq(new IPSocket("144.175.1.4", 22)), eq("root"), aryEq(keyPair.get("private") .getBytes()))).andReturn(client4).atLeastOnce(); + expect( + factory.create(eq(new IPSocket("155.175.1.5", 22)), eq("root"), aryEq(keyPair.get("private") + .getBytes()))).andReturn(client5).atLeastOnce(); - helloAndJava(client1); helloAndJava(client2); helloAndJava(client3); helloAndJava(client4); + helloAndJava(client5); replay(factory); replay(client1); replay(client2); replay(client3); replay(client4); + replay(client5); bind(SshClient.Factory.class).toInstance(factory); } + private void runScriptAndService(SshClient client, int nodeId) { + client.connect(); + + try { + runScript(client, "jboss", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class + .getResourceAsStream("/initscript_with_jboss.sh")), nodeId); + } catch (IOException e) { + Throwables.propagate(e); + } + + client.disconnect(); + + } + private void runScriptAndInstallSsh(SshClient client, String scriptName, int nodeId) { client.connect(); try { runScript(client, scriptName, Utils.toStringAndClose(StubComputeServiceIntegrationTest.class - .getResourceAsStream("/initscript_with_keys.sh")), nodeId); + .getResourceAsStream("/initscript_with_java.sh")), nodeId); } catch (IOException e) { Throwables.propagate(e); } @@ -181,7 +211,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes } private void runScript(SshClient client, String scriptName, String script, int nodeId) { - client.put(eq("" + scriptName + ""), payloadEq(script)); + client.put(scriptName, script); expect(client.exec("chmod 755 " + scriptName + "")).andReturn(EXEC_GOOD); expect(client.getUsername()).andReturn("root").atLeastOnce(); expect(client.getHostAddress()).andReturn(nodeId + "").atLeastOnce(); @@ -299,6 +329,11 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes super.testAScriptExecutionAfterBootWithBasicTemplate(); } + @Test(enabled = true, dependsOnMethods = { "testCompareSizes" }) + public void testCreateAndRunAService() throws Exception { + super.testCreateAndRunAService(); + } + @Test(enabled = true, dependsOnMethods = "testTemplateMatch") public void testCreateTwoNodesWithRunScript() throws Exception { super.testCreateTwoNodesWithRunScript(); diff --git a/compute/src/test/resources/initscript_with_keys.sh b/compute/src/test/resources/initscript_with_java.sh similarity index 89% rename from compute/src/test/resources/initscript_with_keys.sh rename to compute/src/test/resources/initscript_with_java.sh index ac11ffa738..df87d2435d 100644 --- a/compute/src/test/resources/initscript_with_keys.sh +++ b/compute/src/test/resources/initscript_with_java.sh @@ -79,20 +79,22 @@ cd $INSTANCE_HOME echo nameserver 208.67.222.222 >> /etc/resolv.conf cp /etc/apt/sources.list /etc/apt/sources.list.old sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list -apt-get update -apt-get install -f -y --force-yes openjdk-6-jdk +apt-get update -y -qq +apt-get install -f -y -qq --force-yes curl +apt-get install -f -y -qq --force-yes unzip +apt-get install -f -y -qq --force-yes openjdk-6-jdk -mkdir -p .ssh -cat >> .ssh/authorized_keys <<'END_OF_FILE' +mkdir -p ~/.ssh +cat >> ~/.ssh/authorized_keys <<'END_OF_FILE' ssh-rsa END_OF_FILE -chmod 600 .ssh/authorized_keys -mkdir -p .ssh -rm .ssh/id_rsa -cat >> .ssh/id_rsa <<'END_OF_FILE' +chmod 600 ~/.ssh/authorized_keys +mkdir -p ~/.ssh +rm ~/.ssh/id_rsa +cat >> ~/.ssh/id_rsa <<'END_OF_FILE' -----BEGIN RSA PRIVATE KEY----- END_OF_FILE -chmod 600 .ssh/id_rsa +chmod 600 ~/.ssh/id_rsa END_OF_SCRIPT diff --git a/compute/src/test/resources/initscript_with_jboss.sh b/compute/src/test/resources/initscript_with_jboss.sh new file mode 100644 index 0000000000..f28900a506 --- /dev/null +++ b/compute/src/test/resources/initscript_with_jboss.sh @@ -0,0 +1,137 @@ +#!/bin/bash +set +u +shopt -s xpg_echo +shopt -s expand_aliases +unset PATH JAVA_HOME LD_LIBRARY_PATH +function abort { + echo "aborting: $@" 1>&2 + exit 1 +} +function default { + export INSTANCE_NAME="jboss" +export INSTANCE_HOME="/usr/local/jboss" +export LOG_DIR="/usr/local/jboss" + return 0 +} +function jboss { + export JBOSS_HOME="/usr/local/jboss" + return 0 +} +function findPid { + unset FOUND_PID; + [ $# -eq 1 ] || { + abort "findPid requires a parameter of pattern to match" + return 1 + } + local PATTERN="$1"; shift + local _FOUND=`ps auxwww|grep "$PATTERN"|grep -v " $0"|grep -v grep|awk '{print $2}'` + [ -n "$_FOUND" ] && { + export FOUND_PID=$_FOUND + return 0 + } || { + return 1 + } +} +function forget { + unset FOUND_PID; + [ $# -eq 3 ] || { + abort "forget requires parameters INSTANCE_NAME SCRIPT LOG_DIR" + return 1 + } + local INSTANCE_NAME="$1"; shift + local SCRIPT="$1"; shift + local LOG_DIR="$1"; shift + mkdir -p $LOG_DIR + findPid $INSTANCE_NAME + [ -n "$FOUND_PID" ] && { + echo $INSTANCE_NAME already running pid [$FOUND_PID] + } || { + nohup $SCRIPT >$LOG_DIR/stdout.log 2>$LOG_DIR/stderr.log & + sleep 1 + findPid $INSTANCE_NAME + [ -n "$FOUND_PID" ] || abort "$INSTANCE_NAME did not start" + } + return 0 +} +export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin +case $1 in +init) + default || exit 1 + jboss || exit 1 + mkdir -p ~/.ssh + cat >> ~/.ssh/authorized_keys <<'END_OF_FILE' +ssh-rsa +END_OF_FILE + chmod 600 ~/.ssh/authorized_keys + echo nameserver 208.67.222.222 >> /etc/resolv.conf + cp /etc/apt/sources.list /etc/apt/sources.list.old + sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list + apt-get update -y -qq + apt-get install -f -y -qq --force-yes curl + apt-get install -f -y -qq --force-yes unzip + apt-get install -f -y -qq --force-yes openjdk-6-jdk + + (mkdir -p /usr/local &&cd /usr/local &&curl -X GET -s --retry 20 http://superb-sea2.dl.sourceforge.net/project/jboss/JBoss/JBoss-5.0.0.CR2/jboss-5.0.0.CR2-jdk6.zip >extract.zip && unzip -o -qq extract.zip&& rm extract.zip) + mkdir -p /usr/local/jboss + mv /usr/local/jboss-5.0.0.CR2/* /usr/local/jboss + mkdir -p $INSTANCE_HOME + + # create runscript header + cat > $INSTANCE_HOME/jboss.sh <> $INSTANCE_HOME/jboss.sh <<'END_OF_SCRIPT' +cd $INSTANCE_HOME +java -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.endorsed.dirs=lib/endorsed -Djboss.bind.address=0.0.0.0 -classpath bin/run.jar org.jboss.Main +END_OF_SCRIPT + + # add runscript footer + cat >> $INSTANCE_HOME/jboss.sh <<'END_OF_SCRIPT' +exit 0 +END_OF_SCRIPT + + chmod u+x $INSTANCE_HOME/jboss.sh + ;; +status) + default || exit 1 + findPid $INSTANCE_NAME || exit 1 + echo [$FOUND_PID] + ;; +stop) + default || exit 1 + findPid $INSTANCE_NAME || exit 1 + [ -n "$FOUND_PID" ] && { + echo stopping $FOUND_PID + kill -9 $FOUND_PID + } + ;; +start) + default || exit 1 + forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1 + ;; +tail) + default || exit 1 + tail $LOG_DIR/stdout.log + ;; +tailerr) + default || exit 1 + tail $LOG_DIR/stderr.log + ;; +run) + default || exit 1 + $INSTANCE_HOME/$INSTANCE_NAME.sh + ;; +esac +exit 0 diff --git a/compute/src/test/resources/runscript.sh b/compute/src/test/resources/runscript.sh index a23d1c38fd..84f034da27 100644 --- a/compute/src/test/resources/runscript.sh +++ b/compute/src/test/resources/runscript.sh @@ -79,8 +79,10 @@ cd $INSTANCE_HOME echo nameserver 208.67.222.222 >> /etc/resolv.conf cp /etc/apt/sources.list /etc/apt/sources.list.old sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list -apt-get update -apt-get install -f -y --force-yes openjdk-6-jdk +apt-get update -y -qq +apt-get install -f -y -qq --force-yes curl +apt-get install -f -y -qq --force-yes unzip +apt-get install -f -y -qq --force-yes openjdk-6-jdk END_OF_SCRIPT diff --git a/extensions/ssh/jsch/src/main/java/org/jclouds/ssh/jsch/JschSshClient.java b/extensions/ssh/jsch/src/main/java/org/jclouds/ssh/jsch/JschSshClient.java index 343cd09550..83f3b54838 100644 --- a/extensions/ssh/jsch/src/main/java/org/jclouds/ssh/jsch/JschSshClient.java +++ b/extensions/ssh/jsch/src/main/java/org/jclouds/ssh/jsch/JschSshClient.java @@ -132,15 +132,7 @@ public class JschSshClient implements SshClient { public Payload get(String path) { checkNotNull(path, "path"); - checkConnected(); - logger.debug("%s@%s:%d: Opening sftp Channel.", username, host, port); - ChannelSftp sftp = null; - try { - sftp = (ChannelSftp) session.openChannel("sftp"); - sftp.connect(); - } catch (JSchException e) { - throw new SshException(String.format("%s@%s:%d: Error connecting to sftp.", username, host, port), e); - } + ChannelSftp sftp = getSftp(); try { return Payloads.newInputStreamPayload(new CloseFtpChannelOnCloseInputStream(sftp.get(path), sftp)); } catch (SftpException e) { @@ -148,10 +140,26 @@ public class JschSshClient implements SshClient { } } + @Override public void put(String path, Payload contents) { checkNotNull(path, "path"); checkNotNull(contents, "contents"); + ChannelSftp sftp = getSftp(); + try { + sftp.put(contents.getInput(), path); + } catch (SftpException e) { + throw new SshException(String.format("%s@%s:%d: Error putting path: %s", username, host, port, path), e); + } finally { + Closeables.closeQuietly(contents); + } + } + @Override + public void put(String path, String contents) { + put(path, Payloads.newStringPayload(checkNotNull(contents, "contents"))); + } + + private ChannelSftp getSftp() { checkConnected(); logger.debug("%s@%s:%d: Opening sftp Channel.", username, host, port); ChannelSftp sftp = null; @@ -161,13 +169,7 @@ public class JschSshClient implements SshClient { } catch (JSchException e) { throw new SshException(String.format("%s@%s:%d: Error connecting to sftp.", username, host, port), e); } - try { - sftp.put(contents.getInput(), path); - } catch (SftpException e) { - throw new SshException(String.format("%s@%s:%d: Error putting path: %s", username, host, port, path), e); - } finally { - Closeables.closeQuietly(contents); - } + return sftp; } private void checkConnected() { diff --git a/extensions/ssh/jsch/src/test/java/org/jclouds/ssh/jsch/JschSshClientLiveTest.java b/extensions/ssh/jsch/src/test/java/org/jclouds/ssh/jsch/JschSshClientLiveTest.java index 447152bd06..dd02cf693f 100644 --- a/extensions/ssh/jsch/src/test/java/org/jclouds/ssh/jsch/JschSshClientLiveTest.java +++ b/extensions/ssh/jsch/src/test/java/org/jclouds/ssh/jsch/JschSshClientLiveTest.java @@ -46,8 +46,8 @@ import com.google.inject.Injector; */ @Test(groups = "live", testName = "ssh.JschSshClientLiveTest") public class JschSshClientLiveTest { - protected static final String sshHost = System.getProperty("test.ssh.host"); - protected static final String sshPort = System.getProperty("test.ssh.port"); + protected static final String sshHost = System.getProperty("test.ssh.host", "localhost"); + protected static final String sshPort = System.getProperty("test.ssh.port", "22"); protected static final String sshUser = System.getProperty("test.ssh.username"); protected static final String sshPass = System.getProperty("test.ssh.password"); protected static final String sshKeyFile = System.getProperty("test.ssh.keyfile"); @@ -55,7 +55,7 @@ public class JschSshClientLiveTest { @BeforeGroups(groups = { "live" }) public SshClient setupClient() throws NumberFormatException, FileNotFoundException, IOException { - int port = (sshPort != null) ? Integer.parseInt(sshPort) : 22; + int port = Integer.parseInt(sshPort); if (sshUser == null || ((sshPass == null || sshPass.trim().equals("")) && (sshKeyFile == null || sshKeyFile.trim().equals(""))) || sshUser.trim().equals("")) { @@ -99,6 +99,11 @@ public class JschSshClientLiveTest { return null; } + @Override + public void put(String path, String contents) { + + } + }; } else { Injector i = Guice.createInjector(new JschSshClientModule()); diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/InitBuilder.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/InitBuilder.java index f7ec65f6e0..361c2aa94a 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/InitBuilder.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/InitBuilder.java @@ -19,6 +19,7 @@ package org.jclouds.scriptbuilder; +import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.scriptbuilder.domain.Statements.call; import static org.jclouds.scriptbuilder.domain.Statements.createRunScript; import static org.jclouds.scriptbuilder.domain.Statements.findPid; @@ -31,8 +32,10 @@ import static org.jclouds.scriptbuilder.domain.Statements.switchArg; import java.util.Map; import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.scriptbuilder.domain.StatementList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; /** @@ -42,9 +45,21 @@ import com.google.common.collect.Iterables; */ public class InitBuilder extends ScriptBuilder { - @SuppressWarnings("unchecked") + private final String instanceName; + private final String instanceHome; + private final String logDir; + public InitBuilder(String instanceName, String instanceHome, String logDir, Map variables, Iterable statements) { + this(instanceName, instanceHome, logDir, variables, ImmutableSet.of(), statements); + } + + @SuppressWarnings("unchecked") + public InitBuilder(String instanceName, String instanceHome, String logDir, Map variables, + Iterable initStatements, Iterable statements) { + this.instanceName = checkNotNull(instanceName, "instanceName"); + this.instanceHome = checkNotNull(instanceHome, "instanceHome"); + this.logDir = checkNotNull(logDir, "logDir"); Map defaultVariables = ImmutableMap.of("instanceName", instanceName, "instanceHome", instanceHome, "logDir", logDir); addEnvironmentVariableScope("default", defaultVariables) @@ -56,7 +71,7 @@ public class InitBuilder extends ScriptBuilder { .put( "init", newStatementList(call("default"), call(instanceName), - createRunScript( + new StatementList(initStatements), createRunScript( instanceName,// TODO: convert // so // that @@ -98,4 +113,58 @@ public class InitBuilder extends ScriptBuilder { interpret("{varl}INSTANCE_HOME{varr}{fs}{varl}INSTANCE_NAME{varr}.{sh}{lf}"))) .build())); } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((instanceHome == null) ? 0 : instanceHome.hashCode()); + result = prime * result + ((instanceName == null) ? 0 : instanceName.hashCode()); + result = prime * result + ((logDir == null) ? 0 : logDir.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + InitBuilder other = (InitBuilder) obj; + if (instanceHome == null) { + if (other.instanceHome != null) + return false; + } else if (!instanceHome.equals(other.instanceHome)) + return false; + if (instanceName == null) { + if (other.instanceName != null) + return false; + } else if (!instanceName.equals(other.instanceName)) + return false; + if (logDir == null) { + if (other.logDir != null) + return false; + } else if (!logDir.equals(other.logDir)) + return false; + return true; + } + + public String getInstanceName() { + return instanceName; + } + + public String getInstanceHome() { + return instanceHome; + } + + public String getLogDir() { + return logDir; + } + + @Override + public String toString() { + return "[instanceName=" + instanceName + ", instanceHome=" + instanceHome + ", logDir=" + logDir + "]"; + } } \ No newline at end of file diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java index dbcc168b7a..4821342d0f 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java @@ -50,7 +50,7 @@ public class AuthorizeRSAPublicKey implements Statement { checkNotNull(family, "family"); if (family == OsFamily.WINDOWS) throw new UnsupportedOperationException("windows not yet implemented"); - return new StatementList(ImmutableList.of(exec("{md} .ssh"), appendFile(".ssh/authorized_keys", Splitter.on('\n') - .split(publicKey)), exec("chmod 600 .ssh/authorized_keys"))).render(family); + return new StatementList(ImmutableList.of(exec("{md} ~/.ssh"), appendFile("~/.ssh/authorized_keys", Splitter.on('\n') + .split(publicKey)), exec("chmod 600 ~/.ssh/authorized_keys"))).render(family); } } \ No newline at end of file diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java index 78763e5ec2..635affb406 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java @@ -51,7 +51,7 @@ public class InstallRSAPrivateKey implements Statement { checkNotNull(family, "family"); if (family == OsFamily.WINDOWS) throw new UnsupportedOperationException("windows not yet implemented"); - return new StatementList(ImmutableList.of(exec("{md} .ssh"), rm(".ssh/id_rsa"), appendFile(".ssh/id_rsa", Splitter.on('\n') - .split(privateKey)), exec("chmod 600 .ssh/id_rsa"))).render(family); + return new StatementList(ImmutableList.of(exec("{md} ~/.ssh"), rm("~/.ssh/id_rsa"), appendFile("~/.ssh/id_rsa", Splitter.on('\n') + .split(privateKey)), exec("chmod 600 ~/.ssh/id_rsa"))).render(family); } } \ No newline at end of file diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectory.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectory.java index fe89f829cc..6da722a60a 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectory.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectory.java @@ -48,7 +48,7 @@ public class UnzipHttpResponseIntoDirectory extends InterpretableStatement { public UnzipHttpResponseIntoDirectory(String method, URI endpoint, Multimap headers, String dir) { super( format( - "({md} %s &&{cd} %s &&curl -X %s -s --retry 20 %s %s >extract.zip && unzip -qq extract.zip&& rm extract.zip)\n", + "({md} %s &&{cd} %s &&curl -X %s -s --retry 20 %s %s >extract.zip && unzip -o -qq extract.zip&& rm extract.zip)\n", dir, dir, method, Joiner.on(' ').join( transform(headers.entries(), new Function, String>() { diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CopyOfAuthorizeRSAPublicKeyTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKeyTest.java similarity index 87% rename from scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CopyOfAuthorizeRSAPublicKeyTest.java rename to scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKeyTest.java index 68b6d4a35f..9cfca03ccf 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CopyOfAuthorizeRSAPublicKeyTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKeyTest.java @@ -27,14 +27,14 @@ import org.testng.annotations.Test; * @author Adrian Cole */ @Test(groups = "unit", testName = "scriptbuilder.AuthorizeRSAPublicKeyTest") -public class CopyOfAuthorizeRSAPublicKeyTest { +public class AuthorizeRSAPublicKeyTest { AuthorizeRSAPublicKey auth = new AuthorizeRSAPublicKey("ssh-dss AAAAB"); public void testAuthorizeRSAPublicKeyUNIX() { assertEquals( auth.render(OsFamily.UNIX), - "mkdir -p .ssh\ncat >> .ssh/authorized_keys <<'END_OF_FILE'\nssh-dss AAAAB\nEND_OF_FILE\nchmod 600 .ssh/authorized_keys\n"); } + "mkdir -p ~/.ssh\ncat >> ~/.ssh/authorized_keys <<'END_OF_FILE'\nssh-dss AAAAB\nEND_OF_FILE\nchmod 600 ~/.ssh/authorized_keys\n"); } @Test(expectedExceptions = UnsupportedOperationException.class) public void testAuthorizeRSAPublicKeyWINDOWS() { diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKeyTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKeyTest.java index 9775282f4a..0d0d2d8e83 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKeyTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKeyTest.java @@ -34,7 +34,7 @@ public class InstallRSAPrivateKeyTest { public void testInstallRSAPrivateKeyUNIX() { assertEquals( key.render(OsFamily.UNIX), - "mkdir -p .ssh\nrm .ssh/id_rsa\ncat >> .ssh/id_rsa <<'END_OF_FILE'\n-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n\nEND_OF_FILE\nchmod 600 .ssh/id_rsa\n"); + "mkdir -p ~/.ssh\nrm ~/.ssh/id_rsa\ncat >> ~/.ssh/id_rsa <<'END_OF_FILE'\n-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n\nEND_OF_FILE\nchmod 600 ~/.ssh/id_rsa\n"); } @Test(expectedExceptions = UnsupportedOperationException.class) diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectoryToTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectoryToTest.java index 63afb46cf7..6171139b76 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectoryToTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/UnzipHttpResponseIntoDirectoryToTest.java @@ -42,7 +42,7 @@ public class UnzipHttpResponseIntoDirectoryToTest { public void testUnzipHttpResponseIntoDirectoryUNIX() { assertEquals( jboss.render(OsFamily.UNIX), - "(mkdir -p /tmp &&cd /tmp &&curl -X GET -s --retry 20 http://superb-sea2.dl.sourceforge.net/project/jboss/JBoss/JBoss-5.0.0.CR2/jboss-5.0.0.CR2-jdk6.zip >extract.zip && unzip -qq extract.zip&& rm extract.zip)\n"); + "(mkdir -p /tmp &&cd /tmp &&curl -X GET -s --retry 20 http://superb-sea2.dl.sourceforge.net/project/jboss/JBoss/JBoss-5.0.0.CR2/jboss-5.0.0.CR2-jdk6.zip >extract.zip && unzip -o -qq extract.zip&& rm extract.zip)\n"); } public void testUnzipHttpResponseIntoDirectoryWINDOWS() { From f425a28b80e6ff7ccce18fae012ebb9ffd1a5c57 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Fri, 24 Sep 2010 17:59:05 -0700 Subject: [PATCH 5/6] fixed jboss port binding --- compute/src/test/java/org/jclouds/compute/RunScriptData.java | 2 +- compute/src/test/resources/initscript_with_jboss.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compute/src/test/java/org/jclouds/compute/RunScriptData.java b/compute/src/test/java/org/jclouds/compute/RunScriptData.java index ec7a3326d9..4b5c664ccb 100644 --- a/compute/src/test/java/org/jclouds/compute/RunScriptData.java +++ b/compute/src/test/java/org/jclouds/compute/RunScriptData.java @@ -68,7 +68,7 @@ public class RunScriptData { jbossVersion, jboss)), "/usr/local"), exec("{md} " + jbossHome), exec("mv /usr/local/jboss-" + jbossVersion + "/* " + jbossHome)), ImmutableList - . of(interpret("java -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.endorsed.dirs=lib/endorsed -Djboss.bind.address=0.0.0.0 -classpath bin/run.jar org.jboss.Main"))); + . of(interpret("java -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.endorsed.dirs=lib/endorsed -classpath bin/run.jar org.jboss.Main -b 0.0.0.0"))); return toReturn; } diff --git a/compute/src/test/resources/initscript_with_jboss.sh b/compute/src/test/resources/initscript_with_jboss.sh index f28900a506..dc94b9b7ac 100644 --- a/compute/src/test/resources/initscript_with_jboss.sh +++ b/compute/src/test/resources/initscript_with_jboss.sh @@ -94,7 +94,7 @@ END_OF_SCRIPT # add desired commands from the user cat >> $INSTANCE_HOME/jboss.sh <<'END_OF_SCRIPT' cd $INSTANCE_HOME -java -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.endorsed.dirs=lib/endorsed -Djboss.bind.address=0.0.0.0 -classpath bin/run.jar org.jboss.Main +java -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.endorsed.dirs=lib/endorsed -classpath bin/run.jar org.jboss.Main -b 0.0.0.0 END_OF_SCRIPT # add runscript footer From 47697d6f7e3e982eb443b4b60a677cff1cecfdd4 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sun, 26 Sep 2010 14:02:31 +0100 Subject: [PATCH 6/6] fixed copy on template as it was missing parameters --- .../compute/domain/internal/TemplateBuilderImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java index 5c0599b453..e872baf83e 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java @@ -815,6 +815,12 @@ public class TemplateBuilderImpl implements TemplateBuilder { to.withMetadata(); if (!from.shouldBlockUntilRunning()) to.blockUntilRunning(false); + if (!from.shouldBlockOnComplete()) + to.blockOnComplete(false); + if (from.getOverrideCredentials() != null) + to.withOverridingCredentials(from.getOverrideCredentials()); + if (from.getTaskName() != null) + to.nameTask(from.getTaskName()); } @VisibleForTesting