From 3ae7dfb1b79f26b0be0899a78cd44305cfdac635 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Fri, 27 Aug 2010 13:33:32 -0700 Subject: [PATCH 01/63] changed default test so that they work with self-signed certs --- .../compute/BaseComputeServiceLiveTest.java | 111 +++++++++--------- 1 file changed, 58 insertions(+), 53 deletions(-) diff --git a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java index afe92c5120..4f776095cf 100755 --- a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java @@ -43,6 +43,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.util.Map; import java.util.NoSuchElementException; +import java.util.Properties; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -50,6 +51,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import org.jclouds.Constants; import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.Image; @@ -92,32 +94,32 @@ 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(); + .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(); + .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(); + .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")// + .append("sudo zypper install java-1.6.0-openjdk-devl\n")// + .toString(); abstract public void setServiceDefaults(); @@ -165,7 +167,7 @@ public abstract class BaseComputeServiceLiveTest { String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8); assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret; return ImmutableMap. of("private", secret, "public", Files.toString(new File(secretKeyFile - + ".pub"), Charsets.UTF_8)); + + ".pub"), Charsets.UTF_8)); } protected void setupCredentials() { @@ -180,8 +182,11 @@ public abstract class BaseComputeServiceLiveTest { private void initializeContextAndClient() throws IOException { if (context != null) context.close(); + Properties props = new Properties(); + props.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); + props.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); context = new ComputeServiceContextFactory().createContext(provider, identity, credential, ImmutableSet.of( - new Log4JLoggingModule(), getSshModule())); + new Log4JLoggingModule(), getSshModule()), props); client = context.getComputeService(); } @@ -200,7 +205,7 @@ public abstract class BaseComputeServiceLiveTest { ComputeServiceContext context = null; try { context = new ComputeServiceContextFactory().createContext(provider, "MOMMA", "MIA", ImmutableSet - . of(new Log4JLoggingModule())); + . of(new Log4JLoggingModule())); context.getComputeService().listNodes(); } finally { if (context != null) @@ -239,7 +244,7 @@ public abstract class BaseComputeServiceLiveTest { OperatingSystem os = get(nodes, 0).getOperatingSystem(); try { Map responses = runScriptWithCreds(tag, os, new Credentials( - good.identity, "romeo")); + good.identity, "romeo")); assert false : "shouldn't pass with a bad password\n" + responses; } catch (RunScriptOnNodesException e) { assert getRootCause(e).getMessage().contains("Auth fail") : e; @@ -294,8 +299,8 @@ public abstract class BaseComputeServiceLiveTest { template = buildTemplate(client.templateBuilder()); template.getOptions().installPrivateKey(newStringPayload(keyPair.get("private"))).authorizePublicKey( - newStringPayload(keyPair.get("public"))).runScript( - newStringPayload(buildScript(template.getImage().getOperatingSystem()))); + newStringPayload(keyPair.get("public"))).runScript( + newStringPayload(buildScript(template.getImage().getOperatingSystem()))); } protected void checkImageIdMatchesTemplate(NodeMetadata node) { @@ -306,8 +311,8 @@ public abstract class BaseComputeServiceLiveTest { protected void checkOsMatchesTemplate(NodeMetadata node) { if (node.getOperatingSystem() != null) assert node.getOperatingSystem().getFamily().equals(template.getImage().getOperatingSystem().getFamily()) : String - .format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(), node - .getOperatingSystem()); + .format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(), node + .getOperatingSystem()); } void assertLocationSameOrChild(Location test, Location expected) { @@ -332,10 +337,10 @@ public abstract class BaseComputeServiceLiveTest { } protected Map runScriptWithCreds(final String tag, OperatingSystem os, - Credentials creds) throws RunScriptOnNodesException { + Credentials creds) throws RunScriptOnNodesException { try { return client.runScriptOnNodesMatching(runningWithTag(tag), newStringPayload(buildScript(os)), - overrideCredentialsWith(creds)); + overrideCredentialsWith(creds)); } catch (SshException e) { throw e; } @@ -393,7 +398,7 @@ public abstract class BaseComputeServiceLiveTest { protected void assertNodeZero(Set metadataSet) { assert metadataSet.size() == 0 : String.format("nodes left in set: [%s] which didn't match set: [%s]", - metadataSet, nodes); + metadataSet, nodes); } @Test(enabled = true, dependsOnMethods = "testGet") @@ -454,26 +459,26 @@ public abstract class BaseComputeServiceLiveTest { assert location != location.getParent() : location; assert location.getScope() != null : location; switch (location.getScope()) { - case PROVIDER: - assertProvider(location); - break; - case REGION: - assertProvider(location.getParent()); - break; - case ZONE: - Location provider = location.getParent().getParent(); - // zone can be a direct descendant of provider - if (provider == null) - provider = location.getParent(); - assertProvider(provider); - break; - case HOST: - Location provider2 = location.getParent().getParent().getParent(); - // zone can be a direct descendant of provider - if (provider2 == null) - provider2 = location.getParent().getParent(); - assertProvider(provider2); - break; + case PROVIDER: + assertProvider(location); + break; + case REGION: + assertProvider(location.getParent()); + break; + case ZONE: + Location provider = location.getParent().getParent(); + // zone can be a direct descendant of provider + if (provider == null) + provider = location.getParent(); + assertProvider(provider); + break; + case HOST: + Location provider2 = location.getParent().getParent().getParent(); + // zone can be a direct descendant of provider + if (provider2 == null) + provider2 = location.getParent().getParent(); + assertProvider(provider2); + break; } } } From b6fbc29c830e9e8e7c229c378bf02df75aab7d9b Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Fri, 27 Aug 2010 13:33:55 -0700 Subject: [PATCH 02/63] Issue 280: added orglist command --- .../java/domain/VCloudLoginAsyncClient.java | 2 +- .../org/jclouds/vcloud/VCloudAsyncClient.java | 39 ++- .../java/org/jclouds/vcloud/VCloudClient.java | 117 +++++--- .../config/CommonVCloudRestClientModule.java | 246 ++++++++-------- .../domain/InstantiateVAppTemplateParams.java | 99 +++++++ .../org/jclouds/vcloud/endpoints/OrgList.java | 40 +++ .../jclouds/vcloud/VCloudAsyncClientTest.java | 264 ++++++++---------- .../jclouds/vcloud/VCloudClientLiveTest.java | 13 +- 8 files changed, 497 insertions(+), 323 deletions(-) create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/domain/InstantiateVAppTemplateParams.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/endpoints/OrgList.java diff --git a/vcloud/core/src/main/java/domain/VCloudLoginAsyncClient.java b/vcloud/core/src/main/java/domain/VCloudLoginAsyncClient.java index fbd3d86c98..0e7401ddb6 100644 --- a/vcloud/core/src/main/java/domain/VCloudLoginAsyncClient.java +++ b/vcloud/core/src/main/java/domain/VCloudLoginAsyncClient.java @@ -44,7 +44,7 @@ import com.google.common.util.concurrent.ListenableFuture; public interface VCloudLoginAsyncClient { /** - * This request returns a token to use in subsequent requests. After ten minutes of inactivity, + * This request returns a token to use in subsequent requests. After 30 minutes of inactivity, * the token expires and you have to request a new token with this call. */ @POST diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java index 6bb34b7983..1e0fc1adfd 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java @@ -27,6 +27,7 @@ import static org.jclouds.vcloud.VCloudMediaType.VAPP_XML; import static org.jclouds.vcloud.VCloudMediaType.VM_XML; import java.net.URI; +import java.util.Map; import javax.annotation.Nullable; import javax.ws.rs.Consumes; @@ -38,6 +39,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.jclouds.predicates.validators.DnsNameValidator; +import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; @@ -52,16 +54,19 @@ import org.jclouds.vcloud.binders.BindCloneVAppParamsToXmlPayload; import org.jclouds.vcloud.binders.BindDeployVAppParamsToXmlPayload; import org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload; import org.jclouds.vcloud.binders.BindUndeployVAppParamsToXmlPayload; +import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VAppTemplate; import org.jclouds.vcloud.domain.Vm; import org.jclouds.vcloud.domain.ovf.OvfEnvelope; +import org.jclouds.vcloud.endpoints.OrgList; import org.jclouds.vcloud.filters.SetVCloudTokenCookie; import org.jclouds.vcloud.functions.OrgNameCatalogNameVAppTemplateNameToEndpoint; import org.jclouds.vcloud.functions.OrgNameVDCNameResourceEntityNameToEndpoint; import org.jclouds.vcloud.options.CloneVAppOptions; import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; +import org.jclouds.vcloud.xml.OrgListHandler; import org.jclouds.vcloud.xml.TaskHandler; import org.jclouds.vcloud.xml.VAppHandler; import org.jclouds.vcloud.xml.VAppTemplateHandler; @@ -74,11 +79,21 @@ import com.google.common.util.concurrent.ListenableFuture; * Provides access to VCloud resources via their REST API. *

* - * @see + * @see * @author Adrian Cole */ @RequestFilters(SetVCloudTokenCookie.class) public interface VCloudAsyncClient extends CommonVCloudAsyncClient { + /** + * + * @see VCloudClient#listOrgs + */ + @GET + @Endpoint(OrgList.class) + @XMLResponseParser(OrgListHandler.class) + @Consumes(VCloudMediaType.ORGLIST_XML) + ListenableFuture> listOrgs(); /** * @see VCloudClient#getVAppTemplate @@ -107,9 +122,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VAppTemplateHandler.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture findVAppTemplateInOrgCatalogNamed( - @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String orgName, - @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String catalogName, - @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String itemName); + @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String orgName, + @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String catalogName, + @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String itemName); /** * @see VCloudClient#instantiateVAppTemplateInVDC @@ -121,9 +136,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VAppHandler.class) @MapBinder(BindInstantiateVAppTemplateParamsToXmlPayload.class) ListenableFuture instantiateVAppTemplateInVDC(@EndpointParam URI vdc, - @MapPayloadParam("template") URI template, - @MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, - InstantiateVAppTemplateOptions... options); + @MapPayloadParam("template") URI template, + @MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, + InstantiateVAppTemplateOptions... options); /** * @see VCloudClient#cloneVAppInVDC @@ -135,8 +150,8 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(TaskHandler.class) @MapBinder(BindCloneVAppParamsToXmlPayload.class) ListenableFuture cloneVAppInVDC(@EndpointParam URI vdc, @MapPayloadParam("vApp") URI toClone, - @MapPayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, - CloneVAppOptions... options); + @MapPayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, + CloneVAppOptions... options); /** * @see VCloudClient#findVAppInOrgVDCNamed @@ -146,9 +161,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VAppHandler.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture findVAppInOrgVDCNamed( - @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName, - @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName, - @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String vAppName); + @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName, + @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName, + @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String vAppName); /** * @see VCloudClient#getVApp diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java index 71ca38ced2..ac16a52d7c 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java @@ -20,12 +20,14 @@ package org.jclouds.vcloud; import java.net.URI; +import java.util.Map; import java.util.NoSuchElementException; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; import org.jclouds.concurrent.Timeout; +import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VAppTemplate; @@ -38,11 +40,20 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; * Provides access to VCloud resources via their REST API. *

* - * @see + * @see * @author Adrian Cole */ @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) public interface VCloudClient extends CommonVCloudClient { + /** + * The response to a login request includes a list of the organizations to + * which the authenticated user has access. + * + * @return organizations indexed by name + */ + Map listOrgs(); VApp instantiateVAppTemplateInVDC(URI vDC, URI template, String appName, InstantiateVAppTemplateOptions... options); @@ -53,8 +64,9 @@ public interface VCloudClient extends CommonVCloudClient { OvfEnvelope getOvfEnvelopeForVAppTemplate(URI vAppTemplate); /** - * returns the vapp template corresponding to a catalog item in the catalog associated with the - * specified name. Note that the org and catalog parameters can be null to choose default. + * returns the vapp template corresponding to a catalog item in the catalog + * associated with the specified name. Note that the org and catalog + * parameters can be null to choose default. * * @param orgName * organization name, or null for the default @@ -64,10 +76,11 @@ public interface VCloudClient extends CommonVCloudClient { * item you wish to lookup * * @throws NoSuchElementException - * if you specified an org, catalog, or catalog item name that isn't present + * if you specified an org, catalog, or catalog item name that + * isn't present */ VAppTemplate findVAppTemplateInOrgCatalogNamed(@Nullable String orgName, @Nullable String catalogName, - String itemName); + String itemName); VApp findVAppInOrgVDCNamed(@Nullable String orgName, @Nullable String catalogName, String vAppName); @@ -76,100 +89,112 @@ public interface VCloudClient extends CommonVCloudClient { Vm getVm(URI vm); /** - * To deploy a vApp, the client makes a request to its action/deploy URL. Deploying a vApp - * automatically deploys all of the virtual machines it contains. To deploy a virtual machine, - * the client makes a request to its action/deploy URL. + * To deploy a vApp, the client makes a request to its action/deploy URL. + * Deploying a vApp automatically deploys all of the virtual machines it + * contains. To deploy a virtual machine, the client makes a request to its + * action/deploy URL. *

- * Deploying a Vm implicitly deploys the parent vApp if that vApp is not already deployed. + * Deploying a Vm implicitly deploys the parent vApp if that vApp is not + * already deployed. */ Task deployVAppOrVm(URI vAppOrVmId); /** - * like {@link #deployVAppOrVm(URI)}, except deploy transistions to power on state + * like {@link #deployVAppOrVm(URI)}, except deploy transistions to power on + * state * */ Task deployAndPowerOnVAppOrVm(URI vAppOrVmId); /** - * Undeploying a vApp powers off or suspends any running virtual machines it contains, then frees - * the resources reserved for the vApp and sets the vApp’s deploy attribute to a value of false - * to indicate that it is not deployed. + * Undeploying a vApp powers off or suspends any running virtual machines it + * contains, then frees the resources reserved for the vApp and sets the + * vApp’s deploy attribute to a value of false to indicate that it is not + * deployed. *

- * Undeploying a virtual machine powers off or suspends the virtual machine, then frees the - * resources reserved for it and sets the its deploy attribute to a value of false to indicate - * that it is not deployed. This operation has no effect on the containing vApp. + * Undeploying a virtual machine powers off or suspends the virtual machine, + * then frees the resources reserved for it and sets the its deploy attribute + * to a value of false to indicate that it is not deployed. This operation + * has no effect on the containing vApp. *

NOTE

- * Using this method will simply power off the vms. In order to save their state, use - * {@link #undeployAndSaveStateOfVAppOrVm} + * Using this method will simply power off the vms. In order to save their + * state, use {@link #undeployAndSaveStateOfVAppOrVm} * */ Task undeployVAppOrVm(URI vAppOrVmId); /** - * like {@link #undeployVAppOrVm(URI)}, where the undeployed virtual machines are suspended and - * their suspend state saved + * like {@link #undeployVAppOrVm(URI)}, where the undeployed virtual machines + * are suspended and their suspend state saved * */ Task undeployAndSaveStateOfVAppOrVm(URI vAppOrVmId); /** - * A powerOn request to a vApp URL powers on all of the virtual machines in the vApp, as - * specified in the vApp’s StartupSection field. + * A powerOn request to a vApp URL powers on all of the virtual machines in + * the vApp, as specified in the vApp’s StartupSection field. *

- * A powerOn request to a virtual machine URL powers on the specified virtual machine and forces - * deployment of the parent vApp. + * A powerOn request to a virtual machine URL powers on the specified virtual + * machine and forces deployment of the parent vApp. *

- *

NOTE

A powerOn request to a vApp or virtual machine that is undeployed forces - * deployment. + *

NOTE

A powerOn request to a vApp or virtual machine that is + * undeployed forces deployment. */ Task powerOnVAppOrVm(URI vAppOrVmId); /** - * A powerOff request to a vApp URL powers off all of the virtual machines in the vApp, as - * specified in its StartupSection field. + * A powerOff request to a vApp URL powers off all of the virtual machines in + * the vApp, as specified in its StartupSection field. *

- * A powerOff request to a virtual machine URL powers off the specified virtual machine. + * A powerOff request to a virtual machine URL powers off the specified + * virtual machine. */ Task powerOffVAppOrVm(URI vAppOrVmId); /** - * A shutdown request to a vApp URL shuts down all of the virtual machines in the vApp, as - * specified in its StartupSection field. + * A shutdown request to a vApp URL shuts down all of the virtual machines in + * the vApp, as specified in its StartupSection field. *

- * A shutdown request to a virtual machine URL shuts down the specified virtual machine. + * A shutdown request to a virtual machine URL shuts down the specified + * virtual machine. *

- *

NOTENOTE - * A reset request to a virtual machine URL resets the specified virtual machine. + * A reset request to a virtual machine URL resets the specified virtual + * machine. */ Task resetVAppOrVm(URI vAppOrVmId); /** - * A reboot request to a vApp URL reboots all of the virtual machines in the vApp, as specified - * in its StartupSection field. + * A reboot request to a vApp URL reboots all of the virtual machines in the + * vApp, as specified in its StartupSection field. *

- * A reboot request to a virtual machine URL reboots the specified virtual machine. + * A reboot request to a virtual machine URL reboots the specified virtual + * machine. *

- *

NOTE

Because this request sends a signal to the guest OS, the vCloud API cannot track - * the progress or verify the result of the requested operation. Hence, void is returned + *

NOTE

Because this request sends a signal to the guest OS, the + * vCloud API cannot track the progress or verify the result of the requested + * operation. Hence, void is returned */ void rebootVAppOrVm(URI vAppOrVmId); /** - * A suspend request to a vApp URL suspends all of the virtual machines in the vApp, as specified - * in its StartupSection field. + * A suspend request to a vApp URL suspends all of the virtual machines in + * the vApp, as specified in its StartupSection field. *

- * A suspend request to a virtual machine URL suspends the specified virtual machine. + * A suspend request to a virtual machine URL suspends the specified virtual + * machine. */ Task suspendVAppOrVm(URI vAppOrVmId); - + Task deleteVApp(URI vAppId); } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/config/CommonVCloudRestClientModule.java b/vcloud/core/src/main/java/org/jclouds/vcloud/config/CommonVCloudRestClientModule.java index 4677ca2d5a..68fed093c0 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/config/CommonVCloudRestClientModule.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/config/CommonVCloudRestClientModule.java @@ -71,6 +71,7 @@ import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.VCloudSession; import org.jclouds.vcloud.domain.VDC; import org.jclouds.vcloud.endpoints.Network; +import org.jclouds.vcloud.endpoints.OrgList; import org.jclouds.vcloud.endpoints.TasksList; import org.jclouds.vcloud.functions.AllCatalogItemsInCatalog; import org.jclouds.vcloud.functions.AllCatalogsInOrg; @@ -94,14 +95,15 @@ import com.google.inject.name.Names; import domain.VCloudVersionsAsyncClient; /** - * Configures the VCloud authentication service connection, including logging and http transport. + * Configures the VCloud authentication service connection, including logging + * and http transport. * * @author Adrian Cole */ @RequiresHttp @ConfiguresRestClient public class CommonVCloudRestClientModule extends - RestClientModule { + RestClientModule { public CommonVCloudRestClientModule(Class syncClientType, Class asyncClientType) { super(syncClientType, asyncClientType); @@ -144,20 +146,20 @@ public class CommonVCloudRestClientModule> provideVDCtoORG(@Named(PROPERTY_SESSION_INTERVAL) long seconds, - final Supplier> orgToVDCSupplier) { + final Supplier> orgToVDCSupplier) { return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, seconds, - new Supplier>() { - @Override - public Map get() { - Map returnVal = newLinkedHashMap(); - for (Entry orgr : orgToVDCSupplier.get().entrySet()) { - for (String vdc : orgr.getValue().getVDCs().keySet()) { - returnVal.put(vdc, orgr.getKey()); - } + new Supplier>() { + @Override + public Map get() { + Map returnVal = newLinkedHashMap(); + for (Entry orgr : orgToVDCSupplier.get().entrySet()) { + for (String vdc : orgr.getValue().getVDCs().keySet()) { + returnVal.put(vdc, orgr.getKey()); } - return returnVal; } - }); + return returnVal; + } + }); } @@ -180,15 +182,24 @@ public class CommonVCloudRestClientModule> provideOrgMapCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, - final OrgMapSupplier supplier) { + final OrgMapSupplier supplier) { return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, - seconds, new Supplier>() { - @Override - public Map get() { - return supplier.get(); - } + seconds, new Supplier>() { + @Override + public Map get() { + return supplier.get(); + } - }); + }); + } + + @Provides + @Singleton + @OrgList + URI provideOrgListURI(Supplier sessionSupplier) { + VCloudSession session = sessionSupplier.get(); + return URI.create(Iterables.getLast(session.getOrgs().values()).getHref().toASCIIString().replaceAll("org/.*", + "org")); } @Singleton @@ -198,7 +209,7 @@ public class CommonVCloudRestClientModule sessionSupplier, - Function, Iterable> organizationsForNames) { + Function, Iterable> organizationsForNames) { this.sessionSupplier = sessionSupplier; this.organizationsForNames = organizationsForNames; } @@ -211,13 +222,13 @@ public class CommonVCloudRestClientModule>> { + Supplier>> { protected final Supplier> orgSupplier; private final Function> allCatalogsInOrg; @Inject protected OrgCatalogSupplier(Supplier> orgSupplier, - Function> allCatalogsInOrg) { + Function> allCatalogsInOrg) { this.orgSupplier = orgSupplier; this.allCatalogsInOrg = allCatalogsInOrg; } @@ -225,16 +236,16 @@ public class CommonVCloudRestClientModule> get() { return transformValues( - transformValues(orgSupplier.get(), allCatalogsInOrg), - new Function, Map>() { + transformValues(orgSupplier.get(), allCatalogsInOrg), + new Function, Map>() { - @Override - public Map apply( - Iterable from) { - return uniqueIndex(from, name); - } + @Override + public Map apply( + Iterable from) { + return uniqueIndex(from, name); + } - }); + }); } } @@ -265,27 +276,27 @@ public class CommonVCloudRestClientModule> provideVDCtoORG(@Named(PROPERTY_SESSION_INTERVAL) long seconds, - final OrgNameToOrgSupplier supplier) { + final OrgNameToOrgSupplier supplier) { return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, - seconds, new Supplier>() { - @Override - public Map get() { - return supplier.get(); - } - }); + seconds, new Supplier>() { + @Override + public Map get() { + return supplier.get(); + } + }); } @Provides @Singleton protected Supplier> provideURIToVDC( - @Named(PROPERTY_SESSION_INTERVAL) long seconds, final URItoVDC supplier) { + @Named(PROPERTY_SESSION_INTERVAL) long seconds, final URItoVDC supplier) { return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier>( - authException, seconds, new Supplier>() { - @Override - public Map get() { - return supplier.get(); - } - }); + authException, seconds, new Supplier>() { + @Override + public Map get() { + return supplier.get(); + } + }); } @Singleton @@ -300,24 +311,24 @@ public class CommonVCloudRestClientModule get() { return uniqueIndex( - concat(transform( - orgVDCMap.get().values(), - new Function, Iterable>() { + concat(transform( + orgVDCMap.get().values(), + new Function, Iterable>() { - @Override - public Iterable apply( - Map from) { - return from.values(); - } + @Override + public Iterable apply( + Map from) { + return from.values(); + } - })), new Function() { + })), new Function() { - @Override - public URI apply(org.jclouds.vcloud.domain.VDC from) { - return from.getHref(); - } + @Override + public URI apply(org.jclouds.vcloud.domain.VDC from) { + return from.getHref(); + } - }); + }); } } @@ -346,8 +357,7 @@ public class CommonVCloudRestClientModule versions = versionService.getSupportedVersions().get(180, TimeUnit.SECONDS); checkState(versions.size() > 0, "No versions present"); checkState(versions.containsKey(version), "version " + version + " not present in: " + versions); @@ -381,7 +391,7 @@ public class CommonVCloudRestClientModule>> catalogs) { + Supplier>> catalogs) { return getLast(getLast(catalogs.get().values()).keySet()); } @@ -389,7 +399,7 @@ public class CommonVCloudRestClientModule successTester(Injector injector, - @Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) { + @Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) { return new RetryablePredicate(injector.getInstance(TaskSuccess.class), completed); } @Provides @Singleton protected Supplier>> provideOrgCatalogItemMapSupplierCache( - @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgCatalogSupplier supplier) { + @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgCatalogSupplier supplier) { return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier>>( - authException, seconds, - new Supplier>>() { - @Override - public Map> get() { - return supplier.get(); - } + authException, seconds, + new Supplier>>() { + @Override + public Map> get() { + return supplier.get(); + } - }); + }); } @Provides @Singleton protected Supplier>> provideOrgVDCSupplierCache( - @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { + @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier>>( - authException, seconds, - new Supplier>>() { - @Override - public Map> get() { - return supplier.get(); - } + authException, seconds, new Supplier>>() { + @Override + public Map> get() { + return supplier.get(); + } - }); + }); } @Singleton public static class OrgVDCSupplier implements - Supplier>> { + Supplier>> { protected final Supplier> orgSupplier; private final Function> allVDCsInOrg; @Inject protected OrgVDCSupplier(Supplier> orgSupplier, - Function> allVDCsInOrg) { + Function> allVDCsInOrg) { this.orgSupplier = orgSupplier; this.allVDCsInOrg = allVDCsInOrg; } @@ -480,29 +489,29 @@ public class CommonVCloudRestClientModule> get() { return transformValues( - transformValues(orgSupplier.get(), allVDCsInOrg), - new Function, Map>() { + transformValues(orgSupplier.get(), allVDCsInOrg), + new Function, Map>() { - @Override - public Map apply( - Iterable from) { - return uniqueIndex(from, name); - } + @Override + public Map apply( + Iterable from) { + return uniqueIndex(from, name); + } - }); + }); } } @Singleton public static class OrgCatalogItemSupplier implements - Supplier>>> { + Supplier>>> { protected final Supplier>> catalogSupplier; private final Function> allCatalogItemsInCatalog; @Inject protected OrgCatalogItemSupplier( - Supplier>> catalogSupplier, - Function> allCatalogItemsInCatalog) { + Supplier>> catalogSupplier, + Function> allCatalogItemsInCatalog) { this.catalogSupplier = catalogSupplier; this.allCatalogItemsInCatalog = allCatalogItemsInCatalog; } @@ -510,40 +519,39 @@ public class CommonVCloudRestClientModule>> get() { return transformValues( - catalogSupplier.get(), - new Function, Map>>() { + catalogSupplier.get(), + new Function, Map>>() { - @Override - public Map> apply( - Map from) { - return transformValues( - from, - new Function>() { + @Override + public Map> apply( + Map from) { + return transformValues( + from, + new Function>() { - @Override - public Map apply( - org.jclouds.vcloud.domain.Catalog from) { - return uniqueIndex(allCatalogItemsInCatalog.apply(from), name); - } - }); + @Override + public Map apply(org.jclouds.vcloud.domain.Catalog from) { + return uniqueIndex(allCatalogItemsInCatalog.apply(from), name); + } + }); - } - }); + } + }); } } @Provides @Singleton protected Supplier>>> provideOrgCatalogItemSupplierCache( - @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgCatalogItemSupplier supplier) { + @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgCatalogItemSupplier supplier) { return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier>>>( - authException, seconds, - new Supplier>>>() { - @Override - public Map>> get() { - return supplier.get(); - } - }); + authException, seconds, + new Supplier>>>() { + @Override + public Map>> get() { + return supplier.get(); + } + }); } @Provides diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/InstantiateVAppTemplateParams.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/InstantiateVAppTemplateParams.java new file mode 100644 index 0000000000..036d07d175 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/InstantiateVAppTemplateParams.java @@ -0,0 +1,99 @@ +/** + * + * 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.vcloud.domain; + +import java.util.Set; + +import org.jclouds.vcloud.domain.ovf.ResourceAllocation; +import org.jclouds.vcloud.domain.ovf.System; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; + +/** + * The InstantiateVAppTemplateParams element forms the body of an instantiateVappTemplate request. + */ +public class InstantiateVAppTemplateParams { + + protected final String info; + protected final System virtualSystem; + protected final Set resourceAllocations = Sets.newLinkedHashSet(); + + public InstantiateVAppTemplateParams(String info, System virtualSystem, Iterable resourceAllocations) { + this.info = info; + this.virtualSystem = virtualSystem; + Iterables.addAll(this.resourceAllocations, resourceAllocations); + } + + public String getInfo() { + return info; + } + + public System getSystem() { + return virtualSystem; + } + + public Set getResourceAllocations() { + return resourceAllocations; + } + + @Override + public String toString() { + return "[info=" + getInfo() + ", virtualSystem=" + getSystem() + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((info == null) ? 0 : info.hashCode()); + result = prime * result + ((resourceAllocations == null) ? 0 : resourceAllocations.hashCode()); + result = prime * result + ((virtualSystem == null) ? 0 : virtualSystem.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; + InstantiateVAppTemplateParams other = (InstantiateVAppTemplateParams) obj; + if (info == null) { + if (other.info != null) + return false; + } else if (!info.equals(other.info)) + return false; + if (resourceAllocations == null) { + if (other.resourceAllocations != null) + return false; + } else if (!resourceAllocations.equals(other.resourceAllocations)) + return false; + if (virtualSystem == null) { + if (other.virtualSystem != null) + return false; + } else if (!virtualSystem.equals(other.virtualSystem)) + return false; + return true; + } + +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/endpoints/OrgList.java b/vcloud/core/src/main/java/org/jclouds/vcloud/endpoints/OrgList.java new file mode 100644 index 0000000000..93a9bdc70c --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/endpoints/OrgList.java @@ -0,0 +1,40 @@ +/** + * + * 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.vcloud.endpoints; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +/** + * Related to a VCloud express Org List. + * + * @author Adrian Cole + * + */ +@Retention(value = RetentionPolicy.RUNTIME) +@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) +@Qualifier +public @interface OrgList { + +} \ No newline at end of file diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java index 7486aafd2b..2bfa10a84f 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java @@ -45,6 +45,7 @@ import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory.ContextSpec; +import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.rest.internal.RestAnnotationProcessor; @@ -67,6 +68,7 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; import org.jclouds.vcloud.xml.CatalogHandler; import org.jclouds.vcloud.xml.CatalogItemHandler; import org.jclouds.vcloud.xml.OrgHandler; +import org.jclouds.vcloud.xml.OrgListHandler; import org.jclouds.vcloud.xml.OrgNetworkHandler; import org.jclouds.vcloud.xml.TaskHandler; import org.jclouds.vcloud.xml.TasksListHandler; @@ -97,21 +99,21 @@ import domain.VCloudVersionsAsyncClient; public class VCloudAsyncClientTest extends RestClientTest { public void testInstantiateVAppTemplateInVDCURIOptions() throws SecurityException, NoSuchMethodException, - IOException { + IOException { Method method = VCloudAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", URI.class, URI.class, - String.class, InstantiateVAppTemplateOptions[].class); + String.class, InstantiateVAppTemplateOptions[].class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"), "my-vapp", - addNetworkConfig(new NetworkConfig("aloha", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), FenceMode.NAT_ROUTED))); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"), "my-vapp", + addNetworkConfig(new NetworkConfig("aloha", URI + .create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), FenceMode.NAT_ROUTED))); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/instantiateVAppTemplate HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/instantiateVAppTemplate HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n"); assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream( - "/instantiationparams-network.xml")), "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", - false); + "/instantiationparams-network.xml")), "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", + false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, VAppHandler.class); @@ -122,28 +124,28 @@ public class VCloudAsyncClientTest extends RestClientTest { @Test(expectedExceptions = IllegalArgumentException.class) public void testInstantiateVAppTemplateInOrgOptionsIllegalName() throws SecurityException, NoSuchMethodException, - IOException { + IOException { Method method = VCloudAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", URI.class, URI.class, - String.class, InstantiateVAppTemplateOptions[].class); - processor.createRequest(method, URI.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), "CentOS 01", processorCount(1).memory(512) - .disk(1024).addNetworkConfig( - new NetworkConfig(null, URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), - null))); + String.class, InstantiateVAppTemplateOptions[].class); + processor + .createRequest(method, URI.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), "CentOS 01", processorCount(1).memory( + 512).disk(1024).addNetworkConfig( + new NetworkConfig(null, URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), null))); } public void testCloneVAppInVDC() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("cloneVAppInVDC", URI.class, URI.class, String.class, - CloneVAppOptions[].class); + CloneVAppOptions[].class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/4181"), "my-vapp"); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/4181"), "my-vapp"); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream("/cloneVApp-default.xml")), - "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); + "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -154,17 +156,17 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCloneVAppInVDCOptions() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("cloneVAppInVDC", URI.class, URI.class, String.class, - CloneVAppOptions[].class); + CloneVAppOptions[].class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/201"), "new-linux-server", - new CloneVAppOptions().deploy().powerOn().withDescription("The description of the new vApp")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/201"), "new-linux-server", new CloneVAppOptions() + .deploy().powerOn().withDescription("The description of the new vApp")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream("/cloneVApp.xml")), - "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); + "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -173,10 +175,25 @@ public class VCloudAsyncClientTest extends RestClientTest { checkFilters(request); } + public void testlistOrgs() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("listOrgs"); + HttpRequest request = processor.createRequest(method); + + assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/org HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.orgList+xml\n"); + assertPayloadEquals(request, null, null, false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, OrgListHandler.class); + assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(request); + } + public void testOrg() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getOrg", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/org/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/org/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/org/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.org+xml\n"); @@ -207,7 +224,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCatalog() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getCatalog", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/catalog/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalog+xml\n"); @@ -238,7 +255,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testNetwork() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getNetwork", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/network/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/network/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/network/2 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.network+xml\n"); @@ -254,7 +271,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCatalogItemURI() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getCatalogItem", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalogItem+xml\n"); @@ -269,7 +286,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testFindCatalogItemInOrgCatalogNamed() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("findCatalogItemInOrgCatalogNamed", String.class, String.class, - String.class); + String.class); HttpRequest request = processor.createRequest(method, "org", "catalog", "item"); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1 HTTP/1.1"); @@ -285,7 +302,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testFindVAppTemplate() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("findVAppTemplateInOrgCatalogNamed", String.class, - String.class, String.class); + String.class, String.class); HttpRequest request = processor.createRequest(method, "org", "catalog", "template"); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2 HTTP/1.1"); @@ -302,7 +319,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testVAppTemplateURI() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVAppTemplate", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vAppTemplate+xml\n"); @@ -318,7 +335,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetOvfEnvelopeForVAppTemplate() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getOvfEnvelopeForVAppTemplate", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2/ovf HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: text/xml\n"); @@ -391,7 +408,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetVDC() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVDC", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vdc/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vdc+xml\n"); @@ -407,7 +424,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetTasksList() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getTasksList", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/tasksList/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.tasksList+xml\n"); @@ -438,12 +455,12 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testDeployVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("deployVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/deploy HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, "", - "application/vnd.vmware.vcloud.deployVAppParams+xml", false); + "application/vnd.vmware.vcloud.deployVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -455,12 +472,12 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testDeployAndPowerOnVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("deployAndPowerOnVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/deploy HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, "", - "application/vnd.vmware.vcloud.deployVAppParams+xml", false); + "application/vnd.vmware.vcloud.deployVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -472,7 +489,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetVApp() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVApp", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vApp/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n"); @@ -488,7 +505,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vm/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vm/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vm/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vm+xml\n"); @@ -504,10 +521,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testRebootVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("rebootVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reboot HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reboot HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); assertPayloadEquals(request, null, null, false); @@ -521,13 +538,13 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testUndeployVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("undeployVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, "", - "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); + "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -537,17 +554,17 @@ public class VCloudAsyncClientTest extends RestClientTest { } public void testUndeployAndSaveStateOfVAppOrVmSaveState() throws SecurityException, NoSuchMethodException, - IOException { + IOException { Method method = VCloudAsyncClient.class.getMethod("undeployAndSaveStateOfVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, - "", - "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); + "", + "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -559,7 +576,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testDeleteVApp() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("deleteVApp", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "DELETE https://vcenterprise.bluelock.com/api/v1.0/vApp/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); @@ -575,10 +592,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testPowerOnVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("powerOnVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOn HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOn HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -592,10 +609,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testPowerOffVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("powerOffVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOff HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOff HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -609,10 +626,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testResetVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("resetVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reset HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reset HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -626,10 +643,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testSuspendVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("suspendVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/suspend HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/suspend HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -643,10 +660,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testShutdownVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("shutdownVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/shutdown HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/shutdown HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); assertPayloadEquals(request, null, null, false); @@ -660,7 +677,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetTask() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getTask", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/task/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); @@ -676,7 +693,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCancelTask() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("cancelTask", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); assertRequestLineEquals(request, "POST https://vcenterprise.bluelock.com/api/v1.0/task/1/action/cancel HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); @@ -718,7 +735,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public static class VCloudRestClientModuleExtension extends VCloudRestClientModule { @Override protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService, - @Named(PROPERTY_API_VERSION) String version) { + @Named(PROPERTY_API_VERSION) String version) { return URI.create("https://vcenterprise.bluelock.com/api/v1.0/login"); } @@ -761,13 +778,13 @@ public class VCloudAsyncClientTest extends RestClientTest { @Override protected Supplier provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, - final VCloudLoginAsyncClient login) { + final VCloudLoginAsyncClient login) { return Suppliers. ofInstance(new VCloudSession() { @Override public Map getOrgs() { return ImmutableMap. of("org", new ReferenceTypeImpl("org", - VCloudMediaType.ORG_XML, URI.create("https://vcenterprise.bluelock.com/api/v1.0/org/1"))); + VCloudMediaType.ORG_XML, URI.create("https://vcenterprise.bluelock.com/api/v1.0/org/1"))); } @Override @@ -788,44 +805,19 @@ public class VCloudAsyncClientTest extends RestClientTest { } protected Supplier>> provideOrgVDCSupplierCache( - @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { + @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { - return Suppliers - .>> ofInstance(ImmutableMap - .> of( - "org", + return Suppliers.>> ofInstance(ImmutableMap + .> of("org", - ImmutableMap - . of( - "vdc", - new VDCImpl( - "vdc", - null, - URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), - null, - null, - "description", - null, - null, - null, - null, - null, - ImmutableMap - . of( - "vapp", - new ReferenceTypeImpl( - "vapp", - "application/vnd.vmware.vcloud.vApp+xml", - URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/188849-1")), - "network", - new ReferenceTypeImpl( - "network", - "application/vnd.vmware.vcloud.vAppTemplate+xml", - URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdcItem/2"))), - null, 0, 0, 0, false)))); + ImmutableMap. of("vdc", new VDCImpl("vdc", null, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), null, null, "description", null, + null, null, null, null, ImmutableMap. of("vapp", new ReferenceTypeImpl( + "vapp", "application/vnd.vmware.vcloud.vApp+xml", URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/188849-1")), "network", + new ReferenceTypeImpl("network", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdcItem/2"))), null, 0, 0, 0, + false)))); } @@ -839,18 +831,15 @@ public class VCloudAsyncClientTest extends RestClientTest { @Override public Map get() { return ImmutableMap. of("org", new OrgImpl("org", null, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/org/1"), "org", "description", ImmutableMap - . of("catalog", new ReferenceTypeImpl("catalog", - VCloudMediaType.CATALOG_XML, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"))), ImmutableMap - . of("vdc", new ReferenceTypeImpl("vdc", VCloudMediaType.VDC_XML, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"))), ImmutableMap - . of("network", new ReferenceTypeImpl("network", - VCloudMediaType.NETWORK_XML, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/network/1"))), - new ReferenceTypeImpl("tasksList", VCloudMediaType.TASKSLIST_XML, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")), ImmutableList - . of())); + .create("https://vcenterprise.bluelock.com/api/v1.0/org/1"), "org", "description", ImmutableMap + . of("catalog", new ReferenceTypeImpl("catalog", VCloudMediaType.CATALOG_XML, + URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"))), ImmutableMap + . of("vdc", new ReferenceTypeImpl("vdc", VCloudMediaType.VDC_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"))), ImmutableMap + . of("network", new ReferenceTypeImpl("network", VCloudMediaType.NETWORK_XML, + URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1"))), new ReferenceTypeImpl( + "tasksList", VCloudMediaType.TASKSLIST_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")), ImmutableList. of())); } } @@ -866,14 +855,13 @@ public class VCloudAsyncClientTest extends RestClientTest { return ImmutableMap.> of("org", ImmutableMap. of("catalog", new CatalogImpl("catalog", "type", - URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"), null, "description", - ImmutableMap. of("item", new ReferenceTypeImpl("item", + URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"), null, "description", ImmutableMap + . of("item", new ReferenceTypeImpl("item", "application/vnd.vmware.vcloud.catalogItem+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1")), - "template", new ReferenceTypeImpl("template", - "application/vnd.vmware.vcloud.vAppTemplate+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"))), - ImmutableList. of(), true))); + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1")), "template", + new ReferenceTypeImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"))), + ImmutableList. of(), true))); } } @@ -885,26 +873,14 @@ public class VCloudAsyncClientTest extends RestClientTest { @Override public Map>> get() { - return ImmutableMap - .>> of( - "org", - ImmutableMap - .> of( - "catalog", - ImmutableMap - . of( - "template", - new CatalogItemImpl( - "template", - URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"), - "description", - new ReferenceTypeImpl( - "template", - "application/vnd.vmware.vcloud.vAppTemplate+xml", - URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")), - ImmutableMap. of())))); + return ImmutableMap.>> of( + "org", ImmutableMap.> of( + "catalog", ImmutableMap. of("template", + new CatalogItemImpl("template", URI + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"), "description", + new ReferenceTypeImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml", + URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")), + ImmutableMap. of())))); } } diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java index 6a4e812fd0..d52a686d36 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java @@ -47,6 +47,17 @@ public class VCloudClientLiveTest extends CommonVCloudClientLiveTest Date: Fri, 27 Aug 2010 17:26:49 -0700 Subject: [PATCH 03/63] updated snapshot repository info --- .../src/main/resources/archetype-resources/pom.xml | 2 +- .../src/main/resources/archetype-resources/pom.xml | 2 +- boxdotnet/pom.xml | 2 +- chef/core/pom.xml | 2 +- chef/servlet/pom.xml | 2 +- demos/antjruby/build.xml | 2 +- ibmdev/pom.xml | 2 +- opscodeplatform/pom.xml | 2 +- thirdparty/pom.xml | 2 +- tools/antcontrib/samples/cargooverssh/build.xml | 2 +- tools/antcontrib/samples/compute/build.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml index 431a8b2600..74b8f2a1d7 100644 --- a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml +++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml @@ -54,7 +54,7 @@ jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots true diff --git a/archetypes/json-client-archetype/src/main/resources/archetype-resources/pom.xml b/archetypes/json-client-archetype/src/main/resources/archetype-resources/pom.xml index 987c38e444..2efa11e0a5 100644 --- a/archetypes/json-client-archetype/src/main/resources/archetype-resources/pom.xml +++ b/archetypes/json-client-archetype/src/main/resources/archetype-resources/pom.xml @@ -54,7 +54,7 @@ jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots true diff --git a/boxdotnet/pom.xml b/boxdotnet/pom.xml index f683bb14c7..fada127582 100644 --- a/boxdotnet/pom.xml +++ b/boxdotnet/pom.xml @@ -52,7 +52,7 @@ jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots true diff --git a/chef/core/pom.xml b/chef/core/pom.xml index e0bf76592f..0965011843 100644 --- a/chef/core/pom.xml +++ b/chef/core/pom.xml @@ -49,7 +49,7 @@ jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots true diff --git a/chef/servlet/pom.xml b/chef/servlet/pom.xml index 5d32cad055..13aa804c29 100644 --- a/chef/servlet/pom.xml +++ b/chef/servlet/pom.xml @@ -41,7 +41,7 @@ jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots true diff --git a/demos/antjruby/build.xml b/demos/antjruby/build.xml index ba54fc0a80..b76fe31e3c 100644 --- a/demos/antjruby/build.xml +++ b/demos/antjruby/build.xml @@ -31,7 +31,7 @@ classpathref="maven-ant-tasks.classpath" /> - + diff --git a/ibmdev/pom.xml b/ibmdev/pom.xml index c9a5e2295f..f838e698d2 100644 --- a/ibmdev/pom.xml +++ b/ibmdev/pom.xml @@ -51,7 +51,7 @@ jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots diff --git a/opscodeplatform/pom.xml b/opscodeplatform/pom.xml index 9d7ecbe6aa..e221246bc7 100644 --- a/opscodeplatform/pom.xml +++ b/opscodeplatform/pom.xml @@ -52,7 +52,7 @@ jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots true diff --git a/thirdparty/pom.xml b/thirdparty/pom.xml index d099a049d9..0042920680 100644 --- a/thirdparty/pom.xml +++ b/thirdparty/pom.xml @@ -43,7 +43,7 @@ jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com:8081/nexus/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots diff --git a/tools/antcontrib/samples/cargooverssh/build.xml b/tools/antcontrib/samples/cargooverssh/build.xml index 409ea99620..b473d6fa4c 100644 --- a/tools/antcontrib/samples/cargooverssh/build.xml +++ b/tools/antcontrib/samples/cargooverssh/build.xml @@ -56,7 +56,7 @@ - + diff --git a/tools/antcontrib/samples/compute/build.xml b/tools/antcontrib/samples/compute/build.xml index 043f0ad227..5c1744a44f 100644 --- a/tools/antcontrib/samples/compute/build.xml +++ b/tools/antcontrib/samples/compute/build.xml @@ -46,7 +46,7 @@ - + From ac02d5c5f0e21ca241112dddea2180be3ac6264b Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 10:45:06 -0700 Subject: [PATCH 04/63] fixed parent project refs --- chef/core/pom.xml | 2 +- chef/servlet/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/chef/core/pom.xml b/chef/core/pom.xml index 0965011843..0deea59757 100644 --- a/chef/core/pom.xml +++ b/chef/core/pom.xml @@ -25,7 +25,7 @@ org.jclouds jclouds-chef-project 1.0-SNAPSHOT - ../project/pom.xml + ../pom.xml org.jclouds jclouds-chef diff --git a/chef/servlet/pom.xml b/chef/servlet/pom.xml index 13aa804c29..886c50736d 100644 --- a/chef/servlet/pom.xml +++ b/chef/servlet/pom.xml @@ -26,7 +26,7 @@ org.jclouds jclouds-chef-project 1.0-SNAPSHOT - ../project/pom.xml + ../pom.xml org.jclouds jclouds-chef-servlet From 612b8939d3a52a345c2475314d6076db763d0857 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 10:46:53 -0700 Subject: [PATCH 05/63] Issue 191: added example to integrate chef with compute --- chef/compute/pom.xml | 150 +++++++++++++++++++++++++++++++++++++++++++ chef/pom.xml | 1 + 2 files changed, 151 insertions(+) create mode 100644 chef/compute/pom.xml diff --git a/chef/compute/pom.xml b/chef/compute/pom.xml new file mode 100644 index 0000000000..f347e3de5d --- /dev/null +++ b/chef/compute/pom.xml @@ -0,0 +1,150 @@ + + + + 4.0.0 + + org.jclouds + jclouds-chef-project + 1.0-SNAPSHOT + ../pom.xml + + org.jclouds + jclouds-chef-compute + jclouds chef compute integration + provisions nodes with jclouds and kick's off chef to configure and integrate + + + YOUR_PREFERRED_PROVIDER + + + YOUR_ACCOUNT + YOUR_CREDENTIAL + YOUR_USER + ${user.home}/.chef/${jclouds.chef.identity}.pem + YOUR_ORG + https://api.opscode.com/organizations/${jclouds.opscodeplatform.org} + + + + + + jclouds-googlecode-deploy + http://jclouds.googlecode.com/svn/repo + + + jclouds-rimu-snapshots-nexus + https://oss.sonatype.org/content/repositories/snapshots + + true + + + + + + + ${project.groupId} + jclouds-chef + ${project.version} + + + ${project.groupId} + jclouds-compute + ${project.version} + + + ${project.groupId} + jclouds-compute + ${project.version} + test-jar + test + + + ${project.groupId} + jclouds-allcompute + ${project.version} + test + true + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration + integration-test + + test + + + + none + + + **/*LiveTest.java + + + + jclouds.compute.provider + ${jclouds.compute.provider} + + + jclouds.compute.endpoint + ${jclouds.compute.endpoint} + + + jclouds.compute.identity + ${jclouds.compute.identity} + + + jclouds.compute.credential + ${jclouds.compute.credential} + + + jclouds.chef.identity + ${jclouds.chef.identity} + + + jclouds.chef.identity.pem + ${jclouds.chef.identity.pem} + + + jclouds.chef.endpoint + ${jclouds.chef.endpoint} + + + + + + + + + + + + diff --git a/chef/pom.xml b/chef/pom.xml index 9af1509dea..05b43def2d 100644 --- a/chef/pom.xml +++ b/chef/pom.xml @@ -34,5 +34,6 @@ core servlet + compute From f265c4f3d79bd40815b5f31fe5aaae2356318e29 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 11:23:28 -0700 Subject: [PATCH 06/63] more live tests for template builder --- .../compute/EC2TemplateBuilderLiveTest.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) 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 e76b32a9d3..b5bc116dc1 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 @@ -27,6 +27,7 @@ import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; +import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.reference.EC2Constants; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; @@ -55,8 +56,28 @@ public class EC2TemplateBuilderLiveTest { } @Test - public void testTemplateBuilderCanUseImageId() { - // TODO + public void testTemplateBuilderCanUseImageIdAndSizeId() { + ComputeServiceContext newContext = null; + try { + newContext = new ComputeServiceContextFactory().createContext("ec2", user, password, ImmutableSet + .of(new Log4JLoggingModule())); + + Template template = newContext.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5").sizeId(InstanceType.M2_2XLARGE).build(); + + System.out.println(template.getImage()); + assert (template.getImage().getProviderId().startsWith("ami-")) : template; + assertEquals(template.getImage().getOperatingSystem().getVersion(), "5.4"); + assertEquals(template.getImage().getOperatingSystem().is64Bit(), true); + assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); + assertEquals(template.getImage().getVersion(), "4.4.10"); + assertEquals(template.getLocation().getId(), "us-east-1"); + assertEquals(template.getSize().getCores(), 13.0d); // because it is m2 2xl + assertEquals(template.getSize().getId(), InstanceType.M2_2XLARGE); + + } finally { + if (newContext != null) + newContext.close(); + } } @Test From 815eeaba3f4b350cb59d9aa5d697a1dac123105d Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 11:53:32 -0700 Subject: [PATCH 07/63] fixed properties and jar location for ant sample --- tools/antcontrib/samples/compute/build.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/antcontrib/samples/compute/build.xml b/tools/antcontrib/samples/compute/build.xml index 043f0ad227..65708cc3f8 100644 --- a/tools/antcontrib/samples/compute/build.xml +++ b/tools/antcontrib/samples/compute/build.xml @@ -27,21 +27,21 @@ - + - + @@ -59,16 +59,16 @@ - + From 3f19db9cc50137b7bcb682d0256bbd7ba9c3ab44 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 11:58:59 -0700 Subject: [PATCH 08/63] updated ant sample to work with latest snapshot --- tools/antcontrib/samples/compute/build.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/antcontrib/samples/compute/build.xml b/tools/antcontrib/samples/compute/build.xml index 65708cc3f8..550526680c 100644 --- a/tools/antcontrib/samples/compute/build.xml +++ b/tools/antcontrib/samples/compute/build.xml @@ -31,7 +31,7 @@ @@ -46,7 +46,7 @@ - + From 8b05fd26e0c334820a49e55421f59a5ee37e161d Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 12:29:20 -0700 Subject: [PATCH 09/63] Issue 290: fixed extra output --- .../org/jclouds/vcloud/compute/functions/GetExtraFromVApp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVApp.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVApp.java index ec56cf9d06..324128d06f 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVApp.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVApp.java @@ -68,7 +68,7 @@ public class GetExtraFromVApp implements Function> { resourceType(ResourceType.DISK_DRIVE))) { if (disk instanceof VCloudHardDisk) { VCloudHardDisk vDisk = VCloudHardDisk.class.cast(disk); - extra.put(String.format("disk_drive/%s/kb", disk.getAddressOnParent()), vDisk.getCapacity() + ""); + extra.put(String.format("disk_drive/%s/mb", disk.getAddressOnParent()), vDisk.getCapacity() + ""); } else { extra.put(String.format("disk_drive/%s/kb", disk.getAddressOnParent()), disk.getVirtualQuantity() + ""); } From caf38ac87526d37286a36f5048c2fa0f8135b888 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 13:55:27 -0700 Subject: [PATCH 10/63] lowered the debug level --- .../org/jclouds/date/internal/SimpleDateFormatDateService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java b/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java index 2d4105f514..aba0e8533d 100755 --- a/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java +++ b/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java @@ -154,7 +154,7 @@ public class SimpleDateFormatDateService implements DateService { private String trimTZ(String toParse) { if (TZ_PATTERN.matcher(toParse).matches()) { - logger.warn("trimming tz from %s", toParse); + logger.trace("trimming tz from %s", toParse); toParse = toParse.substring(0, toParse.length() - 6) + 'Z'; } if (toParse.length() == 25 && SECOND_PATTERN.matcher(toParse).matches()) From d6075af116a1a2f32957728ce759c10179a2b163 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 14:22:35 -0700 Subject: [PATCH 11/63] fixed ant demos to new snapshot --- demos/antjruby/build.xml | 89 +++++-------------- .../build.properties.bluelock-vclouddirector | 5 ++ .../build.properties.bluelock-vcloudexpress | 5 ++ .../samples/cargooverssh/build.properties.ec2 | 8 +- .../cargooverssh/build.properties.eucalyptus | 7 ++ .../cargooverssh/build.properties.gogrid | 5 ++ .../build.properties.hostingdotcom | 5 -- .../cargooverssh/build.properties.ibmdev | 5 ++ .../build.properties.rackspacecloudservers | 8 +- .../cargooverssh/build.properties.rimuhosting | 8 +- .../cargooverssh/build.properties.trmk-ecloud | 8 +- .../build.properties.trmk-vcloudexpress | 8 +- .../cargooverssh/build.properties.vcloud | 8 +- .../antcontrib/samples/cargooverssh/build.xml | 38 ++++---- .../build.properties.bluelock-vclouddirector | 5 ++ .../build.properties.bluelock-vcloudexpress | 5 ++ .../samples/compute/build.properties.ec2 | 8 +- .../compute/build.properties.eucalyptus | 7 ++ .../samples/compute/build.properties.gogrid | 6 +- .../compute/build.properties.hostingdotcom | 5 -- .../samples/compute/build.properties.ibmdev | 5 ++ .../build.properties.rackspacecloudservers | 6 +- .../compute/build.properties.rimuhosting | 6 +- .../compute/build.properties.trmk-ecloud | 5 ++ .../build.properties.trmk-vcloudexpress | 5 ++ .../samples/compute/build.properties.vcloud | 6 +- tools/antcontrib/samples/compute/build.xml | 2 +- 27 files changed, 141 insertions(+), 137 deletions(-) create mode 100644 tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vclouddirector create mode 100644 tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vcloudexpress create mode 100644 tools/antcontrib/samples/cargooverssh/build.properties.eucalyptus create mode 100644 tools/antcontrib/samples/cargooverssh/build.properties.gogrid delete mode 100644 tools/antcontrib/samples/cargooverssh/build.properties.hostingdotcom create mode 100644 tools/antcontrib/samples/cargooverssh/build.properties.ibmdev create mode 100644 tools/antcontrib/samples/compute/build.properties.bluelock-vclouddirector create mode 100644 tools/antcontrib/samples/compute/build.properties.bluelock-vcloudexpress create mode 100644 tools/antcontrib/samples/compute/build.properties.eucalyptus delete mode 100644 tools/antcontrib/samples/compute/build.properties.hostingdotcom create mode 100644 tools/antcontrib/samples/compute/build.properties.ibmdev create mode 100644 tools/antcontrib/samples/compute/build.properties.trmk-ecloud create mode 100644 tools/antcontrib/samples/compute/build.properties.trmk-vcloudexpress diff --git a/demos/antjruby/build.xml b/demos/antjruby/build.xml index b76fe31e3c..fbf89a88a1 100644 --- a/demos/antjruby/build.xml +++ b/demos/antjruby/build.xml @@ -2,7 +2,7 @@ - + - + - + - - - - - - + + + @@ -63,91 +60,51 @@ /> - - - + - - - - diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vclouddirector b/tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vclouddirector new file mode 100644 index 0000000000..097c905ee2 --- /dev/null +++ b/tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vclouddirector @@ -0,0 +1,5 @@ +provider=bluelock-vcloudirector +driver=bluelock +identity=user@your_org +credential=password +tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vcloudexpress b/tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vcloudexpress new file mode 100644 index 0000000000..3103999af4 --- /dev/null +++ b/tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vcloudexpress @@ -0,0 +1,5 @@ +provider=bluelock-vcloudexpress +driver=bluelock +identity=user@youregistered.com +credential=password +tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.ec2 b/tools/antcontrib/samples/cargooverssh/build.properties.ec2 index 95f2aca5ab..80d6a63cba 100644 --- a/tools/antcontrib/samples/cargooverssh/build.properties.ec2 +++ b/tools/antcontrib/samples/cargooverssh/build.properties.ec2 @@ -1,5 +1,5 @@ -service=ec2 +provider=ec2 driver=aws -account=accesskeyid -key=secretaccesskey -nodetag=we_create_and_delete_based_on_key_and_security_group_name_not_instance_id +identity=accesscredentialid +credential=secretaccesscredential +tag=we_create_and_delete_based_on_credential_and_security_group_name_not_instance_id diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.eucalyptus b/tools/antcontrib/samples/cargooverssh/build.properties.eucalyptus new file mode 100644 index 0000000000..0d7950a850 --- /dev/null +++ b/tools/antcontrib/samples/cargooverssh/build.properties.eucalyptus @@ -0,0 +1,7 @@ +provider=eucalyptus +driver=aws +# note you need to change this to the correct endpoint +eucalyptus.endpoint=http://173.205.188.130:8773/services/Eucalyptus +identity=accesskey +credential=secret +tag=name_of_your_cluster_or_instance diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.gogrid b/tools/antcontrib/samples/cargooverssh/build.properties.gogrid new file mode 100644 index 0000000000..240ed0f4fc --- /dev/null +++ b/tools/antcontrib/samples/cargooverssh/build.properties.gogrid @@ -0,0 +1,5 @@ +provider=gogrid +driver=gogrid +identity=apikey +credential=secret +tag=name_of_your_server diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.hostingdotcom b/tools/antcontrib/samples/cargooverssh/build.properties.hostingdotcom deleted file mode 100644 index e8fdf11819..0000000000 --- a/tools/antcontrib/samples/cargooverssh/build.properties.hostingdotcom +++ /dev/null @@ -1,5 +0,0 @@ -service=hostingdotcom -driver=hostingdotcom -account=user@youregistered.com -key=password -nodetag=name_of_your_vapp diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.ibmdev b/tools/antcontrib/samples/cargooverssh/build.properties.ibmdev new file mode 100644 index 0000000000..8e3e7b5b9d --- /dev/null +++ b/tools/antcontrib/samples/cargooverssh/build.properties.ibmdev @@ -0,0 +1,5 @@ +provider=ibmdev +driver=ibmdev +identity=user@youregistered.com +credential=password +tag=name_of_your_server diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.rackspacecloudservers b/tools/antcontrib/samples/cargooverssh/build.properties.rackspacecloudservers index a352b2d540..37848da0b4 100644 --- a/tools/antcontrib/samples/cargooverssh/build.properties.rackspacecloudservers +++ b/tools/antcontrib/samples/cargooverssh/build.properties.rackspacecloudservers @@ -1,5 +1,5 @@ -service=cloudservers +provider=cloudservers driver=rackspace -account=user -key=your_key -nodetag=name_of_your_server +identity=user +credential=your_credential +tag=name_of_your_server diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.rimuhosting b/tools/antcontrib/samples/cargooverssh/build.properties.rimuhosting index e2f3baf214..c76f9e0322 100644 --- a/tools/antcontrib/samples/cargooverssh/build.properties.rimuhosting +++ b/tools/antcontrib/samples/cargooverssh/build.properties.rimuhosting @@ -1,5 +1,5 @@ -service=rimuhosting +provider=rimuhosting driver=rimuhosting -account=apikey -key=apikey -nodetag=name_of_your_server +identity=apicredential +credential=apicredential +tag=name_of_your_server diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.trmk-ecloud b/tools/antcontrib/samples/cargooverssh/build.properties.trmk-ecloud index fc6fc1c476..f122fa79c4 100644 --- a/tools/antcontrib/samples/cargooverssh/build.properties.trmk-ecloud +++ b/tools/antcontrib/samples/cargooverssh/build.properties.trmk-ecloud @@ -1,5 +1,5 @@ -service=trmk-ecloud +provider=trmk-ecloud driver=terremark -account=user@youregistered.com -key=password -nodetag=name_of_your_vapp +identity=user@youregistered.com +credential=password +tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.trmk-vcloudexpress b/tools/antcontrib/samples/cargooverssh/build.properties.trmk-vcloudexpress index 38f105801d..b3a67a75d1 100644 --- a/tools/antcontrib/samples/cargooverssh/build.properties.trmk-vcloudexpress +++ b/tools/antcontrib/samples/cargooverssh/build.properties.trmk-vcloudexpress @@ -1,5 +1,5 @@ -service=trmk-vcloudexpress +provider=trmk-vcloudexpress driver=terremark -account=user@youregistered.com -key=password -nodetag=name_of_your_vapp +identity=user@youregistered.com +credential=password +tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.vcloud b/tools/antcontrib/samples/cargooverssh/build.properties.vcloud index 521cb53687..9d99604052 100644 --- a/tools/antcontrib/samples/cargooverssh/build.properties.vcloud +++ b/tools/antcontrib/samples/cargooverssh/build.properties.vcloud @@ -1,7 +1,7 @@ -service=vcloud +provider=vcloud driver=vcloud # note you need to change this to the correct endpoint vcloud.endpoint=https://vcloud_host_you_want/api -account=user@youregistered.com -key=password -nodetag=name_of_your_vapp +identity=user@your_org +credential=password +tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/cargooverssh/build.xml b/tools/antcontrib/samples/cargooverssh/build.xml index b473d6fa4c..042c67636c 100644 --- a/tools/antcontrib/samples/cargooverssh/build.xml +++ b/tools/antcontrib/samples/cargooverssh/build.xml @@ -26,32 +26,30 @@ - + - - + @@ -60,8 +58,8 @@ - - + + @@ -73,21 +71,21 @@ - - - - + + + + - + - + - + - diff --git a/tools/antcontrib/samples/compute/build.properties.bluelock-vclouddirector b/tools/antcontrib/samples/compute/build.properties.bluelock-vclouddirector new file mode 100644 index 0000000000..097c905ee2 --- /dev/null +++ b/tools/antcontrib/samples/compute/build.properties.bluelock-vclouddirector @@ -0,0 +1,5 @@ +provider=bluelock-vcloudirector +driver=bluelock +identity=user@your_org +credential=password +tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/compute/build.properties.bluelock-vcloudexpress b/tools/antcontrib/samples/compute/build.properties.bluelock-vcloudexpress new file mode 100644 index 0000000000..3103999af4 --- /dev/null +++ b/tools/antcontrib/samples/compute/build.properties.bluelock-vcloudexpress @@ -0,0 +1,5 @@ +provider=bluelock-vcloudexpress +driver=bluelock +identity=user@youregistered.com +credential=password +tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/compute/build.properties.ec2 b/tools/antcontrib/samples/compute/build.properties.ec2 index a1302cad87..80d6a63cba 100644 --- a/tools/antcontrib/samples/compute/build.properties.ec2 +++ b/tools/antcontrib/samples/compute/build.properties.ec2 @@ -1,5 +1,5 @@ -service=ec2 +provider=ec2 driver=aws -account=accesskeyid -key=secretaccesskey -tag=we_create_and_delete_based_on_key_and_security_group_name_not_instance_id +identity=accesscredentialid +credential=secretaccesscredential +tag=we_create_and_delete_based_on_credential_and_security_group_name_not_instance_id diff --git a/tools/antcontrib/samples/compute/build.properties.eucalyptus b/tools/antcontrib/samples/compute/build.properties.eucalyptus new file mode 100644 index 0000000000..0d7950a850 --- /dev/null +++ b/tools/antcontrib/samples/compute/build.properties.eucalyptus @@ -0,0 +1,7 @@ +provider=eucalyptus +driver=aws +# note you need to change this to the correct endpoint +eucalyptus.endpoint=http://173.205.188.130:8773/services/Eucalyptus +identity=accesskey +credential=secret +tag=name_of_your_cluster_or_instance diff --git a/tools/antcontrib/samples/compute/build.properties.gogrid b/tools/antcontrib/samples/compute/build.properties.gogrid index 174dc7a006..240ed0f4fc 100644 --- a/tools/antcontrib/samples/compute/build.properties.gogrid +++ b/tools/antcontrib/samples/compute/build.properties.gogrid @@ -1,5 +1,5 @@ -service=gogrid +provider=gogrid driver=gogrid -account=apikey_not_your_email -key=shared_secret_not_your_password +identity=apikey +credential=secret tag=name_of_your_server diff --git a/tools/antcontrib/samples/compute/build.properties.hostingdotcom b/tools/antcontrib/samples/compute/build.properties.hostingdotcom deleted file mode 100644 index bab8387fbc..0000000000 --- a/tools/antcontrib/samples/compute/build.properties.hostingdotcom +++ /dev/null @@ -1,5 +0,0 @@ -service=hostingdotcom -driver=hostingdotcom -account=user@youregistered.com -key=password -tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/compute/build.properties.ibmdev b/tools/antcontrib/samples/compute/build.properties.ibmdev new file mode 100644 index 0000000000..8e3e7b5b9d --- /dev/null +++ b/tools/antcontrib/samples/compute/build.properties.ibmdev @@ -0,0 +1,5 @@ +provider=ibmdev +driver=ibmdev +identity=user@youregistered.com +credential=password +tag=name_of_your_server diff --git a/tools/antcontrib/samples/compute/build.properties.rackspacecloudservers b/tools/antcontrib/samples/compute/build.properties.rackspacecloudservers index 38eb771f4e..37848da0b4 100644 --- a/tools/antcontrib/samples/compute/build.properties.rackspacecloudservers +++ b/tools/antcontrib/samples/compute/build.properties.rackspacecloudservers @@ -1,5 +1,5 @@ -service=cloudservers +provider=cloudservers driver=rackspace -account=user -key=your_key +identity=user +credential=your_credential tag=name_of_your_server diff --git a/tools/antcontrib/samples/compute/build.properties.rimuhosting b/tools/antcontrib/samples/compute/build.properties.rimuhosting index aff127ad35..c76f9e0322 100644 --- a/tools/antcontrib/samples/compute/build.properties.rimuhosting +++ b/tools/antcontrib/samples/compute/build.properties.rimuhosting @@ -1,5 +1,5 @@ -service=rimuhosting +provider=rimuhosting driver=rimuhosting -account=apikey -key=apikey +identity=apicredential +credential=apicredential tag=name_of_your_server diff --git a/tools/antcontrib/samples/compute/build.properties.trmk-ecloud b/tools/antcontrib/samples/compute/build.properties.trmk-ecloud new file mode 100644 index 0000000000..f122fa79c4 --- /dev/null +++ b/tools/antcontrib/samples/compute/build.properties.trmk-ecloud @@ -0,0 +1,5 @@ +provider=trmk-ecloud +driver=terremark +identity=user@youregistered.com +credential=password +tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/compute/build.properties.trmk-vcloudexpress b/tools/antcontrib/samples/compute/build.properties.trmk-vcloudexpress new file mode 100644 index 0000000000..b3a67a75d1 --- /dev/null +++ b/tools/antcontrib/samples/compute/build.properties.trmk-vcloudexpress @@ -0,0 +1,5 @@ +provider=trmk-vcloudexpress +driver=terremark +identity=user@youregistered.com +credential=password +tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/compute/build.properties.vcloud b/tools/antcontrib/samples/compute/build.properties.vcloud index 576259d835..9d99604052 100644 --- a/tools/antcontrib/samples/compute/build.properties.vcloud +++ b/tools/antcontrib/samples/compute/build.properties.vcloud @@ -1,7 +1,7 @@ -service=vcloud +provider=vcloud driver=vcloud # note you need to change this to the correct endpoint vcloud.endpoint=https://vcloud_host_you_want/api -account=user@youregistered.com -key=password +identity=user@your_org +credential=password tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/compute/build.xml b/tools/antcontrib/samples/compute/build.xml index 550526680c..a188b60483 100644 --- a/tools/antcontrib/samples/compute/build.xml +++ b/tools/antcontrib/samples/compute/build.xml @@ -37,7 +37,7 @@ From eacb6906af9bef31716d1071b495d33be60c09b9 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 14:22:58 -0700 Subject: [PATCH 12/63] reverted thirdparty pom --- thirdparty/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/thirdparty/pom.xml b/thirdparty/pom.xml index 94e30ccc91..0fba2150e0 100644 --- a/thirdparty/pom.xml +++ b/thirdparty/pom.xml @@ -42,8 +42,8 @@ false - jclouds-snapshots - https://oss.sonatype.org/content/repositories/snapshots + jclouds-rimu-snapshots-nexus + http://jclouds.rimuhosting.com/maven2/snapshots From 9b44bf4495fa7ad622b91e16177a4a95ba41a15f Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 14:51:55 -0700 Subject: [PATCH 13/63] honed pom --- thirdparty/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/pom.xml b/thirdparty/pom.xml index 0fba2150e0..03912e4fcf 100644 --- a/thirdparty/pom.xml +++ b/thirdparty/pom.xml @@ -43,7 +43,7 @@ jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com/maven2/snapshots + http://jclouds.rimuhosting.com/nexus/content/repositories/snapshots From 6a4c93840d93376b494c2d0bf38aa72c38f58509 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 15:43:23 -0700 Subject: [PATCH 14/63] Issue 190: penciled in compute integration, tests first --- chef/compute/pom.xml | 25 ++- .../compute/ChefComputeServiceLiveTest.java | 96 ++++++++++ chef/compute/src/test/resources/log4j.xml | 175 ++++++++++++++++++ 3 files changed, 293 insertions(+), 3 deletions(-) create mode 100644 chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java create mode 100755 chef/compute/src/test/resources/log4j.xml diff --git a/chef/compute/pom.xml b/chef/compute/pom.xml index f347e3de5d..fdd2bead02 100644 --- a/chef/compute/pom.xml +++ b/chef/compute/pom.xml @@ -40,7 +40,7 @@ YOUR_ACCOUNT YOUR_CREDENTIAL YOUR_USER - ${user.home}/.chef/${jclouds.chef.identity}.pem + ${user.home}/.chef/${jclouds.chef.identity}.pem YOUR_ORG https://api.opscode.com/organizations/${jclouds.opscodeplatform.org} @@ -71,6 +71,25 @@ jclouds-compute ${project.version} + + ${project.groupId} + jclouds-log4j + ${project.version} + test + + + log4j + log4j + 1.2.14 + test + + + ${project.groupId} + jclouds-core + ${project.version} + test-jar + test + ${project.groupId} jclouds-compute @@ -130,8 +149,8 @@ ${jclouds.chef.identity} - jclouds.chef.identity.pem - ${jclouds.chef.identity.pem} + jclouds.chef.credential.pem + ${jclouds.chef.credential.pem} jclouds.chef.endpoint diff --git a/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java new file mode 100644 index 0000000000..995ea8c527 --- /dev/null +++ b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java @@ -0,0 +1,96 @@ +/** + * + * 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.chef.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.File; +import java.io.IOException; +import java.util.Properties; + +import org.jclouds.chef.ChefContext; +import org.jclouds.chef.ChefContextFactory; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableSet; +import com.google.common.io.Files; +import com.google.inject.Module; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", testName = "chef.ChefComputeServiceLiveTest") +public class ChefComputeServiceLiveTest { + + private ComputeServiceContext computeContext; + private ChefContext chefContext; + + @BeforeGroups(groups = { "live" }) + public void setupCompute() { + String computeProvider = checkNotNull(System.getProperty("jclouds.compute.provider"), "jclouds.compute.provider"); + String computeEndpoint = System.getProperty("jclouds.compute.endpoint"); + Properties props = new Properties(); + if (computeEndpoint != null && !computeEndpoint.trim().equals("")) + props.setProperty(computeProvider + ".endpoint", computeEndpoint); + String computeIdentity = checkNotNull(System.getProperty("jclouds.compute.identity"), "jclouds.compute.identity"); + String computeCredential = checkNotNull(System.getProperty("jclouds.compute.credential"), + "jclouds.compute.credential"); + computeContext = new ComputeServiceContextFactory().createContext(computeProvider, computeIdentity, + computeCredential, ImmutableSet.of(new Log4JLoggingModule()), props); + } + + @BeforeGroups(groups = { "live" }) + public void setupChef() throws IOException { + String chefEndpoint = checkNotNull(System.getProperty("jclouds.chef.endpoint"), "jclouds.chef.endpoint"); + String chefIdentity = checkNotNull(System.getProperty("jclouds.chef.identity"), "jclouds.chef.identity"); + String chefCredentialFile = System.getProperty("jclouds.chef.credential.pem"); + if (chefCredentialFile == null || chefCredentialFile.equals("")) + chefCredentialFile = System.getProperty("user.home") + "/.chef/" + chefIdentity + ".pem"; + Properties props = new Properties(); + props.setProperty("chef.endpoint", chefEndpoint); + chefContext = new ChefContextFactory().createContext(chefIdentity, Files.toString(new File(chefCredentialFile), + Charsets.UTF_8), ImmutableSet. of(new Log4JLoggingModule()), props); + } + + @Test + public void test() { + computeContext.getComputeService().listNodes(); + chefContext.getChefService().listNodesDetails(); + } + + @AfterGroups(groups = { "live" }) + public void teardownCompute() { + if (computeContext != null) + computeContext.close(); + } + + @AfterGroups(groups = { "live" }) + public void teardownChef() { + if (chefContext != null) + chefContext.close(); + } +} diff --git a/chef/compute/src/test/resources/log4j.xml b/chef/compute/src/test/resources/log4j.xml new file mode 100755 index 0000000000..535054a74e --- /dev/null +++ b/chef/compute/src/test/resources/log4j.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From be23e7320728a5a4902dfbb17975b4b14b2c8bcb Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Aug 2010 17:03:51 -0700 Subject: [PATCH 15/63] Issue 191: more progress on compute integration --- chef/compute/pom.xml | 332 +++++++++--------- .../src/main/resources/bootstrap-chef.sh | 14 + chef/compute/src/main/resources/herefile.sh | 5 + .../compute/ChefComputeServiceLiveTest.java | 45 ++- 4 files changed, 233 insertions(+), 163 deletions(-) create mode 100755 chef/compute/src/main/resources/bootstrap-chef.sh create mode 100755 chef/compute/src/main/resources/herefile.sh diff --git a/chef/compute/pom.xml b/chef/compute/pom.xml index fdd2bead02..aa3f9a52c1 100644 --- a/chef/compute/pom.xml +++ b/chef/compute/pom.xml @@ -1,169 +1,179 @@ - + http://www.apache.org/licenses/LICENSE-2.0.html 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. + ==================================================================== + --> - 4.0.0 - - org.jclouds - jclouds-chef-project - 1.0-SNAPSHOT - ../pom.xml - - org.jclouds - jclouds-chef-compute - jclouds chef compute integration - provisions nodes with jclouds and kick's off chef to configure and integrate - - - YOUR_PREFERRED_PROVIDER - - - YOUR_ACCOUNT - YOUR_CREDENTIAL - YOUR_USER - ${user.home}/.chef/${jclouds.chef.identity}.pem - YOUR_ORG - https://api.opscode.com/organizations/${jclouds.opscodeplatform.org} - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 + + org.jclouds + jclouds-chef-project + 1.0-SNAPSHOT + ../pom.xml + + org.jclouds + jclouds-chef-compute + jclouds chef compute integration + provisions nodes with jclouds and kick's off chef to configure and integrate + + + YOUR_PREFERRED_PROVIDER + + + YOUR_ACCOUNT + YOUR_CREDENTIAL + + jcloudschef + YOUR_USER + ${user.home}/.chef/${jclouds.chef.identity}.pem + YOUR_ORG + https://api.opscode.com/organizations/${jclouds.opscodeplatform.org} + - - - - jclouds-googlecode-deploy - http://jclouds.googlecode.com/svn/repo - - - jclouds-rimu-snapshots-nexus - https://oss.sonatype.org/content/repositories/snapshots - - true - - - + + + + jclouds-googlecode-deploy + http://jclouds.googlecode.com/svn/repo + + + jclouds-rimu-snapshots-nexus + https://oss.sonatype.org/content/repositories/snapshots + + true + + + - - - ${project.groupId} - jclouds-chef - ${project.version} - - - ${project.groupId} - jclouds-compute - ${project.version} - - - ${project.groupId} - jclouds-log4j - ${project.version} - test - - - log4j - log4j - 1.2.14 - test - - - ${project.groupId} - jclouds-core - ${project.version} - test-jar - test - - - ${project.groupId} - jclouds-compute - ${project.version} - test-jar - test - - - ${project.groupId} - jclouds-allcompute - ${project.version} - test - true - - - - - live - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration - integration-test - - test - - - - none - - - **/*LiveTest.java - - - - jclouds.compute.provider - ${jclouds.compute.provider} - - - jclouds.compute.endpoint - ${jclouds.compute.endpoint} - - - jclouds.compute.identity - ${jclouds.compute.identity} - - - jclouds.compute.credential - ${jclouds.compute.credential} - - - jclouds.chef.identity - ${jclouds.chef.identity} - - - jclouds.chef.credential.pem - ${jclouds.chef.credential.pem} - - - jclouds.chef.endpoint - ${jclouds.chef.endpoint} - - - - - - - - - - + + + ${project.groupId} + jclouds-chef + ${project.version} + + + ${project.groupId} + jclouds-compute + ${project.version} + + + ${project.groupId} + jclouds-log4j + ${project.version} + test + + + log4j + log4j + 1.2.14 + test + + + ${project.groupId} + jclouds-core + ${project.version} + test-jar + test + + + ${project.groupId} + jclouds-compute + ${project.version} + test-jar + test + + + ${project.groupId} + jclouds-allcompute + ${project.version} + test + true + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration + integration-test + + test + + + + none + + + **/*LiveTest.java + + + + jclouds.compute.provider + ${jclouds.compute.provider} + + + jclouds.compute.endpoint + ${jclouds.compute.endpoint} + + + jclouds.compute.identity + ${jclouds.compute.identity} + + + jclouds.compute.credential + ${jclouds.compute.credential} + + + jclouds.compute.tag + ${jclouds.compute.tag} + + + jclouds.compute.credential + ${jclouds.compute.credential} + + + jclouds.chef.credential.pem + ${jclouds.chef.credential.pem} + + + jclouds.chef.endpoint + ${jclouds.chef.endpoint} + + + + + + + + + + diff --git a/chef/compute/src/main/resources/bootstrap-chef.sh b/chef/compute/src/main/resources/bootstrap-chef.sh new file mode 100755 index 0000000000..8b11e7b552 --- /dev/null +++ b/chef/compute/src/main/resources/bootstrap-chef.sh @@ -0,0 +1,14 @@ +if [ ! -f /usr/bin/chef-client ]; then + apt-get update + apt-get install -y ruby ruby1.8-dev build-essential wget libruby-extras libruby1.8-extras + mkdir -p /tmp/bootchef + ( + cd /tmp/bootchef + curl http://rubyforge.org/frs/download.php/69365/rubygems-1.3.6.tgz| tar -xzf - + cd rubygems-1.3.6 + ruby setup.rb + cp /usr/bin/gem1.8 /usr/bin/gem + ) + rm -rf /tmp/bootchef + gem install chef ohai --no-rdoc --no-ri --verbose +fi \ No newline at end of file diff --git a/chef/compute/src/main/resources/herefile.sh b/chef/compute/src/main/resources/herefile.sh new file mode 100755 index 0000000000..7907fbccea --- /dev/null +++ b/chef/compute/src/main/resources/herefile.sh @@ -0,0 +1,5 @@ +( +cat <<'EOP' +@herefile@ +EOP +) > @destination@ \ No newline at end of file diff --git a/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java index 995ea8c527..d09506237b 100644 --- a/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java +++ b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java @@ -20,15 +20,19 @@ package org.jclouds.chef.compute; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Sets.newHashSet; import java.io.File; import java.io.IOException; import java.util.Properties; +import java.util.Set; import org.jclouds.chef.ChefContext; import org.jclouds.chef.ChefContextFactory; +import org.jclouds.chef.ChefService; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.crypto.Pems; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.testng.annotations.AfterGroups; import org.testng.annotations.BeforeGroups; @@ -48,9 +52,13 @@ public class ChefComputeServiceLiveTest { private ComputeServiceContext computeContext; private ChefContext chefContext; + private String tag; + private String clientName; @BeforeGroups(groups = { "live" }) public void setupCompute() { + tag = System.getProperty("jclouds.compute.tag") != null ? System.getProperty("jclouds.compute.tag") + : "jcloudschef"; String computeProvider = checkNotNull(System.getProperty("jclouds.compute.provider"), "jclouds.compute.provider"); String computeEndpoint = System.getProperty("jclouds.compute.endpoint"); Properties props = new Properties(); @@ -77,11 +85,41 @@ public class ChefComputeServiceLiveTest { } @Test - public void test() { + public void test() throws IOException { + clientName = findNextClientName(chefContext, tag + "-%d"); + String clientKey = Pems.pem(chefContext.getApi().createClient(clientName).getPrivateKey()); + + // herefile /etc/chef/client.rb + // log_level :info + // log_location STDOUT + // chef_server_url "@chef_server_url@" + + // herefile /etc/chef/client.pem + // clientKey + // herefile /etc/chef/first-boot.json + // { "run_list": [ "recipe[apache]" ] } + + // then run /usr/bin/chef-client -j /etc/chef/first-boot.json + + System.out.println("created new client: " + clientName); + computeContext.getComputeService().listNodes(); chefContext.getChefService().listNodesDetails(); } + private String findNextClientName(ChefContext context, String pattern) { + Set nodes = context.getApi().listClients(); + String nodeName; + Set names = newHashSet(nodes); + int index = 0; + while (true) { + nodeName = String.format(pattern, index++); + if (!names.contains(nodeName)) + break; + } + return nodeName; + } + @AfterGroups(groups = { "live" }) public void teardownCompute() { if (computeContext != null) @@ -90,7 +128,10 @@ public class ChefComputeServiceLiveTest { @AfterGroups(groups = { "live" }) public void teardownChef() { - if (chefContext != null) + if (chefContext != null) { + if (clientName != null && chefContext.getApi().clientExists(clientName)) + chefContext.getApi().deleteClient(clientName); chefContext.close(); + } } } From fa8386b3577bdfea0b94d85d54c6e2d857d7a6fa Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Thu, 2 Sep 2010 01:32:16 -0700 Subject: [PATCH 16/63] fixed rsa private key -> pem issue --- core/pom.xml | 8 +- .../main/java/org/jclouds/crypto/Pems.java | 136 +++++++++++------- .../java/org/jclouds/crypto/PemsTest.java | 22 ++- 3 files changed, 98 insertions(+), 68 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 8ba81da45e..d91bcb3547 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -58,7 +58,13 @@ oauth 20100527 - + + + org.bouncycastle + bcprov-jdk15 + 1.44 + true + aopalliance aopalliance diff --git a/core/src/main/java/org/jclouds/crypto/Pems.java b/core/src/main/java/org/jclouds/crypto/Pems.java index 2623f9706f..94cb3b9c83 100644 --- a/core/src/main/java/org/jclouds/crypto/Pems.java +++ b/core/src/main/java/org/jclouds/crypto/Pems.java @@ -31,6 +31,8 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPublicKey; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateKeySpec; @@ -43,12 +45,16 @@ import net.oauth.signature.pem.PEMReader; import net.oauth.signature.pem.PKCS1EncodedKeySpec; import net.oauth.signature.pem.PKCS1EncodedPublicKeySpec; +import org.bouncycastle.asn1.ASN1OutputStream; +import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure; import org.jclouds.crypto.Pems.PemProcessor.ResultParser; import org.jclouds.io.InputSuppliers; import com.google.common.annotations.Beta; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; -import com.google.common.io.ByteStreams; import com.google.common.io.InputSupplier; /** @@ -89,7 +95,7 @@ public class Pems { return parsers.get(reader.getBeginMarker()).parseResult(bytes); } else { throw new IOException(String.format("Invalid PEM file: no parsers for marker %s in %s", reader - .getBeginMarker(), parsers.keySet())); + .getBeginMarker(), parsers.keySet())); } } catch (IOException e) { throw new RuntimeException(e); @@ -98,8 +104,7 @@ public class Pems { } /** - * Returns the object of generic type {@code T} that is pem encoded in the - * supplier. + * Returns the object of generic type {@code T} that is pem encoded in the supplier. * * @param supplier * the input stream factory @@ -107,13 +112,12 @@ public class Pems { * header that begins the PEM block * @param processor * how to parser the object from a byte array - * @return the object of generic type {@code T} which was PEM encoded in the - * stream + * @return the object of generic type {@code T} which was PEM encoded in the stream * @throws IOException * if an I/O error occurs */ public static T fromPem(InputSupplier supplier, PemProcessor processor) - throws IOException { + throws IOException { try { return com.google.common.io.ByteStreams.readBytes(supplier, processor); } catch (RuntimeException e) { @@ -136,24 +140,24 @@ public class Pems { */ public static KeySpec privateKeySpec(InputSupplier supplier) throws IOException { return fromPem(supplier, new PemProcessor(ImmutableMap.> of( - PRIVATE_PKCS1_MARKER, new ResultParser() { + PRIVATE_PKCS1_MARKER, new ResultParser() { - public KeySpec parseResult(byte[] bytes) throws IOException { - return (new PKCS1EncodedKeySpec(bytes)).getKeySpec(); - } + public KeySpec parseResult(byte[] bytes) throws IOException { + return (new PKCS1EncodedKeySpec(bytes)).getKeySpec(); + } - }, PRIVATE_PKCS8_MARKER, new ResultParser() { + }, PRIVATE_PKCS8_MARKER, new ResultParser() { - public KeySpec parseResult(byte[] bytes) throws IOException { - return new PKCS8EncodedKeySpec(bytes); - } + public KeySpec parseResult(byte[] bytes) throws IOException { + return new PKCS8EncodedKeySpec(bytes); + } - }))); + }))); } /** - * Executes {@link Pems#privateKeySpec(InputSupplier)} on the string which - * contains an encoded private key in PEM format. + * Executes {@link Pems#privateKeySpec(InputSupplier)} on the string which contains an encoded + * private key in PEM format. * * @param pem * private key in pem encoded format. @@ -175,24 +179,24 @@ public class Pems { */ public static KeySpec publicKeySpec(InputSupplier supplier) throws IOException { return fromPem(supplier, new PemProcessor(ImmutableMap.> of( - PUBLIC_PKCS1_MARKER, new ResultParser() { + PUBLIC_PKCS1_MARKER, new ResultParser() { - public KeySpec parseResult(byte[] bytes) throws IOException { - return (new PKCS1EncodedPublicKeySpec(bytes)).getKeySpec(); - } + public KeySpec parseResult(byte[] bytes) throws IOException { + return (new PKCS1EncodedPublicKeySpec(bytes)).getKeySpec(); + } - }, PUBLIC_X509_MARKER, new ResultParser() { + }, PUBLIC_X509_MARKER, new ResultParser() { - public X509EncodedKeySpec parseResult(byte[] bytes) throws IOException { - return new X509EncodedKeySpec(bytes); - } + public X509EncodedKeySpec parseResult(byte[] bytes) throws IOException { + return new X509EncodedKeySpec(bytes); + } - }))); + }))); } /** - * Executes {@link Pems#publicKeySpec(InputSupplier)} on the string which - * contains an encoded public key in PEM format. + * Executes {@link Pems#publicKeySpec(InputSupplier)} on the string which contains an encoded + * public key in PEM format. * * @param pem * public key in pem encoded format. @@ -203,8 +207,7 @@ public class Pems { } /** - * Returns the {@link X509EncodedKeySpec} that is pem encoded in the - * supplier. + * Returns the {@link X509EncodedKeySpec} that is pem encoded in the supplier. * * @param supplier * the input stream factory @@ -217,24 +220,24 @@ public class Pems { * @throws CertificateException */ public static X509Certificate x509Certificate(InputSupplier supplier, - @Nullable CertificateFactory certFactory) throws IOException, CertificateException { + @Nullable CertificateFactory certFactory) throws IOException, CertificateException { final CertificateFactory finalCertFactory = certFactory != null ? certFactory : CertificateFactory - .getInstance("X.509"); + .getInstance("X.509"); try { return fromPem(supplier, new PemProcessor(ImmutableMap - .> of(CERTIFICATE_X509_MARKER, - new ResultParser() { + .> of(CERTIFICATE_X509_MARKER, + new ResultParser() { - public X509Certificate parseResult(byte[] bytes) throws IOException { - try { - return (X509Certificate) finalCertFactory.generateCertificate(new ByteArrayInputStream( - bytes)); - } catch (CertificateException e) { - throw new RuntimeException(e); - } - } + public X509Certificate parseResult(byte[] bytes) throws IOException { + try { + return (X509Certificate) finalCertFactory + .generateCertificate(new ByteArrayInputStream(bytes)); + } catch (CertificateException e) { + throw new RuntimeException(e); + } + } - }))); + }))); } catch (RuntimeException e) { if (e.getCause() != null && e.getCause() instanceof CertificateException) { throw (CertificateException) e.getCause(); @@ -244,8 +247,8 @@ public class Pems { } /** - * Executes {@link Pems#x509Certificate(InputSupplier, CertificateFactory)} - * on the string which contains an X.509 certificate in PEM format. + * Executes {@link Pems#x509Certificate(InputSupplier, CertificateFactory)} on the string which + * contains an X.509 certificate in PEM format. * * @param pem * certificate in pem encoded format. @@ -265,9 +268,8 @@ public class Pems { * @throws CertificateEncodingException */ public static String pem(X509Certificate cert) throws IOException, CertificateEncodingException { - return new StringBuilder("-----BEGIN CERTIFICATE-----\n").append( - CryptoStreams.base64Encode(ByteStreams.newInputStreamSupplier(cert.getEncoded()))).append( - "\n-----END CERTIFICATE-----\n").toString(); + String marker = CERTIFICATE_X509_MARKER; + return pem(cert.getEncoded(), marker); } /** @@ -280,9 +282,8 @@ public class Pems { * @throws CertificateEncodingException */ public static String pem(PublicKey key) throws IOException { - return new StringBuilder("-----BEGIN PUBLIC KEY-----\n").append( - CryptoStreams.base64Encode(ByteStreams.newInputStreamSupplier(key.getEncoded()))).append( - "\n-----END PUBLIC KEY-----\n").toString(); + String marker = key instanceof RSAPublicKey ? PUBLIC_PKCS1_MARKER : PUBLIC_X509_MARKER; + return pem(key.getEncoded(), marker); } /** @@ -295,9 +296,34 @@ public class Pems { * @throws CertificateEncodingException */ public static String pem(PrivateKey key) throws IOException { - return new StringBuilder("-----BEGIN PRIVATE KEY-----\n").append( - CryptoStreams.base64Encode(ByteStreams.newInputStreamSupplier(key.getEncoded()))).append( - "\n-----END PRIVATE KEY-----\n").toString(); + String marker = key instanceof RSAPrivateCrtKey ? PRIVATE_PKCS1_MARKER : PRIVATE_PKCS8_MARKER; + return pem(key instanceof RSAPrivateCrtKey ? getEncoded(RSAPrivateCrtKey.class.cast(key)) : key.getEncoded(), + marker); + } + + // TODO find a way to do this without using bouncycastle + static byte[] getEncoded(RSAPrivateCrtKey key) { + RSAPrivateKeyStructure keyStruct = new RSAPrivateKeyStructure(key.getModulus(), key.getPublicExponent(), key + .getPrivateExponent(), key.getPrimeP(), key.getPrimeQ(), key.getPrimeExponentP(), key + .getPrimeExponentQ(), key.getCrtCoefficient()); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ASN1OutputStream aOut = new ASN1OutputStream(bOut); + + try { + aOut.writeObject(keyStruct); + aOut.close(); + } catch (IOException e) { + Throwables.propagate(e); + } + + return bOut.toByteArray(); + } + + private static String pem(byte[] key, String marker) throws IOException { + return new StringBuilder(marker + "\n").append( + Joiner.on('\n').join(Splitter.fixedLength(64).split(CryptoStreams.base64(key)))).append( + "\n" + marker.replace("BEGIN", "END") + "\n").toString().trim(); } } diff --git a/core/src/test/java/org/jclouds/crypto/PemsTest.java b/core/src/test/java/org/jclouds/crypto/PemsTest.java index 3e0934e48b..0edc803b6d 100644 --- a/core/src/test/java/org/jclouds/crypto/PemsTest.java +++ b/core/src/test/java/org/jclouds/crypto/PemsTest.java @@ -26,6 +26,7 @@ import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; +import java.security.interfaces.RSAPrivateCrtKey; import java.security.spec.InvalidKeySpecException; import org.jclouds.io.Payloads; @@ -40,7 +41,7 @@ public class PemsTest { public static final String PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vEuYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n"; - public static final String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiVR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0OZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVzzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQAB\n-----END PUBLIC KEY-----\n"; + public static final String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyb2ZJJqGm0KKR+8nfQJN\nsSd+F9tXNMV7CfOcW6jsqs8EZgiVR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTP\nj1lJpVAida9sXy2+kzyagZA1Am0OZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhv\nHLBz+zM+3QqPRkPV8nYTbfs+HjVzzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvn\nRVQ0P482YwN9VgceOZtpPz0DCKEJ5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuO\nZptN//uAsTmxireqd37z+8ZTdBbJ8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2\nUQIDAQAB\n-----END PUBLIC KEY-----\n"; private static final String CERTIFICATE = "-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n"; @@ -64,29 +65,26 @@ public class PemsTest { Pems.x509Certificate(Payloads.newStringPayload(CERTIFICATE), CertificateFactory.getInstance("X.509")); } - @Test(enabled = false) - // TODO figure out how to write back in the same format + @Test public void testPrivateKeySpecPem() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException { - String encoded = Pems.pem(KeyFactory.getInstance("RSA").generatePrivate( - Pems.privateKeySpec(Payloads.newStringPayload(PRIVATE_KEY)))); - assertEquals(encoded, PRIVATE_KEY.replaceAll("\n", "").replaceAll("Y-----", "Y-----\n").replaceAll("-----E", - "\n-----E")); + RSAPrivateCrtKey key = (RSAPrivateCrtKey) KeyFactory.getInstance("RSA").generatePrivate( + Pems.privateKeySpec(Payloads.newStringPayload(PRIVATE_KEY))); + String encoded = Pems.pem(key); + assertEquals(encoded, PRIVATE_KEY.replaceAll("\n", "\n").trim()); } @Test - public void testPublicKeySpecPem() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException { + public void testRSAPublicKeySpecPem() throws IOException, InvalidKeySpecException, NoSuchAlgorithmException { String encoded = Pems.pem(KeyFactory.getInstance("RSA").generatePublic( Pems.publicKeySpec(Payloads.newStringPayload(PUBLIC_KEY)))); - assertEquals(encoded, PUBLIC_KEY.replaceAll("\n", "").replaceAll("Y-----", "Y-----\n").replaceAll("-----E", - "\n-----E")); + assertEquals(encoded, PUBLIC_KEY.replaceAll("PUBLIC", "RSA PUBLIC").replaceAll("\n", "\n").trim()); } @Test public void testX509CertificatePem() throws IOException, CertificateException { String encoded = Pems.pem(Pems.x509Certificate(Payloads.newStringPayload(CERTIFICATE), CertificateFactory .getInstance("X.509"))); - assertEquals(encoded, CERTIFICATE.replaceAll("\n", "").replaceAll("E-----", "E-----\n").replaceAll("-----E", - "\n-----E")); + assertEquals(encoded, CERTIFICATE.replaceAll("\n", "\n").trim()); } } From a96471c9a8524f3ef23d8b9783cd7a486a73d05a Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Thu, 2 Sep 2010 01:34:40 -0700 Subject: [PATCH 17/63] added create file support to scriptbuilder --- .../aws/ec2/EBSBootEC2ClientLiveTest.java | 41 ++++--- .../compute/callables/RunScriptOnNode.java | 23 ++-- .../StubComputeServiceIntegrationTest.java | 7 +- .../jclouds/scriptbuilder/InitBuilder.java | 37 +++--- .../scriptbuilder/domain/CreateFile.java | 113 ++++++++++++++++++ .../scriptbuilder/domain/CreateRunScript.java | 82 +++++-------- .../domain/InterpretableStatement.java | 19 +-- .../scriptbuilder/domain/Statements.java | 20 ++-- .../scriptbuilder/domain/SwitchArg.java | 40 ++++--- .../scriptbuilder/InitBuilderTest.java | 48 ++++---- .../scriptbuilder/ScriptBuilderTest.java | 52 ++++---- .../scriptbuilder/domain/CreateFileTest.java | 59 +++++++++ .../domain/CreateRunScriptTest.java | 34 +++--- .../scriptbuilder/domain/SwitchArgTest.java | 14 ++- .../src/test/resources/client_rb.cmd | Bin 0 -> 196 bytes scriptbuilder/src/test/resources/client_rb.sh | 5 + .../src/test/resources/test_init.cmd | Bin 3771 -> 4407 bytes scriptbuilder/src/test/resources/test_init.sh | 7 +- .../src/test/resources/test_runrun.cmd | Bin 815 -> 1197 bytes .../src/test/resources/test_runrun.sh | 10 +- .../src/test/resources/test_script.cmd | Bin 744 -> 856 bytes .../src/test/resources/test_script.sh | 3 + .../tools/ant/taskdefs/sshjava/SSHJava.java | 43 +++---- 23 files changed, 421 insertions(+), 236 deletions(-) create mode 100644 scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateFile.java create mode 100644 scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateFileTest.java create mode 100644 scriptbuilder/src/test/resources/client_rb.cmd create mode 100755 scriptbuilder/src/test/resources/client_rb.sh 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 0ace659272..0b11b1b421 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 @@ -66,6 +66,8 @@ import org.jclouds.predicates.SocketOpen; import org.jclouds.rest.RestContextFactory; 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.ssh.SshException; @@ -75,6 +77,7 @@ import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; @@ -250,25 +253,25 @@ public class EBSBootEC2ClientLiveTest { "mkebsboot",// name of the script "/tmp",// working directory "/tmp/logs",// location of stdout.log and stderr.log - ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"),// variables - // used - // inside - // of - // the - // script - "echo creating a filesystem and mounting the ebs volume",// what to - // execute - "{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}", - "rm -rf {varl}IMAGE_DIR{varr}/*", - "yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-", - "mount {varl}EBS_DEVICE{varr} {varl}EBS_MOUNT_POINT{varr}", - "echo making a local working copy of the boot disk", - "rsync -ax --exclude /ubuntu/.bash_history --exclude /home/*/.bash_history --exclude /etc/ssh/ssh_host_* --exclude /etc/ssh/moduli --exclude /etc/udev/rules.d/*persistent-net.rules --exclude /var/lib/ec2/* --exclude=/mnt/* --exclude=/proc/* --exclude=/tmp/* --exclude=/dev/log / {varl}IMAGE_DIR{varr}", - "echo preparing the local working copy", "touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data", - "echo copying the local working copy to the ebs mount", "{cd} {varl}IMAGE_DIR{varr}", - "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 " + SCRIPT_END) + ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"), + ImmutableList + . of(Statements + .interpret( + "echo creating a filesystem and mounting the ebs volume", + "{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}", + "rm -rf {varl}IMAGE_DIR{varr}/*", + "yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-", + "mount {varl}EBS_DEVICE{varr} {varl}EBS_MOUNT_POINT{varr}", + "echo making a local working copy of the boot disk", + "rsync -ax --exclude /ubuntu/.bash_history --exclude /home/*/.bash_history --exclude /etc/ssh/ssh_host_* --exclude /etc/ssh/moduli --exclude /etc/udev/rules.d/*persistent-net.rules --exclude /var/lib/ec2/* --exclude=/mnt/* --exclude=/proc/* --exclude=/tmp/* --exclude=/dev/log / {varl}IMAGE_DIR{varr}", + "echo preparing the local working copy", + "touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data", + "echo copying the local working copy to the ebs mount", + "{cd} {varl}IMAGE_DIR{varr}", + "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 " + SCRIPT_END))) .build(OsFamily.UNIX); } 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 f320ae0671..8358eb9108 100644 --- a/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java +++ b/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNode.java @@ -35,12 +35,15 @@ 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; /** @@ -57,12 +60,12 @@ public class RunScriptOnNode implements SshCallable { private Logger logger = Logger.NULL; public RunScriptOnNode(@Named("SCRIPT_COMPLETE") Predicate runScriptNotRunning, - NodeMetadata node, String scriptName, Payload script) { + NodeMetadata node, String scriptName, Payload 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, Payload script, boolean runAsRoot) { this.runScriptNotRunning = runScriptNotRunning; this.node = checkNotNull(node, "node"); this.scriptName = checkNotNull(scriptName, "scriptName"); @@ -73,7 +76,7 @@ public class RunScriptOnNode implements SshCallable { public static Payload createRunScript(String scriptName, Payload script) { String path = "/tmp/" + scriptName; InitBuilder initBuilder = new InitBuilder(scriptName, path, path, Collections. emptyMap(), - splitOnNewlines(script)); + ImmutableList. of(Statements.interpret(splitOnNewlines(script)))); return Payloads.newByteArrayPayload(initBuilder.build(OsFamily.UNIX).getBytes()); } @@ -100,9 +103,9 @@ public class RunScriptOnNode implements SshCallable { logger.debug("<< complete(%d)", returnVal.getExitCode()); 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()); + .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()); + .getPublicAddresses(), 0), ssh.exec("./" + scriptName + " tailerr").getOutput()); } return returnVal; } @@ -116,23 +119,23 @@ public class RunScriptOnNode implements SshCallable { private ExecResponse runScriptAsRoot() { if (node.getCredentials().identity.equals("root")) { logger.debug(">> running %s as %s@%s", scriptName, node.getCredentials().identity, Iterables.get(node - .getPublicAddresses(), 0)); + .getPublicAddresses(), 0)); return ssh.exec("./" + scriptName + " start"); } else if (ComputeServiceUtils.isKeyAuth(node)) { logger.debug(">> running sudo %s as %s@%s", scriptName, node.getCredentials().identity, Iterables.get(node - .getPublicAddresses(), 0)); + .getPublicAddresses(), 0)); return ssh.exec("sudo ./" + scriptName + " start"); } else { logger.debug(">> running sudo -S %s as %s@%s", scriptName, node.getCredentials().identity, Iterables.get(node - .getPublicAddresses(), 0)); + .getPublicAddresses(), 0)); return ssh.exec(String.format("echo '%s'|sudo -S ./%s", node.getCredentials().credential, scriptName - + " start")); + + " start")); } } private ExecResponse runScriptAsDefaultUser() { logger.debug(">> running script %s as %s@%s", scriptName, node.getCredentials().identity, Iterables.get(node - .getPublicAddresses(), 0)); + .getPublicAddresses(), 0)); return ssh.exec(String.format("./%s", scriptName + " start")); } diff --git a/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java b/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java index 44251b4036..b63b9879ff 100644 --- a/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java +++ b/compute/src/test/java/org/jclouds/compute/StubComputeServiceIntegrationTest.java @@ -46,6 +46,8 @@ import org.jclouds.net.IPSocket; 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; @@ -55,6 +57,7 @@ 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; @@ -242,8 +245,8 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes public static String initScript(String scriptName, String script) { return new InitBuilder(scriptName, "/tmp/" + scriptName, "/tmp/" + scriptName, - ImmutableMap. of(), Iterables.toArray(Splitter.on("\n").split( - new String(checkNotNull(script, "script"))), String.class)) + 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); } diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/InitBuilder.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/InitBuilder.java index 3cd770b341..f7ec65f6e0 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/InitBuilder.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/InitBuilder.java @@ -30,6 +30,8 @@ import static org.jclouds.scriptbuilder.domain.Statements.switchArg; import java.util.Map; +import org.jclouds.scriptbuilder.domain.Statement; + import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; @@ -41,10 +43,10 @@ import com.google.common.collect.Iterables; public class InitBuilder extends ScriptBuilder { @SuppressWarnings("unchecked") - public InitBuilder(String instanceName, String instanceHome, String logDir, - Map variables, String... execLines) { - Map defaultVariables = ImmutableMap.of("instanceName", instanceName, - "instanceHome", instanceHome, "logDir", logDir); + public InitBuilder(String instanceName, String instanceHome, String logDir, Map variables, + Iterable statements) { + Map defaultVariables = ImmutableMap.of("instanceName", instanceName, "instanceHome", + instanceHome, "logDir", logDir); addEnvironmentVariableScope("default", defaultVariables) .addEnvironmentVariableScope(instanceName, variables) .addStatement( @@ -53,31 +55,26 @@ public class InitBuilder extends ScriptBuilder { new ImmutableMap.Builder() .put( "init", - newStatementList(call("default"), - call(instanceName), createRunScript( + newStatementList(call("default"), call(instanceName), + createRunScript( instanceName,// TODO: convert - // so + // so // that // createRunScript // can take from a // variable - Iterables.concat(variables - .keySet(), - defaultVariables - .keySet()), - "{varl}INSTANCE_HOME{varr}", - execLines))) + Iterables.concat(variables.keySet(), + defaultVariables.keySet()), + "{varl}INSTANCE_HOME{varr}", statements))) .put( "status", - newStatementList( - call("default"), + newStatementList(call("default"), findPid("{varl}INSTANCE_NAME{varr}"), interpret("echo [{varl}FOUND_PID{varr}]{lf}"))) .put( "stop", newStatementList(call("default"), - findPid("{varl}INSTANCE_NAME{varr}"), - kill())) + findPid("{varl}INSTANCE_NAME{varr}"), kill())) .put( "start", newStatementList( @@ -88,13 +85,11 @@ public class InitBuilder extends ScriptBuilder { "{varl}LOG_DIR{varr}"))) .put( "tail", - newStatementList( - call("default"), + newStatementList(call("default"), interpret("tail {varl}LOG_DIR{varr}{fs}stdout.log{lf}"))) .put( "tailerr", - newStatementList( - call("default"), + newStatementList(call("default"), interpret("tail {varl}LOG_DIR{varr}{fs}stderr.log{lf}"))) .put( "run", diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateFile.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateFile.java new file mode 100644 index 0000000000..bb4606f928 --- /dev/null +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateFile.java @@ -0,0 +1,113 @@ +/** + * + * 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 com.google.common.base.Preconditions.checkState; +import static org.jclouds.scriptbuilder.domain.Statements.interpret; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +/** + * Creates a run script + * + * @author Adrian Cole + */ +public class CreateFile 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 + this.path = checkNotNull(path, "path"); + this.lines = checkNotNull(lines, "lines"); + checkState(Iterables.size(lines) > 0, "you must pass something to execute"); + } + + public static String escapeVarTokens(String toEscape, OsFamily family) { + Map inputToEscape = Maps.newHashMap(); + for (ShellToken token : ImmutableList.of(ShellToken.VARL, ShellToken.VARR)) { + if (!token.to(family).equals("")) { + String tokenS = "{" + token.toString().toLowerCase() + "}"; + inputToEscape.put(tokenS, "{escvar}" + tokenS); + } + } + for (Entry entry : inputToEscape.entrySet()) { + toEscape = toEscape.replace(entry.getKey(), entry.getValue()); + } + return toEscape; + } + + @Override + public Iterable functionDependecies(OsFamily family) { + return Collections.emptyList(); + } + + @Override + public String render(OsFamily family) { + List statements = Lists.newArrayList(); + if (family == OsFamily.UNIX) { + StringBuilder builder = new StringBuilder(); + 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)); + } + } + return new StatementList(statements).render(family); + } + + private void hereFile(String path, StringBuilder builder) { + builder.append("cat > ").append(path).append(" <<'").append(MARKER).append("'\n"); + for (String line : lines) { + builder.append(line).append("\n"); + } + builder.append(MARKER).append("\n"); + } + + private Statement appendToFile(String line, String path, OsFamily family) { + String quote = ""; + if (!ShellToken.VQ.to(family).equals("")) { + quote = "'"; + } else { + line = escapeVarTokens(line, family); + } + return interpret(addSpaceToEnsureWeDontAccidentallyRedirectFd(String.format("echo %s%s%s>>%s{lf}", quote, line, + quote, path))); + } + + public static final Pattern REDIRECT_FD_PATTERN = Pattern.compile(".*[0-2]>>.*"); + + static String addSpaceToEnsureWeDontAccidentallyRedirectFd(String line) { + return REDIRECT_FD_PATTERN.matcher(line).matches() ? line.replace(">>", " >>") : line; + } + +} \ No newline at end of file diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateRunScript.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateRunScript.java index 29c2391720..a8b02ababc 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateRunScript.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/CreateRunScript.java @@ -20,7 +20,6 @@ package org.jclouds.scriptbuilder.domain; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; import static org.jclouds.scriptbuilder.domain.Statements.interpret; import java.util.Collections; @@ -48,19 +47,13 @@ public class CreateRunScript implements Statement { final String instanceName; final Iterable exports; final String pwd; - final String[] execLines; + final Iterable statements; - public CreateRunScript(String instanceName, Iterable exports, String pwd, - String... execLines) {// TODO: convert so - // that - // createRunScript - // can take from a - // variable + public CreateRunScript(String instanceName, Iterable exports, String pwd, Iterable statements) { this.instanceName = checkNotNull(instanceName, "instanceName"); this.exports = checkNotNull(exports, "exports"); this.pwd = checkNotNull(pwd, "pwd").replaceAll("[/\\\\]", "{fs}"); - this.execLines = checkNotNull(execLines, "execLines"); - checkState(execLines.length > 0, "you must pass something to execute"); + this.statements = checkNotNull(statements, "statements"); } public static class AddTitleToFile implements Statement { @@ -72,10 +65,9 @@ public class CreateRunScript implements Statement { this.file = checkNotNull(file, "file"); } - public static final Map OS_TO_TITLE_PATTERN = ImmutableMap.of( - OsFamily.UNIX, - "echo \"PROMPT_COMMAND='echo -ne \\\"\\033]0;{title}\\007\\\"'\">>{file}\n", - OsFamily.WINDOWS, "echo title {title}>>{file}\r\n"); + public static final Map OS_TO_TITLE_PATTERN = ImmutableMap.of(OsFamily.UNIX, + "echo \"PROMPT_COMMAND='echo -ne \\\"\\033]0;{title}\\007\\\"'\">>{file}\n", OsFamily.WINDOWS, + "echo title {title}>>{file}\r\n"); @Override public Iterable functionDependecies(OsFamily family) { @@ -84,8 +76,8 @@ public class CreateRunScript implements Statement { @Override public String render(OsFamily family) { - return addSpaceToEnsureWeDontAccidentallyRedirectFd(Utils.replaceTokens( - OS_TO_TITLE_PATTERN.get(family), ImmutableMap.of("title", title, "file", file))); + return addSpaceToEnsureWeDontAccidentallyRedirectFd(Utils.replaceTokens(OS_TO_TITLE_PATTERN.get(family), + ImmutableMap.of("title", title, "file", file))); } } @@ -95,14 +87,13 @@ public class CreateRunScript implements Statement { final String file; public AddExportToFile(String export, String value, String file) { - this.export = checkNotNull(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export), - "export"); + this.export = checkNotNull(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export), "export"); this.value = checkNotNull(value, "value"); this.file = checkNotNull(file, "file"); } - public static final Map OS_TO_EXPORT_PATTERN = ImmutableMap.of( - OsFamily.UNIX, "echo \"export {export}='{value}'\">>{file}\n", OsFamily.WINDOWS, + public static final Map OS_TO_EXPORT_PATTERN = ImmutableMap.of(OsFamily.UNIX, + "echo \"export {export}='{value}'\">>{file}\n", OsFamily.WINDOWS, "echo set {export}={value}>>{file}\r\n"); @Override @@ -112,9 +103,8 @@ public class CreateRunScript implements Statement { @Override public String render(OsFamily family) { - return addSpaceToEnsureWeDontAccidentallyRedirectFd(Utils.replaceTokens( - OS_TO_EXPORT_PATTERN.get(family), ImmutableMap.of("export", export, "value", - value, "file", file))); + return addSpaceToEnsureWeDontAccidentallyRedirectFd(Utils.replaceTokens(OS_TO_EXPORT_PATTERN.get(family), + ImmutableMap.of("export", export, "value", value, "file", file))); } } @@ -137,8 +127,8 @@ public class CreateRunScript implements Statement { return Collections.emptyList(); } - public static final Map OS_TO_CHMOD_PATTERN = ImmutableMap.of(OsFamily.UNIX, - "chmod u+x {file}\n", OsFamily.WINDOWS, ""); + public static final Map OS_TO_CHMOD_PATTERN = ImmutableMap.of(OsFamily.UNIX, "chmod u+x {file}\n", + OsFamily.WINDOWS, ""); @Override public String render(OsFamily family) { @@ -158,32 +148,29 @@ public class CreateRunScript implements Statement { statements.add(interpret(builder.toString())); } else { statements.add(interpret(String.format("{rm} %s 2{closeFd}{lf}", runScript))); - for (String line : Splitter.on(ShellToken.LF.to(family)).split( - ShellToken.BEGIN_SCRIPT.to(family))) { + for (String line : Splitter.on(ShellToken.LF.to(family)).split(ShellToken.BEGIN_SCRIPT.to(family))) { if (!line.equals("")) statements.add(appendToFile(line, runScript, family)); } statements.add(new AddTitleToFile(instanceName, runScript)); - statements.add(appendToFile(Utils.writeZeroPath(family).replace(ShellToken.LF.to(family), - ""), runScript, family)); + statements.add(appendToFile(Utils.writeZeroPath(family).replace(ShellToken.LF.to(family), ""), runScript, + family)); statements.add(new AddExportToFile("instanceName", instanceName, runScript)); for (String export : exports) { - statements.add(new AddExportToFile(export, Utils.replaceTokens("{varl}" - + CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export) + "{varr}", - tokenMap), runScript)); + statements + .add(new AddExportToFile(export, Utils.replaceTokens("{varl}" + + CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export) + "{varr}", tokenMap), + runScript)); } statements.add(appendToFile("{cd} " + pwd, runScript, family)); - for (String execLine : execLines) { - statements.add(appendToFile(execLine, runScript, family)); - } - for (String line : Splitter.on(ShellToken.LF.to(family)).split( - ShellToken.END_SCRIPT.to(family))) { + statements.addAll(statements); + for (String line : Splitter.on(ShellToken.LF.to(family)).split(ShellToken.END_SCRIPT.to(family))) { if (!line.equals("")) statements.add(appendToFile(line, runScript, family)); } } - statements.add(interpret(Utils.replaceTokens(OS_TO_CHMOD_PATTERN.get(family), ImmutableMap - .of("file", runScript)))); + statements + .add(interpret(Utils.replaceTokens(OS_TO_CHMOD_PATTERN.get(family), ImmutableMap.of("file", runScript)))); return new StatementList(statements).render(family); } @@ -198,8 +185,8 @@ public class CreateRunScript implements Statement { builder.append("# add desired commands from the user\n"); builder.append("cat >> ").append(runScript).append(" <<'").append(MARKER).append("'\n"); builder.append("cd ").append(pwd).append("\n"); - for (String execLine : execLines) { - builder.append(execLine).append("\n"); + for (Statement statement : statements) { + builder.append(statement.render(OsFamily.UNIX)).append("\n"); } builder.append(MARKER).append("\n"); } @@ -208,15 +195,12 @@ public class CreateRunScript implements Statement { builder.append("# create runscript header\n"); builder.append("cat > ").append(runScript).append(" <<").append(MARKER).append("\n"); builder.append(ShellToken.BEGIN_SCRIPT.to(family)); - builder.append("PROMPT_COMMAND='echo -ne \"\\033]0;").append(instanceName).append( - "\\007\"'\n"); + builder.append("PROMPT_COMMAND='echo -ne \"\\033]0;").append(instanceName).append("\\007\"'\n"); builder.append(Utils.writeZeroPath(family)); builder.append("export INSTANCE_NAME='").append(instanceName).append("'\n"); for (String export : exports) { - String variableNameInUpper = CaseFormat.LOWER_CAMEL - .to(CaseFormat.UPPER_UNDERSCORE, export); - builder.append("export ").append(variableNameInUpper).append("='$").append( - variableNameInUpper).append("'\n"); + String variableNameInUpper = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export); + builder.append("export ").append(variableNameInUpper).append("='$").append(variableNameInUpper).append("'\n"); } builder.append(MARKER).append("\n"); } @@ -228,8 +212,8 @@ public class CreateRunScript implements Statement { } else { line = escapeVarTokens(line, family); } - return interpret(addSpaceToEnsureWeDontAccidentallyRedirectFd(String.format( - "echo %s%s%s>>%s{lf}", quote, line, quote, runScript))); + return interpret(addSpaceToEnsureWeDontAccidentallyRedirectFd(String.format("echo %s%s%s>>%s{lf}", quote, line, + quote, runScript))); } public static final Pattern REDIRECT_FD_PATTERN = Pattern.compile(".*[0-2]>>.*"); diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InterpretableStatement.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InterpretableStatement.java index 59e08a48b0..e9de1ee074 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InterpretableStatement.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InterpretableStatement.java @@ -21,8 +21,11 @@ package org.jclouds.scriptbuilder.domain; import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Arrays; + import org.jclouds.scriptbuilder.util.Utils; +import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; /** @@ -32,14 +35,15 @@ import com.google.common.collect.ImmutableList; */ public class InterpretableStatement implements Statement { - private String statement; + private String[] statements; - public InterpretableStatement(String statement) { - this.statement = checkNotNull(statement, "statement"); + public InterpretableStatement(String... statements) { + this.statements = checkNotNull(statements, "statements"); } public String render(OsFamily family) { - return Utils.replaceTokens(statement, ShellToken.tokenValueMap(family)); + return Utils + .replaceTokens(Joiner.on(ShellToken.LF.to(family)).join(statements), ShellToken.tokenValueMap(family)); } @Override @@ -51,7 +55,7 @@ public class InterpretableStatement implements Statement { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((statement == null) ? 0 : statement.hashCode()); + result = prime * result + Arrays.hashCode(statements); return result; } @@ -64,10 +68,7 @@ public class InterpretableStatement implements Statement { if (getClass() != obj.getClass()) return false; InterpretableStatement other = (InterpretableStatement) obj; - if (statement == null) { - if (other.statement != null) - return false; - } else if (!statement.equals(other.statement)) + if (!Arrays.equals(statements, other.statements)) return false; return true; } 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 74cfe6e371..fdb69039c5 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/Statements.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/Statements.java @@ -41,13 +41,17 @@ public class Statements { return new Call(function, args); } - public static Statement createRunScript(String instanceName, Iterable exports, - String pwd, String... execLines) {// TODO: convert so + public static Statement createFile(String path, Iterable lines) { + return new CreateFile(path, lines); + } + + public static Statement createRunScript(String instanceName, Iterable exports, String pwd, + Iterable statements) {// TODO: convert so // that // createRunScript // can take from a // variable - return new CreateRunScript(instanceName, exports, pwd, execLines); + return new CreateRunScript(instanceName, exports, pwd, statements); } /** @@ -87,20 +91,20 @@ public class Statements { public static Statement kill() { return KILL; } - + /** - * statement can have multiple newlines, note you should use {@code {lf} } to be portable + * statement can have multiple newlines, note you should use {@code lf} to be portable * * @see ShellToken */ - public static Statement interpret(String portableStatement) { - return new InterpretableStatement(portableStatement); + public static Statement interpret(String ... portableStatements) { + return new InterpretableStatement(portableStatements); } /** * interprets and adds a newline to the statement */ public static Statement exec(String portableStatement) { - return interpret(portableStatement+"{lf}"); + return interpret(portableStatement + "{lf}"); } } \ No newline at end of file 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 b2ffa67e5b..abf59d0648 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SwitchArg.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/SwitchArg.java @@ -43,15 +43,14 @@ public class SwitchArg implements Statement { private static final String INDENT = " "; - public static final Map OS_TO_SWITCH_PATTERN = ImmutableMap.of(OsFamily.UNIX, - "case ${arg} in\n", OsFamily.WINDOWS, "goto CASE_%{arg}\r\n"); + public static final Map OS_TO_SWITCH_PATTERN = ImmutableMap.of(OsFamily.UNIX, "case ${arg} in\n", + OsFamily.WINDOWS, "goto CASE_%{arg}\r\n"); - public static final Map OS_TO_END_SWITCH_PATTERN = ImmutableMap.of( - OsFamily.UNIX, "esac\n", OsFamily.WINDOWS, ":END_SWITCH\r\n"); + public static final Map OS_TO_END_SWITCH_PATTERN = ImmutableMap.of(OsFamily.UNIX, "esac\n", + OsFamily.WINDOWS, ":END_SWITCH\r\n"); public static final Map OS_TO_CASE_PATTERN = ImmutableMap.of(OsFamily.UNIX, - "{value})\n{action};;\n", OsFamily.WINDOWS, - ":CASE_{value}\r\n{action}GOTO END_SWITCH\r\n"); + "{value})\n{action};;\n", OsFamily.WINDOWS, ":CASE_{value}\r\n{action}GOTO END_SWITCH\r\n"); private final int arg; @@ -84,26 +83,31 @@ public class SwitchArg implements Statement { public String render(OsFamily family) { StringBuilder switchClause = new StringBuilder(); addArgValidation(switchClause, family); - switchClause.append(Utils.replaceTokens(OS_TO_SWITCH_PATTERN.get(family), ImmutableMap.of( - "arg", arg + ""))); + switchClause.append(Utils.replaceTokens(OS_TO_SWITCH_PATTERN.get(family), ImmutableMap.of("arg", arg + ""))); for (Entry entry : valueToActions.entrySet()) { StringBuilder actionBuilder = new StringBuilder(); + boolean shouldIndent = true; boolean inRunScript = false; - for (String line : Splitter.on(ShellToken.LF.to(family)).split( - entry.getValue().render(family))) { - if (!inRunScript) + boolean inCreateFile = false; + for (String line : Splitter.on(ShellToken.LF.to(family)).split(entry.getValue().render(family))) { + if (shouldIndent) actionBuilder.append(INDENT); actionBuilder.append(line).append(ShellToken.LF.to(family)); if (line.indexOf(CreateRunScript.MARKER) != -1) { inRunScript = inRunScript ? false : true; + } + if (line.indexOf(CreateFile.MARKER) != -1) { + inCreateFile = inCreateFile ? false : true; + } + shouldIndent = !inCreateFile && !inRunScript; + } - actionBuilder.delete(actionBuilder.lastIndexOf(ShellToken.LF.to(family)), actionBuilder - .length()); - switchClause.append(Utils.replaceTokens(OS_TO_CASE_PATTERN.get(family), ImmutableMap.of( - "value", entry.getKey(), "action", actionBuilder.toString()))); + actionBuilder.delete(actionBuilder.lastIndexOf(ShellToken.LF.to(family)), actionBuilder.length()); + switchClause.append(Utils.replaceTokens(OS_TO_CASE_PATTERN.get(family), ImmutableMap.of("value", entry + .getKey(), "action", actionBuilder.toString()))); } switchClause.append(OS_TO_END_SWITCH_PATTERN.get(family)); @@ -114,11 +118,9 @@ public class SwitchArg implements Statement { void addArgValidation(StringBuilder switchClause, OsFamily family) { if (family.equals(OsFamily.WINDOWS)) { for (String value : valueToActions.keySet()) { - switchClause.append("if not \"%").append(arg).append( - String.format("\" == \"%s\" ", value)); + switchClause.append("if not \"%").append(arg).append(String.format("\" == \"%s\" ", value)); } - switchClause.append("(\r\n set EXCEPTION=bad argument: %").append(arg) - .append(" not in "); + switchClause.append("(\r\n set EXCEPTION=bad argument: %").append(arg).append(" not in "); switchClause.append(Joiner.on(" ").join(valueToActions.keySet())); switchClause.append("\r\n goto abort\r\n)\r\n"); } diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/InitBuilderTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/InitBuilderTest.java index 0e0d3de398..dc2f90c824 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/InitBuilderTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/InitBuilderTest.java @@ -19,6 +19,8 @@ package org.jclouds.scriptbuilder; +import static org.jclouds.scriptbuilder.domain.Statements.call; +import static org.jclouds.scriptbuilder.domain.Statements.createFile; import static org.testng.Assert.assertEquals; import java.io.IOException; @@ -26,9 +28,12 @@ import java.net.MalformedURLException; import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.ShellToken; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.scriptbuilder.domain.Statements; import org.testng.annotations.Test; import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.io.CharStreams; import com.google.common.io.Resources; @@ -40,21 +45,20 @@ import com.google.common.io.Resources; */ public class InitBuilderTest { - InitBuilder testInitBuilder = new InitBuilder("mkebsboot", "/mnt/tmp", "/mnt/tmp", ImmutableMap - .of("tmpDir", "/mnt/tmp"), "find /"); + 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 /"))); @Test public void testBuildSimpleWindows() throws MalformedURLException, IOException { - assertEquals(testInitBuilder.build(OsFamily.WINDOWS), CharStreams.toString(Resources - .newReaderSupplier(Resources.getResource("test_init." - + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); + assertEquals(testInitBuilder.build(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.getResource("test_init." - + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); + assertEquals(testInitBuilder.build(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources + .getResource("test_init." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } @Test @@ -64,9 +68,13 @@ public class InitBuilderTest { "mkebsboot",// name of the script "/tmp",// working directory "/tmp/logs",// location of stdout.log and stderr.log - ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", - "ebsMountPoint", "/mnt/ebs"),// variables used inside of the script - "echo creating a filesystem and mounting the ebs volume",// what to execute + ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"),// variables + // used + // inside + // of + // the + // script + ImmutableList. of(Statements.interpret("echo creating a filesystem and mounting the ebs volume",// what to execute "{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}", "rm -rf {varl}IMAGE_DIR{varr}/*", "yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-", @@ -75,17 +83,11 @@ public class InitBuilderTest { "rsync -ax --exclude /ubuntu/.bash_history --exclude /home/*/.bash_history --exclude /etc/ssh/ssh_host_* --exclude /etc/ssh/moduli --exclude /etc/udev/rules.d/*persistent-net.rules --exclude /var/lib/ec2/* --exclude=/mnt/* --exclude=/proc/* --exclude=/tmp/* --exclude=/dev/log / {varl}IMAGE_DIR{varr}", "echo preparing the local working copy", "touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data", - "echo copying the local working copy to the ebs mount", - "{cd} {varl}IMAGE_DIR{varr}", - "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.getResource("test_ebs." + ShellToken.SH.to(OsFamily.UNIX)), - Charsets.UTF_8))); + "echo copying the local working copy to the ebs mount", "{cd} {varl}IMAGE_DIR{varr}", + "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 + .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 f3690a57aa..9fea9578ba 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/ScriptBuilderTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/ScriptBuilderTest.java @@ -20,6 +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.findPid; import static org.jclouds.scriptbuilder.domain.Statements.interpret; import static org.jclouds.scriptbuilder.domain.Statements.kill; @@ -57,28 +58,27 @@ public class ScriptBuilderTest { ImmutableMap .of( "start", - newStatementList( - call("default"), + newStatementList(call("default"), interpret("echo start {varl}RUNTIME{varr}{lf}")), "stop", - newStatementList( - call("default"), + newStatementList(call("default"), interpret("echo stop {varl}RUNTIME{varr}{lf}")), "status", - newStatementList(interpret("echo {vq}the following should be []: [{varl}RUNTIME{varr}]{vq}{lf}"))))); + newStatementList( + createFile("{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(Resources.getResource("test_script." - + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); + assertEquals(testScriptBuilder.build(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.getResource("test_script." - + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); + assertEquals(testScriptBuilder.build(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources + .getResource("test_script." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } ScriptBuilder findPidBuilder = new ScriptBuilder().addStatement(findPid("{args}")).addStatement( @@ -86,40 +86,35 @@ public class ScriptBuilderTest { @Test public void testFindPidWindows() throws MalformedURLException, IOException { - assertEquals(findPidBuilder.build(OsFamily.WINDOWS), CharStreams.toString(Resources - .newReaderSupplier(Resources.getResource("test_find_pid." - + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); + assertEquals(findPidBuilder.build(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.getResource("test_find_pid." - + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); + assertEquals(findPidBuilder.build(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources + .getResource("test_find_pid." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } - ScriptBuilder seekAndDestroyBuilder = new ScriptBuilder().addStatement(findPid("{args}")) - .addStatement(kill()); + ScriptBuilder seekAndDestroyBuilder = new ScriptBuilder().addStatement(findPid("{args}")).addStatement(kill()); @Test public void testSeekAndDestroyWindows() throws MalformedURLException, IOException { - assertEquals(seekAndDestroyBuilder.build(OsFamily.WINDOWS), CharStreams.toString(Resources - .newReaderSupplier(Resources.getResource("test_seek_and_destroy." - + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); + assertEquals(seekAndDestroyBuilder.build(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(Resources.getResource("test_seek_and_destroy." - + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); + assertEquals(seekAndDestroyBuilder.build(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier( + Resources.getResource("test_seek_and_destroy." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } @Test public void testSwitchOn() { ScriptBuilder builder = new ScriptBuilder(); - builder.addStatement(switchArg(1, ImmutableMap.of("start", interpret("echo started{lf}"), - "stop", interpret("echo stopped{lf}")))); + builder.addStatement(switchArg(1, ImmutableMap.of("start", interpret("echo started{lf}"), "stop", + interpret("echo stopped{lf}")))); assertEquals(builder.statements, ImmutableList.of(new SwitchArg(1, ImmutableMap.of("start", interpret("echo started{lf}"), "stop", interpret("echo stopped{lf}"))))); } @@ -134,8 +129,7 @@ public class ScriptBuilderTest { public void testExport() { ScriptBuilder builder = new ScriptBuilder(); builder.addEnvironmentVariableScope("default", ImmutableMap.of("javaHome", "/apps/jdk1.6")); - assertEquals(builder.variableScopes, ImmutableMap.of("default", ImmutableMap.of("javaHome", - "/apps/jdk1.6"))); + assertEquals(builder.variableScopes, ImmutableMap.of("default", ImmutableMap.of("javaHome", "/apps/jdk1.6"))); } @Test diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateFileTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateFileTest.java new file mode 100644 index 0000000000..463e8d68e0 --- /dev/null +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateFileTest.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 static org.jclouds.scriptbuilder.domain.Statements.createFile; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableList; +import com.google.common.io.CharStreams; +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", + "log_location STDOUT", String.format("chef_server_url \"%s\"", "http://localhost:4000"))); + + public void testUNIX() throws IOException { + assertEquals(statement.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources + .getResource("client_rb." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); + } + + public void testWINDOWS() throws IOException { + assertEquals(statement.render(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier(Resources + .getResource("client_rb." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); + } + + public void testRedirectGuard() { + assertEquals(CreateFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo>>"), "foo>>"); + assertEquals(CreateFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo0>>"), "foo0 >>"); + assertEquals(CreateFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo1>>"), "foo1 >>"); + assertEquals(CreateFile.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo2>>"), "foo2 >>"); + } + +} 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 90865cb961..9f5817deba 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateRunScriptTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/CreateRunScriptTest.java @@ -19,6 +19,8 @@ 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.createRunScript; import static org.testng.Assert.assertEquals; @@ -36,30 +38,32 @@ import com.google.common.io.Resources; */ @Test(groups = "unit", testName = "scriptbuilder.CreateRunScriptTest") public class CreateRunScriptTest { - Statement statement = createRunScript("yahooprod", ImmutableList. of("javaHome"), - "{tmp}{fs}{uid}{fs}scripttest", "echo hello", - "echo {varl}JAVA_HOME{varr}{fs}bin{fs}java -DinstanceName={varl}INSTANCE_NAME{varr} myServer.Main"); + Statement statement = createRunScript( + "yahooprod", + ImmutableList. of("javaHome"), + "{tmp}{fs}{uid}{fs}scripttest", + ImmutableList + . of( + call("echo hello"), + createFile("{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"))); public void testUNIX() throws IOException { - assertEquals(statement.render(OsFamily.UNIX), CharStreams.toString(Resources - .newReaderSupplier(Resources.getResource("test_runrun." - + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); + assertEquals(statement.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(Resources + .getResource("test_runrun." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8))); } public void testWINDOWS() throws IOException { - assertEquals(statement.render(OsFamily.WINDOWS), CharStreams.toString(Resources - .newReaderSupplier(Resources.getResource("test_runrun." - + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); + assertEquals(statement.render(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier(Resources + .getResource("test_runrun." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8))); } public void testRedirectGuard() { assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo>>"), "foo>>"); - assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo0>>"), - "foo0 >>"); - assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo1>>"), - "foo1 >>"); - assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo2>>"), - "foo2 >>"); + assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo0>>"), "foo0 >>"); + assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo1>>"), "foo1 >>"); + assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo2>>"), "foo2 >>"); } } 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 69aefc850b..616a8dd9b0 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/SwitchArgTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/domain/SwitchArgTest.java @@ -19,10 +19,15 @@ package org.jclouds.scriptbuilder.domain; +import static org.jclouds.scriptbuilder.domain.Statements.createFile; +import static org.jclouds.scriptbuilder.domain.Statements.interpret; +import static org.jclouds.scriptbuilder.domain.Statements.newStatementList; import static org.testng.Assert.assertEquals; +import java.util.Collections; + import org.testng.annotations.Test; -import static org.jclouds.scriptbuilder.domain.Statements.*; + import com.google.common.collect.ImmutableMap; /** @@ -32,9 +37,10 @@ import com.google.common.collect.ImmutableMap; public class SwitchArgTest { public void testSwitchArgUNIX() { - assertEquals(new SwitchArg(1, ImmutableMap.of("0", interpret("echo hello zero{lf}"), "1", - interpret("echo hello one{lf}"))).render(OsFamily.UNIX), - "case $1 in\n0)\n echo hello zero\n ;;\n1)\n echo hello one\n ;;\nesac\n"); + assertEquals(new SwitchArg(1, ImmutableMap.of("0", newStatementList(createFile( + "{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"); } public void testSwitchArgWindows() { diff --git a/scriptbuilder/src/test/resources/client_rb.cmd b/scriptbuilder/src/test/resources/client_rb.cmd new file mode 100644 index 0000000000000000000000000000000000000000..b3a2b4aa035749354b7e8f7b047fd26b84fd364a GIT binary patch literal 196 zcmYdE%~43Uib*X=j!Di)O^Zp+$xO{F(JM+)FtYOt_2K18P0q+y$jMKS&q*xR>Yaei`QNoIbYLU4$Se`pAP4Iqo-i&KlrQj6kCi*gi{GD=Dctn~GBfQIB` Q /etc/chef/client.rb <<'END_OF_FILE' +log_level :info +log_location STDOUT +chef_server_url "http://localhost:4000" +END_OF_FILE diff --git a/scriptbuilder/src/test/resources/test_init.cmd b/scriptbuilder/src/test/resources/test_init.cmd index e0d437096711d05b35d2d88b722909ef3668b637..f7cc2709c33cb7e049f10816325473ac166d75f1 100644 GIT binary patch delta 17 ZcmdljyIpBRFW2Tr>>HRiALRPQ3;;)W2f_dV delta 27 jcmdn4v|DyVFW2M(9#*!r%)Ar@{mBbCH8> $INSTANCE_HOME/mkebsboot.sh <<'END_OF_SCRIPT' cd $INSTANCE_HOME -find / +cat > /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE' +hello world +END_OF_FILE + +find / || exit 1 + END_OF_SCRIPT # add runscript footer diff --git a/scriptbuilder/src/test/resources/test_runrun.cmd b/scriptbuilder/src/test/resources/test_runrun.cmd index e0bad8b8c4991589fd9ec3cf86b9d58c406c613d..ab5cf7c7bd7ff675bde86f9e7b0bed8d9f04105d 100644 GIT binary patch delta 14 VcmZ3_ww7~)1=9vQrpZ5;%mF771quKF delta 108 zcmZ3>xt?u<1=HjL7B6Y;MAhB)FM6K#LPU9ag$3~ FEC6ZIBMATi diff --git a/scriptbuilder/src/test/resources/test_runrun.sh b/scriptbuilder/src/test/resources/test_runrun.sh index cad630c83c..1ec3307e46 100644 --- a/scriptbuilder/src/test/resources/test_runrun.sh +++ b/scriptbuilder/src/test/resources/test_runrun.sh @@ -15,8 +15,14 @@ END_OF_SCRIPT # add desired commands from the user cat >> /tmp/$USER/scripttest/yahooprod.sh <<'END_OF_SCRIPT' cd /tmp/$USER/scripttest -echo hello -echo $JAVA_HOME/bin/java -DinstanceName=$INSTANCE_NAME myServer.Main +echo hello || return 1 + +cat > /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE' +hello world +END_OF_FILE + +echo $JAVA_HOME/bin/java -DinstanceName=$INSTANCE_NAME myServer.Main || return 1 + END_OF_SCRIPT # add runscript footer diff --git a/scriptbuilder/src/test/resources/test_script.cmd b/scriptbuilder/src/test/resources/test_script.cmd index 2cbca9335b435291bec130adcf2d11a28ce35fc4..b69d2518c3f04004d2f07f5bc60fc8b5c132d912 100644 GIT binary patch delta 139 zcmaFCdV_64A5(owYL0?xh^udaYK&@VuxpT?qpz!KOmT8iW+SNosC^UP(oX zf{~qHs1Glff`US7az?&FMruw@zCw9^QBI1T9Z@DA^p<3#Dx~ED^_Nec%j69J$O$gO delta 11 Scmcb?_JVaoAJgQ2Oi=(Iu>|=5 diff --git a/scriptbuilder/src/test/resources/test_script.sh b/scriptbuilder/src/test/resources/test_script.sh index a7531c352a..97a4422dc5 100644 --- a/scriptbuilder/src/test/resources/test_script.sh +++ b/scriptbuilder/src/test/resources/test_script.sh @@ -22,6 +22,9 @@ stop) echo stop $RUNTIME ;; status) + cat > /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE' +hello world +END_OF_FILE echo "the following should be []: [$RUNTIME]" ;; esac 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 2a1e837e04..f9b4ecf8c0 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 @@ -53,6 +53,7 @@ import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.ShellToken; import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.scriptbuilder.domain.StatementList; +import org.jclouds.scriptbuilder.domain.Statements; import org.jclouds.tools.ant.util.SSHExecute; import com.google.common.annotations.VisibleForTesting; @@ -130,8 +131,7 @@ public class SSHJava extends Java { if (remotedir == null) remotedir = new File(remotebase, id); - String command = createInitScript(osFamily, id, remotedir.getAbsolutePath(), env, - getCommandLine()); + String command = createInitScript(osFamily, id, remotedir.getAbsolutePath(), env, getCommandLine()); try { BufferedWriter out = new BufferedWriter(new FileWriter(new File(localDirectory, "init." @@ -159,8 +159,8 @@ public class SSHJava extends Java { File source = new File(entry.getKey()); if (source.isDirectory()) { set.setDir(new File(entry.getKey())); - mkdirAndCopyTo(remotebase.getAbsolutePath() + ShellToken.FS.to(osFamily) - + entry.getValue(), ImmutableList.of(set)); + mkdirAndCopyTo(remotebase.getAbsolutePath() + ShellToken.FS.to(osFamily) + entry.getValue(), ImmutableList + .of(set)); } else { String destination = remotebase.getAbsolutePath() + ShellToken.FS.to(osFamily) + new File(entry.getValue()).getParent(); @@ -179,19 +179,16 @@ public class SSHJava extends Java { } if (getCommandLine().getBootclasspath() != null) { - copyPathTo(getCommandLine().getBootclasspath(), remotedir.getAbsolutePath() - + "/bootclasspath"); + copyPathTo(getCommandLine().getBootclasspath(), remotedir.getAbsolutePath() + "/bootclasspath"); } if (osFamily == OsFamily.UNIX) { - sshexec(exec("chmod 755 " + remotedir.getAbsolutePath() + "{fs}init.{sh}") - .render(osFamily)); + sshexec(exec("chmod 755 " + remotedir.getAbsolutePath() + "{fs}init.{sh}").render(osFamily)); } - Statement statement = new StatementList(exec("{cd} " + remotedir.getAbsolutePath()), - exec(remotedir.getAbsolutePath() + "{fs}init.{sh} init"), exec(remotedir - .getAbsolutePath() - + "{fs}init.{sh} run")); + Statement statement = new StatementList(exec("{cd} " + remotedir.getAbsolutePath()), exec(remotedir + .getAbsolutePath() + + "{fs}init.{sh} init"), exec(remotedir.getAbsolutePath() + "{fs}init.{sh} run")); try { return sshexecRedirectStreams(statement); } catch (IOException e) { @@ -270,13 +267,11 @@ public class SSHJava extends Java { } private String getScpDir(String path) { - return String.format("%s:%s@%s:%s", userInfo.getName(), - userInfo.getKeyfile() == null ? userInfo.getPassword() : userInfo.getPassphrase(), - scp.getHost(), path); + return String.format("%s:%s@%s:%s", userInfo.getName(), userInfo.getKeyfile() == null ? userInfo.getPassword() + : userInfo.getPassphrase(), scp.getHost(), path); } - void resetPathToUnderPrefixIfExistsAndIsFileIfNotExistsAddAsIs(Path path, String prefix, - StringBuilder destination) { + void resetPathToUnderPrefixIfExistsAndIsFileIfNotExistsAddAsIs(Path path, String prefix, StringBuilder destination) { if (path == null) return; String[] paths = path.list(); @@ -324,8 +319,7 @@ public class SSHJava extends Java { for (Entry entry : shiftMap.entrySet()) { if (in.startsWith(entry.getKey())) { log("match shift map: " + entry.getKey(), Project.MSG_DEBUG); - in = remotebase + ShellToken.FS.to(osFamily) + entry.getValue() - + in.substring(entry.getKey().length()); + in = remotebase + ShellToken.FS.to(osFamily) + entry.getValue() + in.substring(entry.getKey().length()); } } for (Entry entry : replace.entrySet()) { @@ -381,7 +375,7 @@ public class SSHJava extends Java { } InitBuilder testInitBuilder = new InitBuilder(id, basedir, basedir, envVariables, - commandBuilder.toString()); + ImmutableList. of(Statements.interpret( commandBuilder.toString()))); return testInitBuilder.build(osFamily); } @@ -560,11 +554,10 @@ public class SSHJava extends Java { @Override public String toString() { - return "SSHJava [append=" + append + ", env=" + env + ", errorFile=" + errorFile - + ", errorProperty=" + errorProperty + ", localDirectory=" + localDirectory - + ", osFamily=" + osFamily + ", outputFile=" + outputFile + ", outputProperty=" - + outputProperty + ", remoteDirectory=" + remotebase + ", userInfo=" + userInfo - + "]"; + return "SSHJava [append=" + append + ", env=" + env + ", errorFile=" + errorFile + ", errorProperty=" + + errorProperty + ", localDirectory=" + localDirectory + ", osFamily=" + osFamily + ", outputFile=" + + outputFile + ", outputProperty=" + outputProperty + ", remoteDirectory=" + remotebase + ", userInfo=" + + userInfo + "]"; } @Override From 64a52c0420b5e53516617711935659c1defe27d6 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Thu, 2 Sep 2010 01:36:43 -0700 Subject: [PATCH 18/63] updated to allow aggregate client commands --- .../java/org/jclouds/chef/ChefService.java | 11 ++- .../chef/internal/BaseChefService.java | 56 ++++++++--- .../chef/strategy/DeleteAllClientsInList.java | 36 +++++++ .../jclouds/chef/strategy/ListClients.java | 41 ++++++++ .../{GetNodes.java => ListNodes.java} | 6 +- .../CleanupStaleNodesAndClientsImpl.java | 24 +++-- .../internal/DeleteAllClientsInListImpl.java | 81 ++++++++++++++++ .../internal/DeleteAllNodesInListImpl.java | 2 +- .../strategy/internal/ListClientsImpl.java | 94 +++++++++++++++++++ .../{GetNodesImpl.java => ListNodesImpl.java} | 6 +- .../internal/GetNodesImplLiveTest.java | 4 +- 11 files changed, 329 insertions(+), 32 deletions(-) create mode 100644 chef/core/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsInList.java create mode 100644 chef/core/src/main/java/org/jclouds/chef/strategy/ListClients.java rename chef/core/src/main/java/org/jclouds/chef/strategy/{GetNodes.java => ListNodes.java} (90%) create mode 100644 chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsInListImpl.java create mode 100644 chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListClientsImpl.java rename chef/core/src/main/java/org/jclouds/chef/strategy/internal/{GetNodesImpl.java => ListNodesImpl.java} (92%) diff --git a/chef/core/src/main/java/org/jclouds/chef/ChefService.java b/chef/core/src/main/java/org/jclouds/chef/ChefService.java index 6ad1bb8247..d457e7d4f8 100644 --- a/chef/core/src/main/java/org/jclouds/chef/ChefService.java +++ b/chef/core/src/main/java/org/jclouds/chef/ChefService.java @@ -22,6 +22,7 @@ package org.jclouds.chef; import java.io.IOException; import java.io.InputStream; +import org.jclouds.chef.domain.Client; import org.jclouds.chef.domain.Node; import org.jclouds.chef.internal.BaseChefService; @@ -61,7 +62,15 @@ public interface ChefService { Iterable listNodesDetailsMatching(Predicate nodeNameSelector); - Iterable getNodesNamed(Iterable names); + Iterable listNodesNamed(Iterable names); + + void deleteAllClientsInList(Iterable names); + + Iterable listClientsDetails(); + + Iterable listClientsDetailsMatching(Predicate clientNameSelector); + + Iterable listClientsNamed(Iterable names); void updateAutomaticAttributesOnNode(String nodeName); } diff --git a/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java b/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java index db211cc16f..d2c4e6621b 100644 --- a/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java +++ b/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java @@ -33,12 +33,15 @@ import javax.inject.Singleton; import org.jclouds.chef.ChefContext; import org.jclouds.chef.ChefService; +import org.jclouds.chef.domain.Client; import org.jclouds.chef.domain.Node; import org.jclouds.chef.reference.ChefConstants; import org.jclouds.chef.strategy.CleanupStaleNodesAndClients; import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes; +import org.jclouds.chef.strategy.DeleteAllClientsInList; import org.jclouds.chef.strategy.DeleteAllNodesInList; -import org.jclouds.chef.strategy.GetNodes; +import org.jclouds.chef.strategy.ListClients; +import org.jclouds.chef.strategy.ListNodes; import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode; import org.jclouds.io.Payloads; import org.jclouds.io.payloads.RSADecryptingPayload; @@ -64,23 +67,28 @@ public class BaseChefService implements ChefService { private final CleanupStaleNodesAndClients cleanupStaleNodesAndClients; private final CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes; private final DeleteAllNodesInList deleteAllNodesInList; - private final GetNodes getNodes; + private final ListNodes listNodes; + private final DeleteAllClientsInList deleteAllClientsInList; + private final ListClients listClients; private final UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode; private final Provider privateKey; @Inject protected BaseChefService(ChefContext chefContext, CleanupStaleNodesAndClients cleanupStaleNodesAndClients, - CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes, - DeleteAllNodesInList deleteAllNodesInList, GetNodes getNodes, - UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Provider privateKey) { + CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes, + DeleteAllNodesInList deleteAllNodesInList, ListNodes listNodes, + DeleteAllClientsInList deleteAllClientsInList, ListClients listClients, + UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Provider privateKey) { this.chefContext = checkNotNull(chefContext, "chefContext"); this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients"); this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes, - "createNodeAndPopulateAutomaticAttributes"); + "createNodeAndPopulateAutomaticAttributes"); this.deleteAllNodesInList = checkNotNull(deleteAllNodesInList, "deleteAllNodesInList"); - this.getNodes = checkNotNull(getNodes, "getNodes"); + this.listNodes = checkNotNull(listNodes, "listNodes"); + this.deleteAllClientsInList = checkNotNull(deleteAllClientsInList, "deleteAllClientsInList"); + this.listClients = checkNotNull(listClients, "listClients"); this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode, - "updateAutomaticAttributesOnNode"); + "updateAutomaticAttributesOnNode"); this.privateKey = checkNotNull(privateKey, "privateKey"); } @@ -101,17 +109,37 @@ public class BaseChefService implements ChefService { @Override public Iterable listNodesDetails() { - return getNodes.execute(); + return listNodes.execute(); } @Override public Iterable listNodesDetailsMatching(Predicate nodeNameSelector) { - return getNodes.execute(nodeNameSelector); + return listNodes.execute(nodeNameSelector); } @Override - public Iterable getNodesNamed(Iterable names) { - return getNodes.execute(names); + public Iterable listNodesNamed(Iterable names) { + return listNodes.execute(names); + } + + @Override + public void deleteAllClientsInList(Iterable names) { + deleteAllClientsInList.execute(names); + } + + @Override + public Iterable listClientsDetails() { + return listClients.execute(); + } + + @Override + public Iterable listClientsDetailsMatching(Predicate clientNameSelector) { + return listClients.execute(clientNameSelector); + } + + @Override + public Iterable listClientsNamed(Iterable names) { + return listClients.execute(names); } @Override @@ -127,13 +155,13 @@ public class BaseChefService implements ChefService { @Override public byte[] decrypt(InputSupplier supplier) throws IOException { return ByteStreams.toByteArray(new RSADecryptingPayload(Payloads.newPayload(supplier.getInput()), privateKey - .get())); + .get())); } @Override public byte[] encrypt(InputSupplier supplier) throws IOException { return ByteStreams.toByteArray(new RSAEncryptingPayload(Payloads.newPayload(supplier.getInput()), privateKey - .get())); + .get())); } } \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsInList.java b/chef/core/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsInList.java new file mode 100644 index 0000000000..68a1ad21d1 --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsInList.java @@ -0,0 +1,36 @@ +/** + * + * 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.chef.strategy; + +import org.jclouds.chef.strategy.internal.DeleteAllClientsInListImpl; + +import com.google.inject.ImplementedBy; + +/** + * + * + * @author Adrian Cole + */ +@ImplementedBy(DeleteAllClientsInListImpl.class) +public interface DeleteAllClientsInList { + + public void execute(Iterable names); + +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/ListClients.java b/chef/core/src/main/java/org/jclouds/chef/strategy/ListClients.java new file mode 100644 index 0000000000..eef05e2636 --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/ListClients.java @@ -0,0 +1,41 @@ +/** + * + * 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.chef.strategy; + +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.strategy.internal.ListClientsImpl; + +import com.google.common.base.Predicate; +import com.google.inject.ImplementedBy; + +/** + * + * + * @author Adrian Cole + */ +@ImplementedBy(ListClientsImpl.class) +public interface ListClients { + + Iterable execute(); + + Iterable execute(Predicate clientNameSelector); + + Iterable execute(Iterable toGet); +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/GetNodes.java b/chef/core/src/main/java/org/jclouds/chef/strategy/ListNodes.java similarity index 90% rename from chef/core/src/main/java/org/jclouds/chef/strategy/GetNodes.java rename to chef/core/src/main/java/org/jclouds/chef/strategy/ListNodes.java index 02c88153e5..d807783173 100644 --- a/chef/core/src/main/java/org/jclouds/chef/strategy/GetNodes.java +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/ListNodes.java @@ -20,7 +20,7 @@ package org.jclouds.chef.strategy; import org.jclouds.chef.domain.Node; -import org.jclouds.chef.strategy.internal.GetNodesImpl; +import org.jclouds.chef.strategy.internal.ListNodesImpl; import com.google.common.base.Predicate; import com.google.inject.ImplementedBy; @@ -30,8 +30,8 @@ import com.google.inject.ImplementedBy; * * @author Adrian Cole */ -@ImplementedBy(GetNodesImpl.class) -public interface GetNodes { +@ImplementedBy(ListNodesImpl.class) +public interface ListNodes { Iterable execute(); diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java index ba5aa4130f..b5f19a91ab 100644 --- a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java @@ -37,6 +37,9 @@ import javax.inject.Singleton; import org.jclouds.chef.domain.Node; import org.jclouds.chef.reference.ChefConstants; import org.jclouds.chef.strategy.CleanupStaleNodesAndClients; +import org.jclouds.chef.strategy.DeleteAllClientsInList; +import org.jclouds.chef.strategy.DeleteAllNodesInList; +import org.jclouds.chef.strategy.ListNodes; import org.jclouds.domain.JsonBall; import org.jclouds.logging.Logger; @@ -55,13 +58,16 @@ public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClie @Named(ChefConstants.CHEF_LOGGER) protected Logger logger = Logger.NULL; - private final GetNodesImpl getAllNodes; - private final DeleteAllNodesInListImpl deleter; + private final ListNodes nodeLister; + private final DeleteAllNodesInList nodeDeleter; + private final DeleteAllClientsInList clientDeleter; @Inject - public CleanupStaleNodesAndClientsImpl(DeleteAllNodesInListImpl deleter, GetNodesImpl getAllNodes) { - this.getAllNodes = checkNotNull(getAllNodes, "getAllNodes"); - this.deleter = checkNotNull(deleter, "deleter"); + public CleanupStaleNodesAndClientsImpl(DeleteAllNodesInList nodeDeleter, DeleteAllClientsInList clientDeleter, + ListNodes nodeLister) { + this.nodeLister = checkNotNull(nodeLister, "nodeLister"); + this.nodeDeleter = checkNotNull(nodeDeleter, "nodeDeleter"); + this.clientDeleter = checkNotNull(clientDeleter, "clientDeleter"); } @Override @@ -69,7 +75,7 @@ public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClie final Calendar expired = Calendar.getInstance(); expired.setTime(new Date()); expired.add(Calendar.SECOND, -secondsStale); - Iterable staleNodes = filter(getAllNodes.execute(new Predicate() { + Iterable staleNodes = filter(nodeLister.execute(new Predicate() { @Override public boolean apply(String input) { @@ -88,13 +94,15 @@ public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClie } })); - deleter.execute(transform(staleNodes, new Function() { + Iterable nodeNames = transform(staleNodes, new Function() { @Override public String apply(Node from) { return from.getName(); } - })); + }); + nodeDeleter.execute(nodeNames); + clientDeleter.execute(nodeNames); } } \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsInListImpl.java b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsInListImpl.java new file mode 100644 index 0000000000..de771383dc --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsInListImpl.java @@ -0,0 +1,81 @@ +/** + * + * 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.chef.strategy.internal; + +import static com.google.common.collect.Maps.newHashMap; +import static org.jclouds.concurrent.FutureIterables.awaitCompletion; + +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.Constants; +import org.jclouds.chef.ChefAsyncClient; +import org.jclouds.chef.ChefClient; +import org.jclouds.chef.reference.ChefConstants; +import org.jclouds.chef.strategy.DeleteAllClientsInList; +import org.jclouds.logging.Logger; + +import com.google.inject.Inject; + +/** + * + * + * @author Adrian Cole + */ +@Singleton +public class DeleteAllClientsInListImpl implements DeleteAllClientsInList { + + protected final ChefClient chefClient; + protected final ChefAsyncClient chefAsyncClient; + protected final ExecutorService userExecutor; + @Resource + @Named(ChefConstants.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject(optional = true) + @Named(Constants.PROPERTY_REQUEST_TIMEOUT) + protected Long maxTime; + + @Inject + DeleteAllClientsInListImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, + ChefClient getAllClient, ChefAsyncClient ablobstore) { + this.userExecutor = userExecutor; + this.chefAsyncClient = ablobstore; + this.chefClient = getAllClient; + } + + @Override + public void execute(Iterable names) { + Map exceptions = newHashMap(); + Map> responses = newHashMap(); + for (String name : names) { + responses.put(name, chefAsyncClient.deleteClient(name)); + } + exceptions = awaitCompletion(responses, userExecutor, maxTime, logger, String.format( + "deleting clients: %s", names)); + if (exceptions.size() > 0) + throw new RuntimeException(String.format("errors deleting clients: %s: %s", names, exceptions)); + } +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllNodesInListImpl.java b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllNodesInListImpl.java index 8529ae55ea..1de4f361f1 100644 --- a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllNodesInListImpl.java +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllNodesInListImpl.java @@ -74,7 +74,7 @@ public class DeleteAllNodesInListImpl implements DeleteAllNodesInList { responses.put(name, chefAsyncClient.deleteNode(name)); } exceptions = awaitCompletion(responses, userExecutor, maxTime, logger, String.format( - "getting deleting nodes: %s", names)); + "deleting nodes: %s", names)); if (exceptions.size() > 0) throw new RuntimeException(String.format("errors deleting nodes: %s: %s", names, exceptions)); } diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListClientsImpl.java b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListClientsImpl.java new file mode 100644 index 0000000000..80bf87fe56 --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListClientsImpl.java @@ -0,0 +1,94 @@ +/** + * + * 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.chef.strategy.internal; + +import static com.google.common.collect.Iterables.filter; +import static org.jclouds.concurrent.FutureIterables.transformParallel; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.Constants; +import org.jclouds.chef.ChefAsyncClient; +import org.jclouds.chef.ChefClient; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.reference.ChefConstants; +import org.jclouds.chef.strategy.ListClients; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.inject.Inject; + +/** + * + * + * @author Adrian Cole + */ +@Singleton +public class ListClientsImpl implements ListClients { + + protected final ChefClient chefClient; + protected final ChefAsyncClient chefAsyncClient; + protected final ExecutorService userExecutor; + @Resource + @Named(ChefConstants.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject(optional = true) + @Named(Constants.PROPERTY_REQUEST_TIMEOUT) + protected Long maxTime; + + @Inject + ListClientsImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ChefClient getAllClient, + ChefAsyncClient ablobstore) { + this.userExecutor = userExecutor; + this.chefAsyncClient = ablobstore; + this.chefClient = getAllClient; + } + + @Override + public Iterable execute() { + return execute(chefClient.listClients()); + } + + @Override + public Iterable execute(Predicate clientNameSelector) { + return execute(filter(chefClient.listClients(), clientNameSelector)); + } + + @Override + public Iterable execute(Iterable toGet) { + return transformParallel(toGet, new Function>() { + + @Override + public Future apply(String from) { + return chefAsyncClient.getClient(from); + } + + }, userExecutor, maxTime, logger, "getting clients"); + + } + +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListNodesImpl.java similarity index 92% rename from chef/core/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java rename to chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListNodesImpl.java index 477945396b..be3399e7ed 100644 --- a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListNodesImpl.java @@ -34,7 +34,7 @@ import org.jclouds.chef.ChefAsyncClient; import org.jclouds.chef.ChefClient; import org.jclouds.chef.domain.Node; import org.jclouds.chef.reference.ChefConstants; -import org.jclouds.chef.strategy.GetNodes; +import org.jclouds.chef.strategy.ListNodes; import org.jclouds.logging.Logger; import com.google.common.base.Function; @@ -47,7 +47,7 @@ import com.google.inject.Inject; * @author Adrian Cole */ @Singleton -public class GetNodesImpl implements GetNodes { +public class ListNodesImpl implements ListNodes { protected final ChefClient chefClient; protected final ChefAsyncClient chefAsyncClient; @@ -61,7 +61,7 @@ public class GetNodesImpl implements GetNodes { protected Long maxTime; @Inject - GetNodesImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ChefClient getAllNode, + ListNodesImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ChefClient getAllNode, ChefAsyncClient ablobstore) { this.userExecutor = userExecutor; this.chefAsyncClient = ablobstore; diff --git a/chef/core/src/test/java/org/jclouds/chef/strategy/internal/GetNodesImplLiveTest.java b/chef/core/src/test/java/org/jclouds/chef/strategy/internal/GetNodesImplLiveTest.java index 444f3bd324..22ea900a1f 100644 --- a/chef/core/src/test/java/org/jclouds/chef/strategy/internal/GetNodesImplLiveTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/strategy/internal/GetNodesImplLiveTest.java @@ -39,14 +39,14 @@ import com.google.common.collect.ImmutableSet; */ @Test(groups = "live", testName = "chef.GetNodesImplLiveTest") public class GetNodesImplLiveTest extends BaseChefStrategyLiveTest { - private GetNodesImpl strategy; + private ListNodesImpl strategy; private CreateNodeAndPopulateAutomaticAttributesImpl creater; private ChefClient chef; @BeforeTest(groups = "live", dependsOnMethods = "setupClient") void setupStrategy() { this.creater = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class); - this.strategy = injector.getInstance(GetNodesImpl.class); + this.strategy = injector.getInstance(ListNodesImpl.class); this.chef = injector.getInstance(ChefClient.class); } From 8afc0a833ea5fdd7a04388990a142189001c77ea Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Thu, 2 Sep 2010 01:37:27 -0700 Subject: [PATCH 19/63] first working integration between chef and the compute apis --- chef/compute/pom.xml | 6 + chef/compute/src/main/resources/herefile.sh | 5 - .../compute/ChefComputeServiceLiveTest.java | 132 +++++++++++++++--- .../resources/install-chef-gems.sh} | 5 +- chef/compute/src/test/resources/log4j.xml | 28 ++++ 5 files changed, 147 insertions(+), 29 deletions(-) delete mode 100755 chef/compute/src/main/resources/herefile.sh rename chef/compute/src/{main/resources/bootstrap-chef.sh => test/resources/install-chef-gems.sh} (76%) diff --git a/chef/compute/pom.xml b/chef/compute/pom.xml index aa3f9a52c1..f2a00803d4 100644 --- a/chef/compute/pom.xml +++ b/chef/compute/pom.xml @@ -77,6 +77,12 @@ jclouds-compute ${project.version} + + ${project.groupId} + jclouds-jsch + ${project.version} + test + ${project.groupId} jclouds-log4j diff --git a/chef/compute/src/main/resources/herefile.sh b/chef/compute/src/main/resources/herefile.sh deleted file mode 100755 index 7907fbccea..0000000000 --- a/chef/compute/src/main/resources/herefile.sh +++ /dev/null @@ -1,5 +0,0 @@ -( -cat <<'EOP' -@herefile@ -EOP -) > @destination@ \ No newline at end of file diff --git a/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java index d09506237b..de8b0b9b4e 100644 --- a/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java +++ b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java @@ -21,27 +21,52 @@ package org.jclouds.chef.compute; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Sets.newHashSet; +import static org.jclouds.io.Payloads.newStringPayload; +import static org.jclouds.scriptbuilder.domain.Statements.createFile; +import static org.jclouds.scriptbuilder.domain.Statements.exec; +import static org.jclouds.scriptbuilder.domain.Statements.newStatementList; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.Set; import org.jclouds.chef.ChefContext; import org.jclouds.chef.ChefContextFactory; -import org.jclouds.chef.ChefService; +import org.jclouds.compute.BaseComputeServiceLiveTest; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.compute.RunNodesException; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.compute.predicates.NodePredicates; import org.jclouds.crypto.Pems; +import org.jclouds.json.Json; import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.scriptbuilder.domain.OsFamily; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.ssh.jsch.config.JschSshClientModule; +import org.jclouds.util.Utils; import org.testng.annotations.AfterGroups; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; import com.google.common.base.Charsets; +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.ImmutableSet; +import com.google.common.collect.Iterables; import com.google.common.io.Files; import com.google.inject.Module; +import com.google.inject.TypeLiteral; /** * @@ -54,9 +79,12 @@ public class ChefComputeServiceLiveTest { private ChefContext chefContext; private String tag; private String clientName; + private String chefEndpoint; + private Map keyPair; + private Iterable nodes; @BeforeGroups(groups = { "live" }) - public void setupCompute() { + public void setupCompute() throws FileNotFoundException, IOException { tag = System.getProperty("jclouds.compute.tag") != null ? System.getProperty("jclouds.compute.tag") : "jcloudschef"; String computeProvider = checkNotNull(System.getProperty("jclouds.compute.provider"), "jclouds.compute.provider"); @@ -68,12 +96,13 @@ public class ChefComputeServiceLiveTest { String computeCredential = checkNotNull(System.getProperty("jclouds.compute.credential"), "jclouds.compute.credential"); computeContext = new ComputeServiceContextFactory().createContext(computeProvider, computeIdentity, - computeCredential, ImmutableSet.of(new Log4JLoggingModule()), props); + computeCredential, ImmutableSet.of(new Log4JLoggingModule(), getSshModule()), props); + keyPair = BaseComputeServiceLiveTest.setupKeyPair(); } @BeforeGroups(groups = { "live" }) public void setupChef() throws IOException { - String chefEndpoint = checkNotNull(System.getProperty("jclouds.chef.endpoint"), "jclouds.chef.endpoint"); + chefEndpoint = checkNotNull(System.getProperty("jclouds.chef.endpoint"), "jclouds.chef.endpoint"); String chefIdentity = checkNotNull(System.getProperty("jclouds.chef.identity"), "jclouds.chef.identity"); String chefCredentialFile = System.getProperty("jclouds.chef.credential.pem"); if (chefCredentialFile == null || chefCredentialFile.equals("")) @@ -84,27 +113,83 @@ public class ChefComputeServiceLiveTest { Charsets.UTF_8), ImmutableSet. of(new Log4JLoggingModule()), props); } + public static class InstallChefGems implements Statement { + + public String render(OsFamily family) { + try { + return Utils.toStringAndClose(InstallChefGems.class.getClassLoader().getResourceAsStream( + "install-chef-gems.sh")); + } catch (IOException e) { + Throwables.propagate(e); + return null; + } + } + + @Override + public Iterable functionDependecies(OsFamily family) { + return Collections.emptyList(); + } + + } + + protected Module getSshModule() { + return new JschSshClientModule(); + } + @Test - public void test() throws IOException { - clientName = findNextClientName(chefContext, tag + "-%d"); - String clientKey = Pems.pem(chefContext.getApi().createClient(clientName).getPrivateKey()); - - // herefile /etc/chef/client.rb - // log_level :info - // log_location STDOUT - // chef_server_url "@chef_server_url@" - - // herefile /etc/chef/client.pem - // clientKey - // herefile /etc/chef/first-boot.json - // { "run_list": [ "recipe[apache]" ] } - - // then run /usr/bin/chef-client -j /etc/chef/first-boot.json + public void test() throws IOException, InterruptedException { + clientName = findNextClientName(chefContext, tag + "-validator-%d"); System.out.println("created new client: " + clientName); - computeContext.getComputeService().listNodes(); - chefContext.getChefService().listNodesDetails(); + List runList = ImmutableList.of("recipe[apache2]"); + Json json = computeContext.utils().json(); + + String clientKey = Pems.pem(chefContext.getApi().createClient(clientName).getPrivateKey()); + + Statement installChefGems = new InstallChefGems(); + String chefConfigDir = "{root}etc{fs}chef"; + Statement createChefConfigDir = exec("{md} " + chefConfigDir); + Statement createClientRb = createFile(chefConfigDir + "{fs}client.rb", ImmutableList.of("require 'rubygems'", + "require 'ohai'", "o = Ohai::System.new", "o.all_plugins", String.format( + "node_name \"%s-\" + o[:ipaddress]", tag), "log_level :info", "log_location STDOUT", String + .format("validation_client_name \"%s\"", clientName), String.format("chef_server_url \"%s\"", + chefEndpoint))); + + Statement createValidationPem = createFile(chefConfigDir + "{fs}validation.pem", Splitter.on('\n').split( + clientKey)); + String chefBootFile = chefConfigDir + "{fs}first-boot.json"; + + Statement createFirstBoot = createFile(chefBootFile, Collections.singleton(json.toJson(ImmutableMap + .> of("run_list", runList), new TypeLiteral>>() { + }.getType()))); + + Statement runChef = exec("chef-client -j " + chefBootFile); + + Statement bootstrapAndRunChef = newStatementList(installChefGems, createChefConfigDir, createClientRb, + createValidationPem, createFirstBoot, runChef); + + String runScript = bootstrapAndRunChef.render(OsFamily.UNIX); + System.out.println(runScript); + + TemplateOptions options = computeContext.getComputeService().templateOptions().// + installPrivateKey(newStringPayload(keyPair.get("private"))).// + authorizePublicKey(newStringPayload(keyPair.get("public"))).// + runScript(newStringPayload(runScript)); + + try { + nodes = computeContext.getComputeService().runNodesWithTag(tag, 1, options); + } catch (RunNodesException e) { + nodes = Iterables.concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet()); + } + + for (NodeMetadata node : nodes) { + URI uri = URI.create("http://" + Iterables.getLast(node.getPublicAddresses())); + InputStream content = computeContext.utils().http().get(uri); + String string = Utils.toStringAndClose(content); + assert string.indexOf("It works!") >= 0 : string; + } + } private String findNextClientName(ChefContext context, String pattern) { @@ -122,13 +207,16 @@ public class ChefComputeServiceLiveTest { @AfterGroups(groups = { "live" }) public void teardownCompute() { - if (computeContext != null) + if (computeContext != null) { + computeContext.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); computeContext.close(); + } } @AfterGroups(groups = { "live" }) public void teardownChef() { if (chefContext != null) { + chefContext.getChefService().cleanupStaleNodesAndClients(tag + "-", 1); if (clientName != null && chefContext.getApi().clientExists(clientName)) chefContext.getApi().deleteClient(clientName); chefContext.close(); diff --git a/chef/compute/src/main/resources/bootstrap-chef.sh b/chef/compute/src/test/resources/install-chef-gems.sh similarity index 76% rename from chef/compute/src/main/resources/bootstrap-chef.sh rename to chef/compute/src/test/resources/install-chef-gems.sh index 8b11e7b552..e68baaa3cd 100755 --- a/chef/compute/src/main/resources/bootstrap-chef.sh +++ b/chef/compute/src/test/resources/install-chef-gems.sh @@ -4,11 +4,12 @@ if [ ! -f /usr/bin/chef-client ]; then mkdir -p /tmp/bootchef ( cd /tmp/bootchef - curl http://rubyforge.org/frs/download.php/69365/rubygems-1.3.6.tgz| tar -xzf - + wget http://rubyforge.org/frs/download.php/69365/rubygems-1.3.6.tgz + tar xvf rubygems-1.3.6.tgz cd rubygems-1.3.6 ruby setup.rb cp /usr/bin/gem1.8 /usr/bin/gem ) rm -rf /tmp/bootchef gem install chef ohai --no-rdoc --no-ri --verbose -fi \ No newline at end of file +fi diff --git a/chef/compute/src/test/resources/log4j.xml b/chef/compute/src/test/resources/log4j.xml index 535054a74e..66bf053d21 100755 --- a/chef/compute/src/test/resources/log4j.xml +++ b/chef/compute/src/test/resources/log4j.xml @@ -25,7 +25,27 @@ --> + + + + + + + + + + + + + + + + @@ -113,6 +133,9 @@ --> + + + @@ -156,6 +179,11 @@ + + + + + + http://www.apache.org/licenses/LICENSE-2.0.html 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. + ==================================================================== + --> - 4.0.0 - - org.jclouds - jclouds-chef-project - 1.0-SNAPSHOT - ../pom.xml - - org.jclouds - jclouds-chef - jclouds Chef core - jclouds components to access Chef + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 + + org.jclouds + jclouds-chef-project + 1.0-SNAPSHOT + ../pom.xml + + org.jclouds + jclouds-chef + jclouds Chef core + jclouds components to access Chef - - scm:svn:http://jclouds.googlecode.com/svn/trunk/chef - scm:svn:https://jclouds.googlecode.com/svn/trunk/chef - http://jclouds.googlecode.com/svn/trunk/chef - + + scm:svn:http://jclouds.googlecode.com/svn/trunk/chef + scm:svn:https://jclouds.googlecode.com/svn/trunk/chef + http://jclouds.googlecode.com/svn/trunk/chef + - - - - jclouds-googlecode-deploy - http://jclouds.googlecode.com/svn/repo - - false - - - - jclouds-rimu-snapshots-nexus - https://oss.sonatype.org/content/repositories/snapshots - - true - - - + + + + jclouds-googlecode-deploy + http://jclouds.googlecode.com/svn/repo + + false + + + + jclouds-rimu-snapshots-nexus + https://oss.sonatype.org/content/repositories/snapshots + + true + + + - - chef-validator - /etc/chef/validation.pem - http://localhost:4000 - ${jclouds.chef.identity} - ${jclouds.chef.rsa-key} - ${jclouds.chef.endpoint} - + + chef-validator + /etc/chef/validation.pem + http://localhost:4000 + ${jclouds.chef.identity} + ${jclouds.chef.rsa-key} + ${jclouds.chef.endpoint} + - - - ${project.groupId} - jclouds-core - ${project.version} - - - ${project.groupId} - jclouds-core - ${project.version} - test-jar - test - - - log4j - log4j - 1.2.14 - test - - - ${project.groupId} - jclouds-log4j - ${project.version} - test - - - org.danlarkin - clojure-json - 1.1 - true - - - - ${project.groupId} - jclouds-blobstore - ${project.version} - true - - + + + ${project.groupId} + jclouds-core + ${project.version} + + + + org.bouncycastle + bcprov-jdk15 + 1.44 + + + ${project.groupId} + jclouds-scriptbuilder + ${project.version} + + + ${project.groupId} + jclouds-core + ${project.version} + test-jar + test + + + log4j + log4j + 1.2.14 + test + + + ${project.groupId} + jclouds-log4j + ${project.version} + test + + + org.danlarkin + clojure-json + 1.1 + true + + + + ${project.groupId} + jclouds-blobstore + ${project.version} + true + + diff --git a/chef/core/src/main/clojure/org/jclouds/chef.clj b/chef/core/src/main/clojure/org/jclouds/chef.clj index 1f0f084895..fdeb12f590 100644 --- a/chef/core/src/main/clojure/org/jclouds/chef.clj +++ b/chef/core/src/main/clojure/org/jclouds/chef.clj @@ -131,6 +131,24 @@ unit testing" ([#^ChefService chef] (seq (.listNodesDetails chef)))) +(defn update-run-list + "Updates the run-list associated with a tag" + ([run-list tag] (update-run-list run-list tag *chef*)) + ([run-list tag #^ChefService chef] + (.updateRunListForTag chef run-list tag))) + +(defn run-list + "Retrieves the run-list associated with a tag" + ([tag] (run-list tag *chef*)) + ([tag #^ChefService chef] + (seq (.getRunListForTag chef tag)))) + +(defn create-bootstrap + "creates a client and bootstrap script associated with a tag" + ([tag] (create-bootstrap tag *chef*)) + ([tag #^ChefService chef] + (.createClientAndBootstrapScriptForTag chef tag))) + (defn databags "Retrieve the names of the existing data bags in your chef server." ([] (databags *chef*)) diff --git a/chef/core/src/main/java/org/jclouds/chef/ChefService.java b/chef/core/src/main/java/org/jclouds/chef/ChefService.java index d457e7d4f8..09dcb2ca6b 100644 --- a/chef/core/src/main/java/org/jclouds/chef/ChefService.java +++ b/chef/core/src/main/java/org/jclouds/chef/ChefService.java @@ -21,10 +21,12 @@ package org.jclouds.chef; import java.io.IOException; import java.io.InputStream; +import java.util.List; import org.jclouds.chef.domain.Client; import org.jclouds.chef.domain.Node; import org.jclouds.chef.internal.BaseChefService; +import org.jclouds.io.Payload; import com.google.common.base.Predicate; import com.google.common.io.InputSupplier; @@ -56,6 +58,43 @@ public interface ChefService { */ Node createNodeAndPopulateAutomaticAttributes(String nodeName, Iterable runList); + /** + * Creates all steps necessary to bootstrap and run the chef client. + * + * @param tag + * corresponds to a configured + * {@link org.jclouds.chef.reference.ChefConstants#CHEF_BOOTSTRAP_DATABAG databag} + * where run_list and other information are stored + * @return boot script + * @see #updateRunListForTag + */ + Payload createClientAndBootstrapScriptForTag(String tag); + + /** + * assigns a run list to all nodes bootstrapped with a certain tag + * + * @param runList + * list of recipes or roles to assign. syntax is {@code recipe[name]} and {@code + * role[name]} + * + * @param tag + * corresponds to a configured + * {@link org.jclouds.chef.reference.ChefConstants#CHEF_BOOTSTRAP_DATABAG databag} + * where run_list and other information are stored + * @see #makeChefClientBootstrapScriptForTag + */ + void updateRunListForTag(Iterable runList, String tag); + + /** + * @param tag + * corresponds to a configured + * {@link org.jclouds.chef.reference.ChefConstants#CHEF_BOOTSTRAP_DATABAG databag} + * where run_list and other information are stored + * @return run list for all nodes bootstrapped with a certain tag + * @see #updateRunListForTag + */ + List getRunListForTag(String tag); + void deleteAllNodesInList(Iterable names); Iterable listNodesDetails(); @@ -63,7 +102,7 @@ public interface ChefService { Iterable listNodesDetailsMatching(Predicate nodeNameSelector); Iterable listNodesNamed(Iterable names); - + void deleteAllClientsInList(Iterable names); Iterable listClientsDetails(); diff --git a/chef/core/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java b/chef/core/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java index 1088b85196..8e8b48d760 100644 --- a/chef/core/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java +++ b/chef/core/src/main/java/org/jclouds/chef/config/BaseChefRestClientModule.java @@ -65,7 +65,7 @@ public class BaseChefRestClientModule extends RestClientModule { } protected BaseChefRestClientModule(Class syncClientType, Class asyncClientType, - Map, Class> delegates) { + Map, Class> delegates) { super(syncClientType, asyncClientType, delegates); } @@ -91,10 +91,10 @@ public class BaseChefRestClientModule extends RestClientModule { @Provides @Singleton public PrivateKey provideKey(Crypto crypto, @Named(PROPERTY_CREDENTIAL) String pem) throws InvalidKeySpecException, - IOException { + IOException { return crypto.rsaKeyFactory().generatePrivate(Pems.privateKeySpec(InputSuppliers.of(pem))); } - + @Override protected void bindErrorHandlers() { bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ChefErrorHandler.class); diff --git a/chef/core/src/main/java/org/jclouds/chef/config/ChefRestClientModule.java b/chef/core/src/main/java/org/jclouds/chef/config/ChefRestClientModule.java index b27a135dbd..c845cb1487 100644 --- a/chef/core/src/main/java/org/jclouds/chef/config/ChefRestClientModule.java +++ b/chef/core/src/main/java/org/jclouds/chef/config/ChefRestClientModule.java @@ -19,10 +19,24 @@ package org.jclouds.chef.config; +import java.util.List; +import java.util.Map; + +import javax.inject.Singleton; + import org.jclouds.chef.ChefAsyncClient; import org.jclouds.chef.ChefClient; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.functions.ClientForTag; +import org.jclouds.chef.functions.RunListForTag; +import org.jclouds.chef.statements.InstallChefGems; import org.jclouds.http.RequiresHttp; import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.scriptbuilder.domain.Statement; + +import com.google.common.collect.MapMaker; +import com.google.inject.Provides; +import com.google.inject.name.Names; /** * Configures the Chef connection. @@ -37,4 +51,22 @@ public class ChefRestClientModule extends BaseChefRestClientModule> runListForTag(RunListForTag runListForTag) { + return new MapMaker().makeComputingMap(runListForTag); + } + + @Provides + @Singleton + Map tagToClient(ClientForTag tagToClient) { + return new MapMaker().makeComputingMap(tagToClient); + } + + @Override + protected void configure() { + bind(Statement.class).annotatedWith(Names.named("installChefGems")).to(InstallChefGems.class); + super.configure(); + } + } \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/functions/ClientForTag.java b/chef/core/src/main/java/org/jclouds/chef/functions/ClientForTag.java new file mode 100644 index 0000000000..6ff71ab03e --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/functions/ClientForTag.java @@ -0,0 +1,69 @@ +/** + * + * 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.chef.functions; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Sets.newHashSet; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.ChefClient; +import org.jclouds.chef.domain.Client; + +import com.google.common.base.Function; + +/** + * + * Generates a client relevant for a particular tag + * + * @author Adrian Cole + */ +@Singleton +public class ClientForTag implements Function { + private final ChefClient chefClient; + + @Inject + public ClientForTag(ChefClient chefClient) { + this.chefClient = checkNotNull(chefClient, "chefClient"); + } + + @Override + public Client apply(String from) { + String clientName = findNextClientName(chefClient.listClients(), from + "-validator-%02d"); + Client client = chefClient.createClient(clientName); + // response from create only includes the key + return new Client(null, null, clientName, clientName, false, client.getPrivateKey()); + } + + private static String findNextClientName(Set clients, String pattern) { + String clientName; + Set names = newHashSet(clients); + int index = 0; + while (true) { + clientName = String.format(pattern,index++); + if (!names.contains(clientName)) + break; + } + return clientName; + } +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/functions/RunListForTag.java b/chef/core/src/main/java/org/jclouds/chef/functions/RunListForTag.java new file mode 100644 index 0000000000..d847ff4d16 --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/functions/RunListForTag.java @@ -0,0 +1,71 @@ +/** + * + * 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.chef.functions; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static org.jclouds.chef.reference.ChefConstants.CHEF_BOOTSTRAP_DATABAG; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.chef.ChefClient; +import org.jclouds.chef.domain.DatabagItem; +import org.jclouds.json.Json; + +import com.google.common.base.Function; +import com.google.inject.TypeLiteral; + +/** + * + * Retrieves the run-list for a specific tag + * + * + * @author Adrian Cole + */ +@Singleton +public class RunListForTag implements Function> { + public static final Type RUN_LIST_TYPE = new TypeLiteral>>() { + }.getType(); + private final ChefClient client; + private final Json json; + private final String databag; + + @Inject + public RunListForTag(@Named(CHEF_BOOTSTRAP_DATABAG) String databag, ChefClient client, Json json) { + this.databag = checkNotNull(databag, "databag"); + this.client = checkNotNull(client, "client"); + this.json = checkNotNull(json, "json"); + } + + @SuppressWarnings("unchecked") + @Override + public List apply(String from) { + DatabagItem list = client.getDatabagItem(databag, from); + checkState(list != null, "databag item %s/%s not found", databag, from); + return ((Map>) json.fromJson(list.toString(), RUN_LIST_TYPE)).get("run_list"); + } + +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/functions/TagToBootScript.java b/chef/core/src/main/java/org/jclouds/chef/functions/TagToBootScript.java new file mode 100644 index 0000000000..b4b2e3f574 --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/functions/TagToBootScript.java @@ -0,0 +1,118 @@ +/** + * + * 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.chef.functions; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static org.jclouds.io.Payloads.newStringPayload; +import static org.jclouds.scriptbuilder.domain.Statements.createFile; +import static org.jclouds.scriptbuilder.domain.Statements.exec; +import static org.jclouds.scriptbuilder.domain.Statements.newStatementList; + +import java.lang.reflect.Type; +import java.net.URI; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.chef.domain.Client; +import org.jclouds.crypto.Pems; +import org.jclouds.io.Payload; +import org.jclouds.json.Json; +import org.jclouds.rest.annotations.Provider; +import org.jclouds.scriptbuilder.domain.OsFamily; +import org.jclouds.scriptbuilder.domain.Statement; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.inject.TypeLiteral; + +/** + * + * Generates a bootstrap script relevant for a particular tag + * + * @author Adrian Cole + */ +@Singleton +public class TagToBootScript implements Function { + @VisibleForTesting + static final Type RUN_LIST_TYPE = new TypeLiteral>>() { + }.getType(); + private final URI endpoint; + private final Json json; + private final Map tagToClient; + private final Map> runListForTag; + private final Statement installChefGems; + + @Inject + public TagToBootScript(@Provider URI endpoint, Json json, Map tagToClient, + Map> runListForTag, @Named("installChefGems") Statement installChefGems) { + this.endpoint = checkNotNull(endpoint, "endpoint"); + this.json = checkNotNull(json, "json"); + this.tagToClient = checkNotNull(tagToClient, "tagToClient"); + this.runListForTag = checkNotNull(runListForTag, "runListForTag"); + this.installChefGems = checkNotNull(installChefGems, "installChefGems"); + } + + public Payload apply(String tag) { + checkNotNull(tag, "tag"); + + Client client = tagToClient.get(tag); + checkState(client != null, "could not get a client for tag %s", tag); + checkState(client.getClientname() != null, "clientname null for %s", client); + checkState(client.getPrivateKey() != null, "privatekey null for %s", client); + + List runList = runListForTag.get(tag); + checkState(runList != null, "runList for %s was not found", tag); + checkState(runList.size() > 0, "runList for %s was empty", tag); + + String chefConfigDir = "{root}etc{fs}chef"; + Statement createChefConfigDir = exec("{md} " + chefConfigDir); + Statement createClientRb = createFile(chefConfigDir + "{fs}client.rb", ImmutableList.of("require 'rubygems'", + "require 'ohai'", "o = Ohai::System.new", "o.all_plugins", String.format( + "node_name \"%s-\" + o[:ipaddress]", tag), "log_level :info", "log_location STDOUT", String + .format("validation_client_name \"%s\"", client.getClientname()), String.format( + "chef_server_url \"%s\"", endpoint))); + + Statement createValidationPem = createFile(chefConfigDir + "{fs}validation.pem", Splitter.on('\n').split( + Pems.pem(client.getPrivateKey()))); + + String chefBootFile = chefConfigDir + "{fs}first-boot.json"; + + Statement createFirstBoot = createFile(chefBootFile, Collections.singleton(json.toJson(ImmutableMap + .> of("run_list", runList), RUN_LIST_TYPE))); + + Statement runChef = exec("chef-client -j " + chefBootFile); + + Statement bootstrapAndRunChef = newStatementList(installChefGems, createChefConfigDir, createClientRb, + createValidationPem, createFirstBoot, runChef); + + String runScript = bootstrapAndRunChef.render(OsFamily.UNIX); + return newStringPayload(runScript); + } + +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefPropertiesBuilder.java b/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefPropertiesBuilder.java index d4ddde8f3a..6d4339502b 100644 --- a/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefPropertiesBuilder.java +++ b/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefPropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.chef.internal; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; +import static org.jclouds.chef.reference.ChefConstants.CHEF_BOOTSTRAP_DATABAG; import java.util.Properties; @@ -38,6 +39,7 @@ public abstract class BaseChefPropertiesBuilder extends PropertiesBuilder { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_SESSION_INTERVAL, "1"); properties.setProperty(PROPERTY_API_VERSION, ChefAsyncClient.VERSION); + properties.setProperty(CHEF_BOOTSTRAP_DATABAG, "bootstrap"); return properties; } diff --git a/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java b/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java index d2c4e6621b..2efe227a9f 100644 --- a/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java +++ b/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java @@ -20,10 +20,12 @@ package org.jclouds.chef.internal; import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.reference.ChefConstants.CHEF_BOOTSTRAP_DATABAG; import java.io.IOException; import java.io.InputStream; import java.security.PrivateKey; +import java.util.List; import javax.annotation.Resource; import javax.inject.Inject; @@ -34,7 +36,10 @@ import javax.inject.Singleton; import org.jclouds.chef.ChefContext; import org.jclouds.chef.ChefService; import org.jclouds.chef.domain.Client; +import org.jclouds.chef.domain.DatabagItem; import org.jclouds.chef.domain.Node; +import org.jclouds.chef.functions.RunListForTag; +import org.jclouds.chef.functions.TagToBootScript; import org.jclouds.chef.reference.ChefConstants; import org.jclouds.chef.strategy.CleanupStaleNodesAndClients; import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes; @@ -43,12 +48,15 @@ import org.jclouds.chef.strategy.DeleteAllNodesInList; import org.jclouds.chef.strategy.ListClients; import org.jclouds.chef.strategy.ListNodes; import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode; +import org.jclouds.io.Payload; import org.jclouds.io.Payloads; import org.jclouds.io.payloads.RSADecryptingPayload; import org.jclouds.io.payloads.RSAEncryptingPayload; import org.jclouds.logging.Logger; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; import com.google.common.io.ByteStreams; import com.google.common.io.InputSupplier; @@ -72,13 +80,17 @@ public class BaseChefService implements ChefService { private final ListClients listClients; private final UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode; private final Provider privateKey; + private final TagToBootScript tagToBootScript; + private final String databag; + private final RunListForTag runListForTag; @Inject protected BaseChefService(ChefContext chefContext, CleanupStaleNodesAndClients cleanupStaleNodesAndClients, CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes, DeleteAllNodesInList deleteAllNodesInList, ListNodes listNodes, DeleteAllClientsInList deleteAllClientsInList, ListClients listClients, - UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Provider privateKey) { + UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Provider privateKey, + @Named(CHEF_BOOTSTRAP_DATABAG) String databag, TagToBootScript tagToBootScript, RunListForTag runListForTag) { this.chefContext = checkNotNull(chefContext, "chefContext"); this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients"); this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes, @@ -90,6 +102,9 @@ public class BaseChefService implements ChefService { this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode, "updateAutomaticAttributesOnNode"); this.privateKey = checkNotNull(privateKey, "privateKey"); + this.tagToBootScript = checkNotNull(tagToBootScript, "tagToBootScript"); + this.databag = checkNotNull(databag, "databag"); + this.runListForTag = checkNotNull(runListForTag, "runListForTag"); } @Override @@ -152,6 +167,30 @@ public class BaseChefService implements ChefService { return chefContext; } + @Override + public Payload createClientAndBootstrapScriptForTag(String tag) { + return tagToBootScript.apply(tag); + } + + @Override + public void updateRunListForTag(Iterable runList, String tag) { + try { + chefContext.getApi().createDatabag(databag); + } catch (IllegalStateException e) { + + } + chefContext.getApi().updateDatabagItem( + databag, + new DatabagItem(tag, chefContext.utils().json().toJson( + ImmutableMap.> of("run_list", Lists.newArrayList(runList)), + RunListForTag.RUN_LIST_TYPE))); + } + + @Override + public List getRunListForTag(String tag) { + return runListForTag.apply(tag); + } + @Override public byte[] decrypt(InputSupplier supplier) throws IOException { return ByteStreams.toByteArray(new RSADecryptingPayload(Payloads.newPayload(supplier.getInput()), privateKey diff --git a/chef/core/src/main/java/org/jclouds/chef/reference/ChefConstants.java b/chef/core/src/main/java/org/jclouds/chef/reference/ChefConstants.java index 1eb264a767..1286124a36 100644 --- a/chef/core/src/main/java/org/jclouds/chef/reference/ChefConstants.java +++ b/chef/core/src/main/java/org/jclouds/chef/reference/ChefConstants.java @@ -28,8 +28,7 @@ public interface ChefConstants { /** * There are generally 3 types of identities *

@@ -49,4 +48,11 @@ public interface ChefConstants { public static final String CHEF_NODE = "chef.node"; public static final String CHEF_NODE_PATTERN = "chef.node-pattern"; public static final String CHEF_RUN_LIST = "chef.run-list"; + /** + * databag that holds chef bootstrap hints, should be a json ball in the following format: + *

+ * {"tag":{"run_list":["recipe[apache2]"]}} + */ + public static final String CHEF_BOOTSTRAP_DATABAG = "chef.bootstrap-databag"; + } diff --git a/chef/core/src/main/java/org/jclouds/chef/statements/InstallChefGems.java b/chef/core/src/main/java/org/jclouds/chef/statements/InstallChefGems.java new file mode 100644 index 0000000000..6681f743c0 --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/statements/InstallChefGems.java @@ -0,0 +1,54 @@ +/** + * + * 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.chef.statements; + +import java.io.IOException; +import java.util.Collections; + +import javax.inject.Singleton; + +import org.jclouds.scriptbuilder.domain.OsFamily; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.util.Utils; + +import com.google.common.base.Throwables; + +/** + * @author Adrian Cole + */ +@Singleton +public class InstallChefGems implements Statement { + @Override + public String render(OsFamily family) { + try { + return Utils.toStringAndClose(InstallChefGems.class.getClassLoader().getResourceAsStream( + "install-chef-gems.sh")); + } catch (IOException e) { + Throwables.propagate(e); + return null; + } + } + + @Override + public Iterable functionDependecies(OsFamily family) { + return Collections.emptyList(); + } + +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/test/config/TransientChefClientModule.java b/chef/core/src/main/java/org/jclouds/chef/test/config/TransientChefClientModule.java index 3746661014..2b6587a671 100644 --- a/chef/core/src/main/java/org/jclouds/chef/test/config/TransientChefClientModule.java +++ b/chef/core/src/main/java/org/jclouds/chef/test/config/TransientChefClientModule.java @@ -18,16 +18,25 @@ */ package org.jclouds.chef.test.config; +import java.util.List; +import java.util.Map; + import javax.inject.Singleton; import org.jclouds.blobstore.TransientAsyncBlobStore; import org.jclouds.chef.ChefAsyncClient; import org.jclouds.chef.ChefClient; import org.jclouds.chef.config.BaseChefRestClientModule; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.functions.ClientForTag; +import org.jclouds.chef.functions.RunListForTag; +import org.jclouds.chef.statements.InstallChefGems; import org.jclouds.chef.test.TransientChefAsyncClient; import org.jclouds.chef.test.TransientChefClient; import org.jclouds.rest.RestContextFactory; +import org.jclouds.scriptbuilder.domain.Statement; +import com.google.common.collect.MapMaker; import com.google.inject.Provides; import com.google.inject.name.Names; @@ -44,8 +53,9 @@ public class TransientChefClientModule extends BaseChefRestClientModule> runListForTag(RunListForTag runListForTag) { + return new MapMaker().makeComputingMap(runListForTag); + } + + @Provides + @Singleton + Map tagToClient(ClientForTag tagToClient) { + return new MapMaker().makeComputingMap(tagToClient); + } + } \ No newline at end of file diff --git a/chef/compute/src/test/resources/install-chef-gems.sh b/chef/core/src/main/resources/install-chef-gems.sh similarity index 100% rename from chef/compute/src/test/resources/install-chef-gems.sh rename to chef/core/src/main/resources/install-chef-gems.sh diff --git a/chef/core/src/test/clojure/org/jclouds/chef_test.clj b/chef/core/src/test/clojure/org/jclouds/chef_test.clj index 8b74be37f8..fb26934fad 100644 --- a/chef/core/src/test/clojure/org/jclouds/chef_test.clj +++ b/chef/core/src/test/clojure/org/jclouds/chef_test.clj @@ -67,3 +67,6 @@ (is (create-databag-item "databag" {:id "databag-item2" :value "databag-value2"})) (is (= {:id "databag-item2" :value "databag-value2"} (databag-item "databag" "databag-item2")))) +(deftest run-list-test + (update-run-list #{"recipe[foo]"} "tag") + (is (= ["recipe[foo]"] (run-list "tag")))) diff --git a/chef/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java b/chef/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java index da243dc410..f698e0b163 100644 --- a/chef/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java @@ -39,7 +39,7 @@ import com.google.inject.Injector; /** * @author Adrian Cole */ -@Test(groups = "unit", testName = "chef.BindHexEncodedMD5sToJsonPayloadTest") +@Test(groups = "unit", testName = "chef.BootstrapChefClientTest") public class BindHexEncodedMD5sToJsonPayloadTest { Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule()); diff --git a/chef/core/src/test/java/org/jclouds/chef/functions/ClientForTagTest.java b/chef/core/src/test/java/org/jclouds/chef/functions/ClientForTagTest.java new file mode 100644 index 0000000000..8157ecc612 --- /dev/null +++ b/chef/core/src/test/java/org/jclouds/chef/functions/ClientForTagTest.java @@ -0,0 +1,112 @@ +/** + * + * 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.chef.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.io.IOException; +import java.security.PrivateKey; + +import org.jclouds.chef.ChefClient; +import org.jclouds.chef.domain.Client; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "chef.ClientForTagTest") +public class ClientForTagTest { + + public void testWhenNoClientsInList() throws IOException { + ChefClient chefClient = createMock(ChefClient.class); + Client client = createMock(Client.class); + PrivateKey privateKey = createMock(PrivateKey.class); + + ClientForTag fn = new ClientForTag(chefClient); + + expect(chefClient.listClients()).andReturn(ImmutableSet. of()); + expect(chefClient.createClient("foo-validator-00")).andReturn(client); + expect(client.getPrivateKey()).andReturn(privateKey); + + replay(client); + replay(chefClient); + + Client compare = fn.apply("foo"); + assertEquals(compare.getClientname(), "foo-validator-00"); + assertEquals(compare.getName(), "foo-validator-00"); + assertEquals(compare.getPrivateKey(), privateKey); + + verify(client); + verify(chefClient); + } + + public void testWhenClientsInListAddsToEnd() throws IOException { + ChefClient chefClient = createMock(ChefClient.class); + Client client = createMock(Client.class); + PrivateKey privateKey = createMock(PrivateKey.class); + + ClientForTag fn = new ClientForTag(chefClient); + + expect(chefClient.listClients()).andReturn( + ImmutableSet. of("foo-validator-00", "foo-validator-01", "foo-validator-02")); + expect(chefClient.createClient("foo-validator-03")).andReturn(client); + expect(client.getPrivateKey()).andReturn(privateKey); + + replay(client); + replay(chefClient); + + Client compare = fn.apply("foo"); + assertEquals(compare.getClientname(), "foo-validator-03"); + assertEquals(compare.getName(), "foo-validator-03"); + assertEquals(compare.getPrivateKey(), privateKey); + + verify(client); + verify(chefClient); + } + + public void testWhenClientsInListReplacesMissing() throws IOException { + ChefClient chefClient = createMock(ChefClient.class); + Client client = createMock(Client.class); + PrivateKey privateKey = createMock(PrivateKey.class); + + ClientForTag fn = new ClientForTag(chefClient); + + expect(chefClient.listClients()).andReturn(ImmutableSet. of("foo-validator-00", "foo-validator-02")); + expect(chefClient.createClient("foo-validator-01")).andReturn(client); + expect(client.getPrivateKey()).andReturn(privateKey); + + replay(client); + replay(chefClient); + + Client compare = fn.apply("foo"); + assertEquals(compare.getClientname(), "foo-validator-01"); + assertEquals(compare.getName(), "foo-validator-01"); + assertEquals(compare.getPrivateKey(), privateKey); + + verify(client); + verify(chefClient); + } +} diff --git a/chef/core/src/test/java/org/jclouds/chef/functions/RunListForTagTest.java b/chef/core/src/test/java/org/jclouds/chef/functions/RunListForTagTest.java new file mode 100644 index 0000000000..b5a5e34ad5 --- /dev/null +++ b/chef/core/src/test/java/org/jclouds/chef/functions/RunListForTagTest.java @@ -0,0 +1,106 @@ +/** + * + * 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.chef.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.io.IOException; + +import org.jclouds.chef.ChefClient; +import org.jclouds.chef.config.ChefParserModule; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.domain.DatabagItem; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "chef.RunListForTagTest") +public class RunListForTagTest { + Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule()); + Json json = injector.getInstance(Json.class); + + @Test(expectedExceptions = IllegalStateException.class) + public void testWhenNoDatabagItem() throws IOException { + ChefClient chefClient = createMock(ChefClient.class); + Client client = createMock(Client.class); + + RunListForTag fn = new RunListForTag("jclouds", chefClient, json); + + expect(chefClient.getDatabagItem("jclouds", "foo")).andReturn(null); + + replay(client); + replay(chefClient); + + fn.apply("foo"); + + verify(client); + verify(chefClient); + } + + @Test + public void testOneRecipe() throws IOException { + ChefClient chefClient = createMock(ChefClient.class); + Client client = createMock(Client.class); + + RunListForTag fn = new RunListForTag("jclouds", chefClient, json); + + expect(chefClient.getDatabagItem("jclouds", "foo")).andReturn( + new DatabagItem("foo", "{\"run_list\":[\"recipe[apache2]\"]}")); + + replay(client); + replay(chefClient); + + assertEquals(fn.apply("foo"), ImmutableList.of("recipe[apache2]")); + + verify(client); + verify(chefClient); + } + + @Test + public void testTwoRecipes() throws IOException { + ChefClient chefClient = createMock(ChefClient.class); + Client client = createMock(Client.class); + + RunListForTag fn = new RunListForTag("jclouds", chefClient, json); + + expect(chefClient.getDatabagItem("jclouds", "foo")).andReturn( + new DatabagItem("foo", "{\"run_list\":[\"recipe[apache2]\",\"recipe[mysql]\"]}")); + + replay(client); + replay(chefClient); + + assertEquals(fn.apply("foo"), ImmutableList.of("recipe[apache2]", "recipe[mysql]")); + + verify(client); + verify(chefClient); + } + +} diff --git a/chef/core/src/test/java/org/jclouds/chef/functions/TagToBootScriptTest.java b/chef/core/src/test/java/org/jclouds/chef/functions/TagToBootScriptTest.java new file mode 100644 index 0000000000..238943089f --- /dev/null +++ b/chef/core/src/test/java/org/jclouds/chef/functions/TagToBootScriptTest.java @@ -0,0 +1,104 @@ +/** + * + * 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.chef.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.io.IOException; +import java.net.URI; +import java.security.PrivateKey; +import java.util.List; + +import org.jclouds.chef.config.ChefParserModule; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.statements.InstallChefGems; +import org.jclouds.crypto.PemsTest; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import org.jclouds.scriptbuilder.domain.Statement; +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.io.CharStreams; +import com.google.common.io.Resources; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "chef.TagToBootScriptTest") +public class TagToBootScriptTest { + + Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule()); + Json json = injector.getInstance(Json.class); + Statement installChefGems = new InstallChefGems(); + + @Test(expectedExceptions = IllegalStateException.class) + public void testMustHaveClients() { + TagToBootScript fn = new TagToBootScript(URI.create("http://localhost:4000"), json, ImmutableMap + . of(), ImmutableMap.> of("foo", ImmutableList + .of("recipe[apache2]")), installChefGems); + fn.apply("foo"); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testMustHaveRunScripts() { + TagToBootScript fn = new TagToBootScript(URI.create("http://localhost:4000"), json, ImmutableMap + . of("foo", createMock(Client.class)), ImmutableMap.> of(), installChefGems); + fn.apply("foo"); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testMustHaveRunScriptsValue() { + TagToBootScript fn = new TagToBootScript(URI.create("http://localhost:4000"), json, ImmutableMap + . of("foo", createMock(Client.class)), ImmutableMap.> of("foo", + ImmutableList. of()), installChefGems); + fn.apply("foo"); + } + + public void testOneRecipe() throws IOException { + Client client = createMock(Client.class); + PrivateKey privateKey = createMock(PrivateKey.class); + + TagToBootScript fn = new TagToBootScript(URI.create("http://localhost:4000"), json, ImmutableMap + . of("foo", client), ImmutableMap.> of("foo", ImmutableList + . of("recipe[apache2]")), installChefGems); + + expect(client.getClientname()).andReturn("fooclient").atLeastOnce(); + expect(client.getPrivateKey()).andReturn(privateKey).atLeastOnce(); + expect(privateKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes()); + + replay(client); + replay(privateKey); + + assertEquals(fn.apply("foo").getRawContent(), CharStreams.toString(Resources.newReaderSupplier(Resources + .getResource("one-recipe.sh"), Charsets.UTF_8))); + + verify(client); + verify(privateKey); + } +} diff --git a/chef/core/src/test/resources/one-recipe.sh b/chef/core/src/test/resources/one-recipe.sh new file mode 100755 index 0000000000..5209003828 --- /dev/null +++ b/chef/core/src/test/resources/one-recipe.sh @@ -0,0 +1,70 @@ +if [ ! -f /usr/bin/chef-client ]; then + apt-get update + apt-get install -y ruby ruby1.8-dev build-essential wget libruby-extras libruby1.8-extras + mkdir -p /tmp/bootchef + ( + cd /tmp/bootchef + wget http://rubyforge.org/frs/download.php/69365/rubygems-1.3.6.tgz + tar xvf rubygems-1.3.6.tgz + cd rubygems-1.3.6 + ruby setup.rb + cp /usr/bin/gem1.8 /usr/bin/gem + ) + rm -rf /tmp/bootchef + gem install chef ohai --no-rdoc --no-ri --verbose +fi +mkdir -p /etc/chef +cat > /etc/chef/client.rb <<'END_OF_FILE' +require 'rubygems' +require 'ohai' +o = Ohai::System.new +o.all_plugins +node_name "foo-" + o[:ipaddress] +log_level :info +log_location STDOUT +validation_client_name "fooclient" +chef_server_url "http://localhost:4000" +END_OF_FILE +cat > /etc/chef/validation.pem <<'END_OF_FILE' +-----BEGIN PRIVATE KEY----- +LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVB +eWIyWkpKcUdtMEtLUis4bmZRSk5zU2QrRjl0WE5NVjdDZk9jVzZqc3FzOEVaZ2lW +ClIwOWhEMUlZT2o0WXFNMHFKT05sZ3lnNHhSV2V3ZFNHN1FUUGoxbEpwVkFpZGE5 +c1h5MitrenlhZ1pBMUFtME8KWmNicWI1aG9lSURnY1grZURhNzlzMHUwRG9tamNm +TzlFS2h2SExCeit6TSszUXFQUmtQVjhuWVRiZnMrSGpWegp6T1U2RDFCMFhSMytJ +UFpabDJBbldzMmQwcWhuU3RIY0RVdm5SVlEwUDQ4Mll3TjlWZ2NlT1p0cFB6MERD +S0VKCjVUeDVTVHViOGswL3p0L1ZBTUhRYWZMU3VRTUxkMnM0Wkx1T1pwdE4vL3VB +c1RteGlyZXFkMzd6KzhaVGRCYkoKOExFcEoraUNYdVNmbTVhVWg3aXc2b3h2VG9Z +MkFMNTMraksyVVFJREFRQUJBb0lCQVFEQTg4QjNpL3hXbjB2WApCVnhGYW1DWW9l +Y3VOakd3WFhrU3laZXc2MTZBK0VPQ3U0N2JoNGFUdXJkRmJZTDBZRmFBdGFXdnps +YU4yZUhnCkRiK0hEdVRlZkUyOStXa2NHazZTc2hQbWl6NVQwWE9DQUlDV3c2d1NW +RGtIbUd3UzRqWnZiQUZtN1c4bndHazkKWWh4Z3hGaVJuZ3N3SlpGb3BPTG9GNVdY +czJ0ZDhndUlZTnNsTXBvN3R1NTBpRm5CSHdLTzJac1BBazh0OW5uUwp4bERhdkty +dXltRW1xSENyMytkdGlvNWVhZW5KY3AzZmpvWEJRT0tVazNpcElJMjlYUkI4TnFl +Q1ZWLzdLeHdxCmNrcU9CRWJSd0JjbGNreUliRCtSaUFnS3ZPZWxPUmpFaUU5UjQy +dnVxdnhSQTZrOWtkOW83dXRsWDBBVXRwRW4KM2daYzZMZXBBb0dCQVA5YWVsNVk3 +NStzSzJKSlVOT09oTzhhZTQ1Y2RzaWxwMnlJMFgrVUJhU3VRczIrZHlQcAprcEVI +QXhkNHBtbVN2bi84YzlUbEVaaHIrcVliQUJYVlBsRG5jeHBJdXcyQWpiazdzL1M0 +WGFTS3NScXBYTDU3CnpqL1FPcUxrUms4K09WVjlxNmxNZVFOcUx0RWoxdTZKUHZp +WDcwUm8rRlF0UnR0Tk9ZYmZkUC9mQW9HQkFNcEEKWGpSNXdvVjVzVWIrUkVnOXZF +dVlvOFJTeU9hcnhxS0ZDSVhWVU5zTE94KzIyK0FLNCtDUXBidWVXTjdqb3RybApZ +RDZ1VDZzdldpM0FBQzdraVkwVUkvZmpWUFJDVWk4dFZvUVVFMFRhVTVWTElUYVlP +QitXL2JCYURFNE05NTYwCjFOdURXTzkwYmFBNWRmVTQ0aXV6dmEwMnJHSlhLOStu +UzNvOG5rL1BBb0dCQUxPTDZkam5EZTRtd0FhRzZKY28KY2Q0eHI4amt5UHpDUlp1 +eUJDU0Jid3BoSVVYTGM3aERwclBreTA2NG5jSkQxVURtd0lka1hkL2ZwTWtnMlFt +QQovQ1VrNkxFRmpNaXNxSG9qT2FDTDlnUVpKUGhMTjVRVU4yeDFQSldHanMxdlFo +OFRreDBpVVVDT2E4YlFQWE5SCiszNE9Uc1c2VFVuYTRDU1pBeWNMZmhmZkFvR0JB +SWdnVnNlZkJDdnVRa0YwTmVVaG1EQ1JaZmhuZDh5NTVSSFIKMUhDdnFLSWxwdity +aGNYL3pteUJMdXRlb3BZeVJKUnNPaUUyRlcwMGk4K3JJUFJ1NFozUTVueWJ4N3cz +UHpWOQpvSE41UjViYUU5T3lJNEtwWld6dHBZWWl0WkY2N05jbkF2VlVMSEhPdlZK +UUduS1lmTEhKWW1ySkY3R0Exb2pNCkF1TWRGYmpGQW9HQVB4VWh4d0Z5OGdhcUJh +aEtVRVpuNEY4MUhGUDVpaEdoa1Q0UUw2QUZQTzJlK0poSUdqdVIKMjcrODVoY0Zx +UStISFZ0RnNtODFiL2ErUjdQNFV1Q1JnYzhlQ2p4UU1vSjFYbDRuN1ZialBiSE1u +SU4wUnl2ZApPNFpwV0RXWW5DTzAyMUpUT1VVT0o0Si95MDQxNkJ2a3cwejU5eTdz +Tlg3d0RCQkhIYksvWENjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= +-----END PRIVATE KEY----- +END_OF_FILE +cat > /etc/chef/first-boot.json <<'END_OF_FILE' +{"run_list":["recipe[apache2]"]} +END_OF_FILE +chef-client -j /etc/chef/first-boot.json diff --git a/core/src/main/java/org/jclouds/crypto/Pems.java b/core/src/main/java/org/jclouds/crypto/Pems.java index 94cb3b9c83..b12ae57a87 100644 --- a/core/src/main/java/org/jclouds/crypto/Pems.java +++ b/core/src/main/java/org/jclouds/crypto/Pems.java @@ -267,7 +267,7 @@ public class Pems { * @throws IOException * @throws CertificateEncodingException */ - public static String pem(X509Certificate cert) throws IOException, CertificateEncodingException { + public static String pem(X509Certificate cert) throws CertificateEncodingException { String marker = CERTIFICATE_X509_MARKER; return pem(cert.getEncoded(), marker); } @@ -281,7 +281,7 @@ public class Pems { * @throws IOException * @throws CertificateEncodingException */ - public static String pem(PublicKey key) throws IOException { + public static String pem(PublicKey key) { String marker = key instanceof RSAPublicKey ? PUBLIC_PKCS1_MARKER : PUBLIC_X509_MARKER; return pem(key.getEncoded(), marker); } @@ -295,7 +295,7 @@ public class Pems { * @throws IOException * @throws CertificateEncodingException */ - public static String pem(PrivateKey key) throws IOException { + public static String pem(PrivateKey key) { String marker = key instanceof RSAPrivateCrtKey ? PRIVATE_PKCS1_MARKER : PRIVATE_PKCS8_MARKER; return pem(key instanceof RSAPrivateCrtKey ? getEncoded(RSAPrivateCrtKey.class.cast(key)) : key.getEncoded(), marker); @@ -320,7 +320,7 @@ public class Pems { return bOut.toByteArray(); } - private static String pem(byte[] key, String marker) throws IOException { + private static String pem(byte[] key, String marker) { return new StringBuilder(marker + "\n").append( Joiner.on('\n').join(Splitter.fixedLength(64).split(CryptoStreams.base64(key)))).append( "\n" + marker.replace("BEGIN", "END") + "\n").toString().trim(); From df6d35082001ed7b9036c5686013290faa789252 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Fri, 3 Sep 2010 11:40:14 -0700 Subject: [PATCH 21/63] Issue 191: updated to fix an attribute bug and added RunListBuilder --- .../compute/ChefComputeServiceLiveTest.java | 38 +++++-- .../src/main/clojure/org/jclouds/chef.clj | 32 +++++- .../java/org/jclouds/chef/ChefService.java | 11 +- .../org/jclouds/chef/domain/Attribute.java | 8 +- .../jclouds/chef/domain/CookbookVersion.java | 18 +-- .../chef/internal/BaseChefService.java | 29 ++++- .../predicates/CookbookVersionPredicates.java | 97 ++++++++++++++++ .../chef/strategy/ListCookbookVersions.java | 41 +++++++ .../internal/ListCookbookVersionsImpl.java | 104 ++++++++++++++++++ .../org/jclouds/chef/util/RunListBuilder.java | 88 +++++++++++++++ .../org/jclouds/chef/ChefClientLiveTest.java | 10 +- .../ParseCookbookVersionFromJsonTest.java | 2 +- .../jclouds/chef/util/RunListBuilderTest.java | 74 +++++++++++++ 13 files changed, 522 insertions(+), 30 deletions(-) create mode 100644 chef/core/src/main/java/org/jclouds/chef/predicates/CookbookVersionPredicates.java create mode 100644 chef/core/src/main/java/org/jclouds/chef/strategy/ListCookbookVersions.java create mode 100644 chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsImpl.java create mode 100644 chef/core/src/main/java/org/jclouds/chef/util/RunListBuilder.java create mode 100644 chef/core/src/test/java/org/jclouds/chef/util/RunListBuilderTest.java diff --git a/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java index 0e8103a1ef..c94a3a3629 100644 --- a/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java +++ b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java @@ -20,6 +20,12 @@ package org.jclouds.chef.compute; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Iterables.getLast; +import static org.jclouds.chef.predicates.CookbookVersionPredicates.containsRecipe; +import static org.jclouds.chef.predicates.CookbookVersionPredicates.containsRecipes; +import static org.jclouds.compute.options.TemplateOptions.Builder.runScript; import static org.testng.Assert.assertEquals; import java.io.File; @@ -27,16 +33,17 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URI; -import java.util.Collections; +import java.util.List; import java.util.Properties; import org.jclouds.chef.ChefContext; import org.jclouds.chef.ChefContextFactory; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.util.RunListBuilder; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.RunNodesException; import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.predicates.NodePredicates; import org.jclouds.io.Payload; import org.jclouds.logging.log4j.config.Log4JLoggingModule; @@ -48,7 +55,6 @@ import org.testng.annotations.Test; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.common.io.Files; import com.google.inject.Module; @@ -101,24 +107,38 @@ public class ChefComputeServiceLiveTest { @Test public void testCanUpdateRunList() throws IOException { - chefContext.getChefService().updateRunListForTag(Collections.singleton("recipe[apache2]"), tag); - assertEquals(chefContext.getChefService().getRunListForTag(tag), Collections.singleton("recipe[apache2]")); + String recipe = "apache2"; + + Iterable cookbookVersions = chefContext.getChefService().listCookbookVersions(); + + if (any(cookbookVersions, containsRecipe(recipe))) { + List runList = new RunListBuilder().addRecipe(recipe).build(); + chefContext.getChefService().updateRunListForTag(runList, tag); + assertEquals(chefContext.getChefService().getRunListForTag(tag), runList); + } else { + assert false : String.format("recipe %s not in %s", recipe, cookbookVersions); + } + + // TODO move this to a unit test + assert any(cookbookVersions, containsRecipe("apache2::mod_proxy")); + assert any(cookbookVersions, containsRecipes("apache2", "apache2::mod_proxy", "apache2::mod_proxy_http")); + assert !any(cookbookVersions, containsRecipe("apache2::bar")); + assert !any(cookbookVersions, containsRecipe("foo::bar")); } @Test(dependsOnMethods = "testCanUpdateRunList") public void testRunNodesWithBootstrap() throws IOException { Payload bootstrap = chefContext.getChefService().createClientAndBootstrapScriptForTag(tag); - TemplateOptions options = computeContext.getComputeService().templateOptions().runScript(bootstrap); try { - nodes = computeContext.getComputeService().runNodesWithTag(tag, 1, options); + nodes = computeContext.getComputeService().runNodesWithTag(tag, 1, runScript(bootstrap)); } catch (RunNodesException e) { - nodes = Iterables.concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet()); + nodes = concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet()); } for (NodeMetadata node : nodes) { - URI uri = URI.create("http://" + Iterables.getLast(node.getPublicAddresses())); + URI uri = URI.create("http://" + getLast(node.getPublicAddresses())); InputStream content = computeContext.utils().http().get(uri); String string = Utils.toStringAndClose(content); assert string.indexOf("It works!") >= 0 : string; diff --git a/chef/core/src/main/clojure/org/jclouds/chef.clj b/chef/core/src/main/clojure/org/jclouds/chef.clj index fdeb12f590..6503e6d59c 100644 --- a/chef/core/src/main/clojure/org/jclouds/chef.clj +++ b/chef/core/src/main/clojure/org/jclouds/chef.clj @@ -129,7 +129,37 @@ unit testing" "Retrieve the existing nodes in your chef server including all details." ([] (nodes *chef*)) ([#^ChefService chef] - (seq (.listNodesDetails chef)))) + (seq (.listNodes chef)))) + +(defn clients + "Retrieve the names of the existing clients in your chef server." + ([] (clients *chef*)) + ([#^ChefService chef] + (seq (.listClients (as-chef-api chef))))) + +(defn clients-with-details + "Retrieve the existing clients in your chef server including all details." + ([] (clients *chef*)) + ([#^ChefService chef] + (seq (.listClients chef)))) + +(defn cookbooks + "Retrieve the names of the existing cookbooks in your chef server." + ([] (cookbooks *chef*)) + ([#^ChefService chef] + (seq (.listCookbooks (as-chef-api chef))))) + +(defn cookbook-versions + "Retrieve the versions of an existing cookbook in your chef server." + ([name] (cookbook-versions *chef*)) + ([#^ChefService name chef] + (seq (.getVersionsOfCookbook (as-chef-api chef) name)))) + +(defn cookbook-versions-with-details + "Retrieve the existing cookbook versions in your chef server including all details." + ([] (cookbook-versions *chef*)) + ([#^ChefService chef] + (seq (.listCookbookVersions chef)))) (defn update-run-list "Updates the run-list associated with a tag" diff --git a/chef/core/src/main/java/org/jclouds/chef/ChefService.java b/chef/core/src/main/java/org/jclouds/chef/ChefService.java index 09dcb2ca6b..12c968daec 100644 --- a/chef/core/src/main/java/org/jclouds/chef/ChefService.java +++ b/chef/core/src/main/java/org/jclouds/chef/ChefService.java @@ -24,6 +24,7 @@ import java.io.InputStream; import java.util.List; import org.jclouds.chef.domain.Client; +import org.jclouds.chef.domain.CookbookVersion; import org.jclouds.chef.domain.Node; import org.jclouds.chef.internal.BaseChefService; import org.jclouds.io.Payload; @@ -97,9 +98,9 @@ public interface ChefService { void deleteAllNodesInList(Iterable names); - Iterable listNodesDetails(); + Iterable listNodes(); - Iterable listNodesDetailsMatching(Predicate nodeNameSelector); + Iterable listNodesMatching(Predicate nodeNameSelector); Iterable listNodesNamed(Iterable names); @@ -111,5 +112,11 @@ public interface ChefService { Iterable listClientsNamed(Iterable names); + Iterable listCookbookVersions(); + + Iterable listCookbookVersionsMatching(Predicate cookbookNameSelector); + + Iterable listCookbookVersionsNamed(Iterable cookbookNames); + void updateAutomaticAttributesOnNode(String nodeName); } diff --git a/chef/core/src/main/java/org/jclouds/chef/domain/Attribute.java b/chef/core/src/main/java/org/jclouds/chef/domain/Attribute.java index dda2f64833..9a2fe6e584 100644 --- a/chef/core/src/main/java/org/jclouds/chef/domain/Attribute.java +++ b/chef/core/src/main/java/org/jclouds/chef/domain/Attribute.java @@ -22,6 +22,8 @@ package org.jclouds.chef.domain; import java.util.List; import java.util.Set; +import org.jclouds.domain.JsonBall; + import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.gson.annotations.SerializedName; @@ -37,14 +39,14 @@ public class Attribute { private boolean calculated; private List choice = Lists.newArrayList(); @SerializedName("default") - private String defaultValue; + private JsonBall defaultValue; private String type; private List recipes = Lists.newArrayList(); @SerializedName("display_name") private String displayName; private String description; - public Attribute(String required, boolean calculated, Set choice, String defaultValue, String type, + public Attribute(String required, boolean calculated, Set choice, JsonBall defaultValue, String type, List recipes, String displayName, String description) { this.required = required; this.calculated = calculated; @@ -71,7 +73,7 @@ public class Attribute { return choice; } - public String getDefaultValue() { + public JsonBall getDefaultValue() { return defaultValue; } diff --git a/chef/core/src/main/java/org/jclouds/chef/domain/CookbookVersion.java b/chef/core/src/main/java/org/jclouds/chef/domain/CookbookVersion.java index e9bb1a039e..470c7b29d6 100644 --- a/chef/core/src/main/java/org/jclouds/chef/domain/CookbookVersion.java +++ b/chef/core/src/main/java/org/jclouds/chef/domain/CookbookVersion.java @@ -34,7 +34,7 @@ public class CookbookVersion { private String name; private Set definitions = Sets.newLinkedHashSet(); - private Set attributes = Sets.newLinkedHashSet(); + private Set attributes = Sets.newLinkedHashSet(); private Set files = Sets.newLinkedHashSet(); private Metadata metadata = new Metadata(); private Set providers = Sets.newLinkedHashSet(); @@ -62,10 +62,10 @@ public class CookbookVersion { this.name = cookbookName + "-" + version; } - public CookbookVersion(String name, Set definitions, Set attributes, Set files, - Metadata metadata, Set providers, String cookbookName, Set resources, - Set templates, Set libraries, String version, Set recipes, - Set rootFiles) { + public CookbookVersion(String name, Set definitions, Set attributes, Set files, + Metadata metadata, Set providers, String cookbookName, Set resources, + Set templates, Set libraries, String version, Set recipes, + Set rootFiles) { this.name = name; Iterables.addAll(this.definitions, definitions); Iterables.addAll(this.attributes, attributes); @@ -94,7 +94,7 @@ public class CookbookVersion { return definitions; } - public Set getAttributes() { + public Set getAttributes() { return attributes; } @@ -238,9 +238,9 @@ public class CookbookVersion { @Override public String toString() { return "Cookbook [attributes=" + attributes + ", cookbookName=" + cookbookName + ", definitions=" + definitions - + ", files=" + files + ", libraries=" + libraries + ", metadata=" + metadata + ", name=" + name - + ", providers=" + providers + ", recipes=" + recipes + ", resources=" + resources + ", rootFiles=" - + rootFiles + ", templates=" + templates + ", version=" + version + "]"; + + ", files=" + files + ", libraries=" + libraries + ", metadata=" + metadata + ", name=" + name + + ", providers=" + providers + ", recipes=" + recipes + ", resources=" + resources + ", rootFiles=" + + rootFiles + ", templates=" + templates + ", version=" + version + "]"; } } diff --git a/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java b/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java index 2efe227a9f..c87ae96190 100644 --- a/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java +++ b/chef/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java @@ -36,6 +36,7 @@ import javax.inject.Singleton; import org.jclouds.chef.ChefContext; import org.jclouds.chef.ChefService; import org.jclouds.chef.domain.Client; +import org.jclouds.chef.domain.CookbookVersion; import org.jclouds.chef.domain.DatabagItem; import org.jclouds.chef.domain.Node; import org.jclouds.chef.functions.RunListForTag; @@ -46,6 +47,7 @@ import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes; import org.jclouds.chef.strategy.DeleteAllClientsInList; import org.jclouds.chef.strategy.DeleteAllNodesInList; import org.jclouds.chef.strategy.ListClients; +import org.jclouds.chef.strategy.ListCookbookVersions; import org.jclouds.chef.strategy.ListNodes; import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode; import org.jclouds.io.Payload; @@ -83,14 +85,16 @@ public class BaseChefService implements ChefService { private final TagToBootScript tagToBootScript; private final String databag; private final RunListForTag runListForTag; + private final ListCookbookVersions listCookbookVersions; @Inject protected BaseChefService(ChefContext chefContext, CleanupStaleNodesAndClients cleanupStaleNodesAndClients, CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes, DeleteAllNodesInList deleteAllNodesInList, ListNodes listNodes, DeleteAllClientsInList deleteAllClientsInList, ListClients listClients, - UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Provider privateKey, - @Named(CHEF_BOOTSTRAP_DATABAG) String databag, TagToBootScript tagToBootScript, RunListForTag runListForTag) { + ListCookbookVersions listCookbookVersions, UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, + Provider privateKey, @Named(CHEF_BOOTSTRAP_DATABAG) String databag, + TagToBootScript tagToBootScript, RunListForTag runListForTag) { this.chefContext = checkNotNull(chefContext, "chefContext"); this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients"); this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes, @@ -99,6 +103,7 @@ public class BaseChefService implements ChefService { this.listNodes = checkNotNull(listNodes, "listNodes"); this.deleteAllClientsInList = checkNotNull(deleteAllClientsInList, "deleteAllClientsInList"); this.listClients = checkNotNull(listClients, "listClients"); + this.listCookbookVersions = checkNotNull(listCookbookVersions, "listCookbookVersions"); this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode, "updateAutomaticAttributesOnNode"); this.privateKey = checkNotNull(privateKey, "privateKey"); @@ -123,12 +128,12 @@ public class BaseChefService implements ChefService { } @Override - public Iterable listNodesDetails() { + public Iterable listNodes() { return listNodes.execute(); } @Override - public Iterable listNodesDetailsMatching(Predicate nodeNameSelector) { + public Iterable listNodesMatching(Predicate nodeNameSelector) { return listNodes.execute(nodeNameSelector); } @@ -157,6 +162,22 @@ public class BaseChefService implements ChefService { return listClients.execute(names); } + @Override + public Iterable listCookbookVersions() { + return listCookbookVersions.execute(); + } + + @Override + public Iterable listCookbookVersionsMatching(Predicate cookbookNameSelector) { + return listCookbookVersions.execute(cookbookNameSelector); + } + + @Override + public Iterable listCookbookVersionsNamed(Iterable names) { + return listCookbookVersions.execute(names); + } + + @Override public void updateAutomaticAttributesOnNode(String nodeName) { updateAutomaticAttributesOnNode.execute(nodeName); diff --git a/chef/core/src/main/java/org/jclouds/chef/predicates/CookbookVersionPredicates.java b/chef/core/src/main/java/org/jclouds/chef/predicates/CookbookVersionPredicates.java new file mode 100644 index 0000000000..e0d298caf7 --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/predicates/CookbookVersionPredicates.java @@ -0,0 +1,97 @@ +/** + * + * 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.chef.predicates; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Iterables.get; + +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.domain.Resource; + +import com.google.common.base.Predicate; +import com.google.common.base.Splitter; +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.Multimap; + +/** + * Container for cookbook filters (predicates). + * + * This class has static methods that create customized predicates to use with + * {@link org.jclouds.chef.ChefService}. + * + * @author Adrian Cole + */ +public class CookbookVersionPredicates { + /** + * @see #containsRecipes + */ + public static Predicate containsRecipe(String recipe) { + return containsRecipes(checkNotNull(recipe, "recipe must be defined")); + } + + /** + * Note that the default recipe of a cookbook is its name. Otherwise, you prefix the recipe with + * the name of the cookbook. ex. {@code apache2} will be the default recipe where {@code + * apache2::mod_proxy} is a specific one in the cookbook. + * + * @param recipes + * names of the recipes. + * @return true if the cookbook version contains a recipe in the list. + */ + public static Predicate containsRecipes(String... recipes) { + checkNotNull(recipes, "recipes must be defined"); + final Multimap search = LinkedListMultimap.create(); + for (String recipe : recipes) { + if (recipe.indexOf("::") != -1) { + Iterable nameRecipe = Splitter.on("::").split(recipe); + search.put(get(nameRecipe, 0), get(nameRecipe, 1) + ".rb"); + } else { + search.put(recipe, "default.rb"); + } + } + return new Predicate() { + @Override + public boolean apply(final CookbookVersion cookbookVersion) { + return search.containsKey(cookbookVersion.getCookbookName()) + && any(search.get(cookbookVersion.getCookbookName()), new Predicate() { + + @Override + public boolean apply(final String recipeName) { + return any(cookbookVersion.getRecipes(), new Predicate() { + + @Override + public boolean apply(Resource resource) { + return resource.getName().equals(recipeName); + } + + }); + } + + }); + } + + @Override + public String toString() { + return "containsRecipes(" + search + ")"; + } + }; + } +} diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/ListCookbookVersions.java b/chef/core/src/main/java/org/jclouds/chef/strategy/ListCookbookVersions.java new file mode 100644 index 0000000000..4ef353cf16 --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/ListCookbookVersions.java @@ -0,0 +1,41 @@ +/** + * + * 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.chef.strategy; + +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.strategy.internal.ListCookbookVersionsImpl; + +import com.google.common.base.Predicate; +import com.google.inject.ImplementedBy; + +/** + * + * + * @author Adrian Cole + */ +@ImplementedBy(ListCookbookVersionsImpl.class) +public interface ListCookbookVersions { + + Iterable execute(); + + Iterable execute(Predicate cookbookNameSelector); + + Iterable execute(Iterable cookbookNames); +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsImpl.java b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsImpl.java new file mode 100644 index 0000000000..dff73418fd --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsImpl.java @@ -0,0 +1,104 @@ +/** + * + * 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.chef.strategy.internal; + +import static com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.transform; +import static org.jclouds.concurrent.FutureIterables.transformParallel; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.Constants; +import org.jclouds.chef.ChefAsyncClient; +import org.jclouds.chef.ChefClient; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.reference.ChefConstants; +import org.jclouds.chef.strategy.ListCookbookVersions; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.inject.Inject; + +/** + * + * + * @author Adrian Cole + */ +@Singleton +public class ListCookbookVersionsImpl implements ListCookbookVersions { + + protected final ChefClient chefClient; + protected final ChefAsyncClient chefAsyncClient; + protected final ExecutorService userExecutor; + @Resource + @Named(ChefConstants.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject(optional = true) + @Named(Constants.PROPERTY_REQUEST_TIMEOUT) + protected Long maxTime; + + @Inject + ListCookbookVersionsImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, + ChefClient getAllCookbookVersion, ChefAsyncClient ablobstore) { + this.userExecutor = userExecutor; + this.chefAsyncClient = ablobstore; + this.chefClient = getAllCookbookVersion; + } + + @Override + public Iterable execute() { + return execute(chefClient.listCookbooks()); + } + + @Override + public Iterable execute(Predicate cookbookNameSelector) { + return execute(filter(chefClient.listCookbooks(), cookbookNameSelector)); + } + + @Override + public Iterable execute(Iterable toGet) { + return concat(transform(toGet, new Function>() { + + @Override + public Iterable apply(final String cookbook) { + // TODO getting each version could also go parallel + return transformParallel(chefClient.getVersionsOfCookbook(cookbook), + new Function>() { + + @Override + public Future apply(String version) { + return chefAsyncClient.getCookbook(cookbook, version); + } + + }, userExecutor, maxTime, logger, "getting versions of cookbook " + cookbook); + } + + })); + } + +} \ No newline at end of file diff --git a/chef/core/src/main/java/org/jclouds/chef/util/RunListBuilder.java b/chef/core/src/main/java/org/jclouds/chef/util/RunListBuilder.java new file mode 100644 index 0000000000..96f1910119 --- /dev/null +++ b/chef/core/src/main/java/org/jclouds/chef/util/RunListBuilder.java @@ -0,0 +1,88 @@ +/** + * + * 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.chef.util; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.addAll; +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Lists.transform; + +import java.util.Arrays; +import java.util.List; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; + +/** + * builds a run list in the correct syntax for chef. + * + * @author Adrian Cole + */ +public class RunListBuilder { + private List list = newArrayList(); + + /** + * Add the following recipe to the run list + */ + public RunListBuilder addRecipe(String recipe) { + return addRecipes(checkNotNull(recipe, "recipe")); + } + + /** + * Add the following recipes to the run list + */ + public RunListBuilder addRecipes(String... recipes) { + addAll(list, transform(Arrays.asList(checkNotNull(recipes, "recipes")), new Function() { + + @Override + public String apply(String from) { + return "recipe[" + from + "]"; + } + + })); + return this; + } + + /** + * Add the following role to the run list + */ + public RunListBuilder addRole(String role) { + return addRoles(checkNotNull(role, "role")); + } + + /** + * Add the following roles to the run list + */ + public RunListBuilder addRoles(String... roles) { + addAll(list, transform(Arrays.asList(checkNotNull(roles, "roles")), new Function() { + + @Override + public String apply(String from) { + return "role[" + from + "]"; + } + + })); + return this; + } + + public List build() { + return ImmutableList.copyOf(list); + } +} \ No newline at end of file diff --git a/chef/core/src/test/java/org/jclouds/chef/ChefClientLiveTest.java b/chef/core/src/test/java/org/jclouds/chef/ChefClientLiveTest.java index 215e12f2be..416277b112 100644 --- a/chef/core/src/test/java/org/jclouds/chef/ChefClientLiveTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/ChefClientLiveTest.java @@ -20,12 +20,14 @@ package org.jclouds.chef; import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertNotNull; import java.io.File; import java.io.IOException; import java.util.Properties; import org.jclouds.chef.config.ChefParserModule; +import org.jclouds.chef.domain.CookbookVersion; import org.jclouds.json.Json; import org.jclouds.json.config.GsonModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule; @@ -76,7 +78,7 @@ public class ChefClientLiveTest extends BaseChefClientLiveTest { Properties props = new Properties(); props.setProperty("chef.endpoint", endpoint); return new ChefContextFactory().createContext(identity, key, ImmutableSet. of(new Log4JLoggingModule()), - props); + props); } @Override @@ -106,6 +108,12 @@ public class ChefClientLiveTest extends BaseChefClientLiveTest { clientConnection = createConnection(PREFIX, clientKey); } + @Test + public void testListCookbookVersionsWithChefService() throws Exception { + Iterable cookbooks = adminConnection.getChefService().listCookbookVersions(); + assertNotNull(cookbooks); + } + @Override protected void closeContexts() { if (clientConnection != null) diff --git a/chef/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java b/chef/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java index 2753a96b66..4a2be9e550 100644 --- a/chef/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java +++ b/chef/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java @@ -103,7 +103,7 @@ public class ParseCookbookVersionFromJsonTest { new CookbookVersion( "apache-chef-demo-0.0.0", ImmutableSet. of(), - ImmutableSet. of(), + ImmutableSet. of(), ImmutableSet. of(), new Metadata("Apache v2.0", "Your Name", ImmutableMap. of(), ImmutableMap .> of(), "youremail@example.com", ImmutableMap diff --git a/chef/core/src/test/java/org/jclouds/chef/util/RunListBuilderTest.java b/chef/core/src/test/java/org/jclouds/chef/util/RunListBuilderTest.java new file mode 100644 index 0000000000..864dd90cfa --- /dev/null +++ b/chef/core/src/test/java/org/jclouds/chef/util/RunListBuilderTest.java @@ -0,0 +1,74 @@ +/** + * + * 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.chef.util; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; + +/** + * Tests possible uses of RunListBuilder + * + * @author Adrian Cole + */ +public class RunListBuilderTest { + + @Test + public void testRecipeAndRole() { + RunListBuilder options = new RunListBuilder(); + options.addRecipe("recipe").addRole("role"); + assertEquals(options.build(),ImmutableList.of("recipe[recipe]","role[role]")); + } + + @Test + public void testRecipe() { + RunListBuilder options = new RunListBuilder(); + options.addRecipe("test"); + assertEquals(options.build(),ImmutableList.of("recipe[test]")); + } + @Test + public void testRecipes() { + RunListBuilder options = new RunListBuilder(); + options.addRecipes("test", "test2"); + assertEquals(options.build(),ImmutableList.of("recipe[test]","recipe[test2]")); + } + + @Test + public void testRole() { + RunListBuilder options = new RunListBuilder(); + options.addRole("test"); + assertEquals(options.build(),ImmutableList.of("role[test]")); + } + @Test + public void testRoles() { + RunListBuilder options = new RunListBuilder(); + options.addRoles("test", "test2"); + assertEquals(options.build(),ImmutableList.of("role[test]","role[test2]")); + } + + @Test + public void testNoneRecipe() { + RunListBuilder options = new RunListBuilder(); + assertEquals(options.build(), ImmutableList.of()); + } + +} From e5bd9bbfb803a3ad926dc7eeb922f3934a53a88a Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Fri, 3 Sep 2010 12:34:11 -0700 Subject: [PATCH 22/63] updated the test to use properties for credentials and such --- .../compute/ChefComputeServiceLiveTest.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java index c94a3a3629..bbeaf583e0 100644 --- a/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java +++ b/chef/compute/src/test/java/org/jclouds/chef/compute/ChefComputeServiceLiveTest.java @@ -28,7 +28,6 @@ import static org.jclouds.chef.predicates.CookbookVersionPredicates.containsReci import static org.jclouds.compute.options.TemplateOptions.Builder.runScript; import static org.testng.Assert.assertEquals; -import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -53,9 +52,7 @@ import org.testng.annotations.AfterGroups; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; -import com.google.common.base.Charsets; import com.google.common.collect.ImmutableSet; -import com.google.common.io.Files; import com.google.inject.Module; /** @@ -73,32 +70,34 @@ public class ChefComputeServiceLiveTest { private Iterable nodes; @BeforeGroups(groups = { "live" }) - public void setupCompute() throws FileNotFoundException, IOException { + public void setupAll() throws FileNotFoundException, IOException { tag = System.getProperty("jclouds.compute.tag") != null ? System.getProperty("jclouds.compute.tag") : "jcloudschef"; String computeProvider = checkNotNull(System.getProperty("jclouds.compute.provider"), "jclouds.compute.provider"); String computeEndpoint = System.getProperty("jclouds.compute.endpoint"); - Properties props = new Properties(); - if (computeEndpoint != null && !computeEndpoint.trim().equals("")) - props.setProperty(computeProvider + ".endpoint", computeEndpoint); String computeIdentity = checkNotNull(System.getProperty("jclouds.compute.identity"), "jclouds.compute.identity"); String computeCredential = checkNotNull(System.getProperty("jclouds.compute.credential"), "jclouds.compute.credential"); - computeContext = new ComputeServiceContextFactory().createContext(computeProvider, computeIdentity, - computeCredential, ImmutableSet.of(new Log4JLoggingModule(), getSshModule()), props); - } - - @BeforeGroups(groups = { "live" }) - public void setupChef() throws IOException { chefEndpoint = checkNotNull(System.getProperty("jclouds.chef.endpoint"), "jclouds.chef.endpoint"); String chefIdentity = checkNotNull(System.getProperty("jclouds.chef.identity"), "jclouds.chef.identity"); String chefCredentialFile = System.getProperty("jclouds.chef.credential.pem"); if (chefCredentialFile == null || chefCredentialFile.equals("")) chefCredentialFile = System.getProperty("user.home") + "/.chef/" + chefIdentity + ".pem"; + Properties props = new Properties(); + props.setProperty(computeProvider + ".identity", computeIdentity); + props.setProperty(computeProvider + ".credential", computeCredential); props.setProperty("chef.endpoint", chefEndpoint); - chefContext = new ChefContextFactory().createContext(chefIdentity, Files.toString(new File(chefCredentialFile), - Charsets.UTF_8), ImmutableSet. of(new Log4JLoggingModule()), props); + props.setProperty("chef.identity", chefIdentity); + props.setProperty("chef.credential.file", chefCredentialFile); + + if (computeEndpoint != null && !computeEndpoint.trim().equals("")) + props.setProperty(computeProvider + ".endpoint", computeEndpoint); + + computeContext = new ComputeServiceContextFactory().createContext(computeProvider, ImmutableSet.of( + new Log4JLoggingModule(), getSshModule()), props); + + chefContext = new ChefContextFactory().createContext(ImmutableSet. of(new Log4JLoggingModule()), props); } protected Module getSshModule() { From 36dec74379c4ca537a4136277fd52b4348399249 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sun, 5 Sep 2010 00:20:45 -0700 Subject: [PATCH 23/63] Issue 290: added guest customization support --- ...oudDirectorGuestCustomizationLiveTest.java | 44 +++ .../org/jclouds/vcloud/VCloudAsyncClient.java | 42 ++- .../java/org/jclouds/vcloud/VCloudClient.java | 122 ++++---- ...GuestCustomizationSectionToXmlPayload.java | 115 ++++++++ ...antiateVAppTemplateParamsToXmlPayload.java | 49 ++- .../VCloudComputeServiceContextModule.java | 6 + .../compute/functions/GetExtraFromVApp.java | 54 +--- .../compute/functions/GetExtraFromVm.java | 81 +++++ .../internal/VCloudTemplateBuilderImpl.java | 63 ++++ .../options/VCloudTemplateOptions.java | 243 +++++++++++++++ .../VCloudAddNodeWithTagStrategy.java | 44 +++ .../domain/GuestCustomizationSection.java | 129 ++++++-- .../InstantiateVAppTemplateOptions.java | 46 ++- .../xml/GuestCustomizationSectionHandler.java | 3 + .../jclouds/vcloud/VCloudAsyncClientTest.java | 278 +++++++++++------- .../VCloudGuestCustomizationLiveTest.java | 143 +++++++++ ...ateVAppTemplateParamsToXmlPayloadTest.java | 41 +++ .../compute/VCloudComputeServiceLiveTest.java | 1 - .../options/VCloudTemplateOptionsTest.java | 182 ++++++++++++ .../InstantiateVAppTemplateOptionsTest.java | 14 + .../resources/guestCustomizationSection.xml | 3 + .../instantiationparams-customization.xml | 1 + 22 files changed, 1438 insertions(+), 266 deletions(-) create mode 100644 vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/BlueLockVCloudDirectorGuestCustomizationLiveTest.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindGuestCustomizationSectionToXmlPayload.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVm.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/VCloudTemplateBuilderImpl.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java create mode 100644 vcloud/core/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java create mode 100644 vcloud/core/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java create mode 100644 vcloud/core/src/test/resources/guestCustomizationSection.xml create mode 100644 vcloud/core/src/test/resources/instantiationparams-customization.xml diff --git a/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/BlueLockVCloudDirectorGuestCustomizationLiveTest.java b/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/BlueLockVCloudDirectorGuestCustomizationLiveTest.java new file mode 100644 index 0000000000..71a97aed3f --- /dev/null +++ b/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/BlueLockVCloudDirectorGuestCustomizationLiveTest.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.vcloud.bluelock; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.vcloud.VCloudGuestCustomizationLiveTest; +import org.testng.annotations.Test; + +/** + * + * + * @author Adrian Cole + */ +@Test(groups = "live", enabled = true, sequential = true, testName = "vcloud.BlueLockVCloudDirectorGuestCustomizationLiveTest") +public class BlueLockVCloudDirectorGuestCustomizationLiveTest extends VCloudGuestCustomizationLiveTest { + + @Override + protected void setupCredentials() { + provider = "bluelock-vclouddirector"; + identity = checkNotNull(System.getProperty("bluelock-vclouddirector.identity"), + "bluelock-vclouddirector.identity"); + credential = checkNotNull(System.getProperty("bluelock-vclouddirector.credential"), + "bluelock-vclouddirector.credential"); + } + +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java index 1e0fc1adfd..d6feb250a3 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java @@ -20,6 +20,7 @@ package org.jclouds.vcloud; import static org.jclouds.vcloud.VCloudMediaType.DEPLOYVAPPPARAMS_XML; +import static org.jclouds.vcloud.VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML; import static org.jclouds.vcloud.VCloudMediaType.TASK_XML; import static org.jclouds.vcloud.VCloudMediaType.UNDEPLOYVAPPPARAMS_XML; import static org.jclouds.vcloud.VCloudMediaType.VAPPTEMPLATE_XML; @@ -34,11 +35,13 @@ import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.jclouds.predicates.validators.DnsNameValidator; +import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; @@ -52,8 +55,10 @@ import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.vcloud.binders.BindCloneVAppParamsToXmlPayload; import org.jclouds.vcloud.binders.BindDeployVAppParamsToXmlPayload; +import org.jclouds.vcloud.binders.BindGuestCustomizationSectionToXmlPayload; import org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload; import org.jclouds.vcloud.binders.BindUndeployVAppParamsToXmlPayload; +import org.jclouds.vcloud.domain.GuestCustomizationSection; import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; @@ -79,8 +84,7 @@ import com.google.common.util.concurrent.ListenableFuture; * Provides access to VCloud resources via their REST API. *

* - * @see + * @see * @author Adrian Cole */ @RequestFilters(SetVCloudTokenCookie.class) @@ -122,9 +126,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VAppTemplateHandler.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture findVAppTemplateInOrgCatalogNamed( - @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String orgName, - @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String catalogName, - @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String itemName); + @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String orgName, + @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String catalogName, + @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String itemName); /** * @see VCloudClient#instantiateVAppTemplateInVDC @@ -136,9 +140,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VAppHandler.class) @MapBinder(BindInstantiateVAppTemplateParamsToXmlPayload.class) ListenableFuture instantiateVAppTemplateInVDC(@EndpointParam URI vdc, - @MapPayloadParam("template") URI template, - @MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, - InstantiateVAppTemplateOptions... options); + @MapPayloadParam("template") URI template, + @MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, + InstantiateVAppTemplateOptions... options); /** * @see VCloudClient#cloneVAppInVDC @@ -150,8 +154,8 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(TaskHandler.class) @MapBinder(BindCloneVAppParamsToXmlPayload.class) ListenableFuture cloneVAppInVDC(@EndpointParam URI vdc, @MapPayloadParam("vApp") URI toClone, - @MapPayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, - CloneVAppOptions... options); + @MapPayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, + CloneVAppOptions... options); /** * @see VCloudClient#findVAppInOrgVDCNamed @@ -161,9 +165,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VAppHandler.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture findVAppInOrgVDCNamed( - @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName, - @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName, - @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String vAppName); + @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName, + @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName, + @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String vAppName); /** * @see VCloudClient#getVApp @@ -183,6 +187,18 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture getVm(@EndpointParam URI vm); + /** + * @see VCloudClient#updateGuestCustomizationOfVm + */ + @PUT + @Consumes(TASK_XML) + @Produces(GUESTCUSTOMIZATIONSECTION_XML) + @Path("/guestCustomizationSection") + @XMLResponseParser(TaskHandler.class) + ListenableFuture updateGuestCustomizationOfVm( + @EndpointParam URI vm, + @BinderParam(BindGuestCustomizationSectionToXmlPayload.class) GuestCustomizationSection guestCustomizationSection); + /** * @see VCloudClient#deployVAppOrVm */ diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java index ac16a52d7c..2ed33f48ff 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java @@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; import org.jclouds.concurrent.Timeout; +import org.jclouds.vcloud.domain.GuestCustomizationSection; import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; @@ -40,16 +41,14 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; * Provides access to VCloud resources via their REST API. *

* - * @see + * @see * @author Adrian Cole */ @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) public interface VCloudClient extends CommonVCloudClient { /** - * The response to a login request includes a list of the organizations to - * which the authenticated user has access. + * The response to a login request includes a list of the organizations to which the + * authenticated user has access. * * @return organizations indexed by name */ @@ -64,9 +63,19 @@ public interface VCloudClient extends CommonVCloudClient { OvfEnvelope getOvfEnvelopeForVAppTemplate(URI vAppTemplate); /** - * returns the vapp template corresponding to a catalog item in the catalog - * associated with the specified name. Note that the org and catalog - * parameters can be null to choose default. + * Modify the Guest Customization Section of a Virtual Machine + * + * @param vm + * uri to modify + * @param updated + * guestCustomizationSection + * @return task in progress + */ + Task updateGuestCustomizationOfVm(URI vm, GuestCustomizationSection guestCustomizationSection); + + /** + * returns the vapp template corresponding to a catalog item in the catalog associated with the + * specified name. Note that the org and catalog parameters can be null to choose default. * * @param orgName * organization name, or null for the default @@ -76,11 +85,10 @@ public interface VCloudClient extends CommonVCloudClient { * item you wish to lookup * * @throws NoSuchElementException - * if you specified an org, catalog, or catalog item name that - * isn't present + * if you specified an org, catalog, or catalog item name that isn't present */ VAppTemplate findVAppTemplateInOrgCatalogNamed(@Nullable String orgName, @Nullable String catalogName, - String itemName); + String itemName); VApp findVAppInOrgVDCNamed(@Nullable String orgName, @Nullable String catalogName, String vAppName); @@ -89,109 +97,97 @@ public interface VCloudClient extends CommonVCloudClient { Vm getVm(URI vm); /** - * To deploy a vApp, the client makes a request to its action/deploy URL. - * Deploying a vApp automatically deploys all of the virtual machines it - * contains. To deploy a virtual machine, the client makes a request to its - * action/deploy URL. + * To deploy a vApp, the client makes a request to its action/deploy URL. Deploying a vApp + * automatically deploys all of the virtual machines it contains. To deploy a virtual machine, + * the client makes a request to its action/deploy URL. *

- * Deploying a Vm implicitly deploys the parent vApp if that vApp is not - * already deployed. + * Deploying a Vm implicitly deploys the parent vApp if that vApp is not already deployed. */ Task deployVAppOrVm(URI vAppOrVmId); /** - * like {@link #deployVAppOrVm(URI)}, except deploy transistions to power on - * state + * like {@link #deployVAppOrVm(URI)}, except deploy transistions to power on state * */ Task deployAndPowerOnVAppOrVm(URI vAppOrVmId); /** - * Undeploying a vApp powers off or suspends any running virtual machines it - * contains, then frees the resources reserved for the vApp and sets the - * vApp’s deploy attribute to a value of false to indicate that it is not - * deployed. + * Undeploying a vApp powers off or suspends any running virtual machines it contains, then frees + * the resources reserved for the vApp and sets the vApp’s deploy attribute to a value of false + * to indicate that it is not deployed. *

- * Undeploying a virtual machine powers off or suspends the virtual machine, - * then frees the resources reserved for it and sets the its deploy attribute - * to a value of false to indicate that it is not deployed. This operation - * has no effect on the containing vApp. + * Undeploying a virtual machine powers off or suspends the virtual machine, then frees the + * resources reserved for it and sets the its deploy attribute to a value of false to indicate + * that it is not deployed. This operation has no effect on the containing vApp. *

NOTE

- * Using this method will simply power off the vms. In order to save their - * state, use {@link #undeployAndSaveStateOfVAppOrVm} + * Using this method will simply power off the vms. In order to save their state, use + * {@link #undeployAndSaveStateOfVAppOrVm} * */ Task undeployVAppOrVm(URI vAppOrVmId); /** - * like {@link #undeployVAppOrVm(URI)}, where the undeployed virtual machines - * are suspended and their suspend state saved + * like {@link #undeployVAppOrVm(URI)}, where the undeployed virtual machines are suspended and + * their suspend state saved * */ Task undeployAndSaveStateOfVAppOrVm(URI vAppOrVmId); /** - * A powerOn request to a vApp URL powers on all of the virtual machines in - * the vApp, as specified in the vApp’s StartupSection field. + * A powerOn request to a vApp URL powers on all of the virtual machines in the vApp, as + * specified in the vApp’s StartupSection field. *

- * A powerOn request to a virtual machine URL powers on the specified virtual - * machine and forces deployment of the parent vApp. + * A powerOn request to a virtual machine URL powers on the specified virtual machine and forces + * deployment of the parent vApp. *

- *

NOTE

A powerOn request to a vApp or virtual machine that is - * undeployed forces deployment. + *

NOTE

A powerOn request to a vApp or virtual machine that is undeployed forces + * deployment. */ Task powerOnVAppOrVm(URI vAppOrVmId); /** - * A powerOff request to a vApp URL powers off all of the virtual machines in - * the vApp, as specified in its StartupSection field. + * A powerOff request to a vApp URL powers off all of the virtual machines in the vApp, as + * specified in its StartupSection field. *

- * A powerOff request to a virtual machine URL powers off the specified - * virtual machine. + * A powerOff request to a virtual machine URL powers off the specified virtual machine. */ Task powerOffVAppOrVm(URI vAppOrVmId); /** - * A shutdown request to a vApp URL shuts down all of the virtual machines in - * the vApp, as specified in its StartupSection field. + * A shutdown request to a vApp URL shuts down all of the virtual machines in the vApp, as + * specified in its StartupSection field. *

- * A shutdown request to a virtual machine URL shuts down the specified - * virtual machine. + * A shutdown request to a virtual machine URL shuts down the specified virtual machine. *

- *

NOTENOTE - * A reset request to a virtual machine URL resets the specified virtual - * machine. + * A reset request to a virtual machine URL resets the specified virtual machine. */ Task resetVAppOrVm(URI vAppOrVmId); /** - * A reboot request to a vApp URL reboots all of the virtual machines in the - * vApp, as specified in its StartupSection field. + * A reboot request to a vApp URL reboots all of the virtual machines in the vApp, as specified + * in its StartupSection field. *

- * A reboot request to a virtual machine URL reboots the specified virtual - * machine. + * A reboot request to a virtual machine URL reboots the specified virtual machine. *

- *

NOTE

Because this request sends a signal to the guest OS, the - * vCloud API cannot track the progress or verify the result of the requested - * operation. Hence, void is returned + *

NOTE

Because this request sends a signal to the guest OS, the vCloud API cannot track + * the progress or verify the result of the requested operation. Hence, void is returned */ void rebootVAppOrVm(URI vAppOrVmId); /** - * A suspend request to a vApp URL suspends all of the virtual machines in - * the vApp, as specified in its StartupSection field. + * A suspend request to a vApp URL suspends all of the virtual machines in the vApp, as specified + * in its StartupSection field. *

- * A suspend request to a virtual machine URL suspends the specified virtual - * machine. + * A suspend request to a virtual machine URL suspends the specified virtual machine. */ Task suspendVAppOrVm(URI vAppOrVmId); diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindGuestCustomizationSectionToXmlPayload.java b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindGuestCustomizationSectionToXmlPayload.java new file mode 100644 index 0000000000..cf1e192fca --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindGuestCustomizationSectionToXmlPayload.java @@ -0,0 +1,115 @@ +/** + * + * 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.vcloud.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE; +import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_SCHEMA; + +import java.util.Properties; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.http.HttpRequest; +import org.jclouds.logging.Logger; +import org.jclouds.rest.binders.BindToStringPayload; +import org.jclouds.vcloud.domain.GuestCustomizationSection; + +import com.google.common.base.Throwables; +import com.google.inject.Inject; +import com.jamesmurty.utils.XMLBuilder; + +/** + * + * @author Adrian Cole + * + */ +@Singleton +public class BindGuestCustomizationSectionToXmlPayload extends BindToStringPayload { + @Resource + protected Logger logger = Logger.NULL; + + protected final String ns; + protected final String schema; + + @Inject + public BindGuestCustomizationSectionToXmlPayload(BindToStringPayload stringBinder, + @Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns, @Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema) { + this.ns = ns; + this.schema = schema; + } + + public void bindToRequest(HttpRequest request, Object payload) { + checkArgument(checkNotNull(payload, "GuestCustomizationSection") instanceof GuestCustomizationSection, + "this binder is only valid for GuestCustomizationSection!"); + GuestCustomizationSection guest = GuestCustomizationSection.class.cast(payload); + XMLBuilder guestCustomizationSection; + try { + guestCustomizationSection = XMLBuilder.create("GuestCustomizationSection").a("xmlns", ns).a("xmlns:ovf", + "http://schemas.dmtf.org/ovf/envelope/1").a("type", guest.getType()).a("href", + guest.getHref().toASCIIString()).a("ovf:required", "false"); + guestCustomizationSection.e("ovf:Info").t(guest.getInfo()); + + if (guest.isEnabled() != null) + guestCustomizationSection.e("Enabled").t(guest.isEnabled().toString()); + if (guest.shouldChangeSid() != null) + guestCustomizationSection.e("ChangeSid").t(guest.shouldChangeSid().toString()); + if (guest.getVirtualMachineId() != null) + guestCustomizationSection.e("VirtualMachineId").t(guest.getVirtualMachineId().toString()); + if (guest.isJoinDomainEnabled() != null) + guestCustomizationSection.e("JoinDomainEnabled").t(guest.isJoinDomainEnabled().toString()); + if (guest.shouldUseOrgSettings() != null) + guestCustomizationSection.e("UseOrgSettings").t(guest.shouldUseOrgSettings().toString()); + if (guest.getDomainName() != null) + guestCustomizationSection.e("DomainName").t(guest.getDomainName().toString()); + if (guest.getDomainUserName() != null) + guestCustomizationSection.e("DomainUserName").t(guest.getDomainUserName().toString()); + if (guest.getDomainUserPassword() != null) + guestCustomizationSection.e("DomainUserPassword").t(guest.getDomainUserPassword().toString()); + if (guest.isAdminPasswordEnabled() != null) + guestCustomizationSection.e("AdminPasswordEnabled").t(guest.isAdminPasswordEnabled().toString()); + if (guest.isAdminPasswordAuto() != null) + guestCustomizationSection.e("AdminPasswordAuto").t(guest.isAdminPasswordAuto().toString()); + // if (guest.getAdminPassword() != null) + // guestCustomizationSection.e("AdminPassword").t(guest.getAdminPassword().toString()); + if (guest.isResetPasswordRequired() != null) + guestCustomizationSection.e("ResetPasswordRequired").t(guest.isResetPasswordRequired().toString()); + if (guest.getCustomizationScript() != null) + guestCustomizationSection.e("CustomizationScript").t(guest.getCustomizationScript()); + if (guest.getComputerName() != null) + guestCustomizationSection.e("ComputerName").t(guest.getComputerName().toString()); + if (guest.getEdit() != null) + guestCustomizationSection.e("Link").a("rel", "edit").a("type", guest.getType()).a("href", + guest.getHref().toASCIIString()); + + Properties outputProperties = new Properties(); + outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes"); + super.bindToRequest(request, guestCustomizationSection.asString(outputProperties)); + request.getPayload().setContentType(guest.getType()); + } catch (Exception e) { + Throwables.propagate(e); + } + + } + +} diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayload.java b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayload.java index 922ef2997c..9b48b84ab0 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayload.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayload.java @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Properties; import java.util.Set; +import javax.annotation.Nullable; import javax.annotation.Resource; import javax.inject.Named; import javax.inject.Singleton; @@ -45,11 +46,13 @@ import org.jclouds.rest.binders.BindToStringPayload; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.domain.VAppTemplate; +import org.jclouds.vcloud.domain.Vm; import org.jclouds.vcloud.domain.network.FenceMode; import org.jclouds.vcloud.domain.network.NetworkConfig; import org.jclouds.vcloud.endpoints.Network; import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; @@ -73,18 +76,20 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder protected final URI defaultNetwork; protected final FenceMode defaultFenceMode; protected final DefaultNetworkNameInTemplate defaultNetworkNameInTemplate; + protected final VCloudClient client; @Inject public BindInstantiateVAppTemplateParamsToXmlPayload(DefaultNetworkNameInTemplate defaultNetworkNameInTemplate, BindToStringPayload stringBinder, @Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns, @Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema, @Network URI network, - @Named(PROPERTY_VCLOUD_DEFAULT_FENCEMODE) String fenceMode) { + @Named(PROPERTY_VCLOUD_DEFAULT_FENCEMODE) String fenceMode, VCloudClient client) { this.defaultNetworkNameInTemplate = defaultNetworkNameInTemplate; this.ns = ns; this.schema = schema; this.stringBinder = stringBinder; this.defaultNetwork = network; this.defaultFenceMode = FenceMode.fromValue(fenceMode); + this.client = client; } @SuppressWarnings("unchecked") @@ -98,11 +103,12 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder boolean deploy = true; boolean powerOn = true; + Boolean customizeOnInstantiate = null; Set networkConfig = null; - NetworknetworkConfigDecorator networknetworkConfigDecorator = new NetworknetworkConfigDecorator(template, - defaultNetwork, defaultFenceMode, defaultNetworkNameInTemplate); + NetworkConfigDecorator networknetworkConfigDecorator = new NetworkConfigDecorator(template, defaultNetwork, + defaultFenceMode, defaultNetworkNameInTemplate); InstantiateVAppTemplateOptions options = findOptionsInArgsOrNull(gRequest); @@ -110,16 +116,17 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder if (options.getNetworkConfig().size() > 0) networkConfig = Sets.newLinkedHashSet(Iterables.transform(options.getNetworkConfig(), networknetworkConfigDecorator)); - deploy = ifNullDefaultTo(options.shouldDeploy(), deploy); powerOn = ifNullDefaultTo(options.shouldPowerOn(), powerOn); + customizeOnInstantiate = options.shouldCustomizeOnInstantiate(); } if (networkConfig == null) networkConfig = ImmutableSet.of(networknetworkConfigDecorator.apply(null)); try { - stringBinder.bindToRequest(request, generateXml(name, deploy, powerOn, template, networkConfig)); + stringBinder.bindToRequest(request, generateXml(name, deploy, powerOn, template, networkConfig, + customizeOnInstantiate)); } catch (ParserConfigurationException e) { throw new RuntimeException(e); } catch (FactoryConfigurationError e) { @@ -130,13 +137,25 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder } - protected static final class NetworknetworkConfigDecorator implements Function { + @VisibleForTesting + Set ifCustomizationScriptIsSetGetVmsInTemplate(String customizationScript, final URI template) { + Set vms = Sets.newLinkedHashSet(); + if (customizationScript != null) { + VAppTemplate vAppTemplate = client.getVAppTemplate(template); + checkArgument(vAppTemplate != null, "vAppTemplate %s not found!", template); + vms = vAppTemplate.getChildren(); + checkArgument(vms.size() > 0, "no vms found in vAppTemplate %s", vAppTemplate); + } + return vms; + } + + protected static final class NetworkConfigDecorator implements Function { private final URI template; private final URI defaultNetwork; private final FenceMode defaultFenceMode; private final DefaultNetworkNameInTemplate defaultNetworkNameInTemplate; - protected NetworknetworkConfigDecorator(URI template, URI defaultNetwork, FenceMode defaultFenceMode, + protected NetworkConfigDecorator(URI template, URI defaultNetwork, FenceMode defaultFenceMode, DefaultNetworkNameInTemplate defaultNetworkNameInTemplate) { this.template = checkNotNull(template, "template"); this.defaultNetwork = checkNotNull(defaultNetwork, "defaultNetwork"); @@ -180,17 +199,15 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder networkName = Iterables.get(networks, 0).getName(); return networkName; } - } protected String generateXml(String name, boolean deploy, boolean powerOn, URI template, - Iterable networkConfig) throws ParserConfigurationException, - FactoryConfigurationError, TransformerException { + Iterable networkConfig, @Nullable Boolean customizeOnInstantiate) + throws ParserConfigurationException, FactoryConfigurationError, TransformerException { XMLBuilder rootBuilder = buildRoot(name).a("deploy", deploy + "").a("powerOn", powerOn + ""); - XMLBuilder instantiationParamsBuilder = rootBuilder.e("InstantiationParams"); addNetworkConfig(instantiationParamsBuilder, networkConfig); - + addCustomizationConfig(instantiationParamsBuilder, customizeOnInstantiate); rootBuilder.e("Source").a("href", template.toASCIIString()); rootBuilder.e("AllEULAsAccepted").t("true"); @@ -199,6 +216,14 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder return rootBuilder.asString(outputProperties); } + protected void addCustomizationConfig(XMLBuilder instantiationParamsBuilder, Boolean customizeOnInstantiate) { + if (customizeOnInstantiate != null) { +// XMLBuilder customizationSectionBuilder = instantiationParamsBuilder.e("CustomizationSection"); +// customizationSectionBuilder.e("ovf:Info").t("VApp template customization section"); +// customizationSectionBuilder.e("CustomizeOnInstantiate").t(customizeOnInstantiate.toString()); + } + } + protected void addNetworkConfig(XMLBuilder instantiationParamsBuilder, Iterable networkConfig) { XMLBuilder networkConfigBuilder = instantiationParamsBuilder.e("NetworkConfigSection"); diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java index 39411b8856..52a21b30d3 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java @@ -24,7 +24,9 @@ import java.util.Set; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.internal.ComputeServiceContextImpl; +import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.strategy.AddNodeWithTagStrategy; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; @@ -36,6 +38,8 @@ import org.jclouds.rest.internal.RestContextImpl; import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.compute.functions.ImagesInOrg; import org.jclouds.vcloud.compute.functions.SizesInOrg; +import org.jclouds.vcloud.compute.internal.VCloudTemplateBuilderImpl; +import org.jclouds.vcloud.compute.options.VCloudTemplateOptions; import org.jclouds.vcloud.compute.strategy.GetLoginCredentialsFromGuestConfiguration; import org.jclouds.vcloud.compute.strategy.VCloudAddNodeWithTagStrategy; import org.jclouds.vcloud.compute.strategy.VCloudDestroyNodeStrategy; @@ -62,6 +66,8 @@ public class VCloudComputeServiceContextModule extends CommonVCloudComputeServic @Override protected void configure() { super.configure(); + bind(TemplateOptions.class).to(VCloudTemplateOptions.class); + bind(TemplateBuilder.class).to(VCloudTemplateBuilderImpl.class); bind(RebootNodeStrategy.class).to(VCloudRebootNodeStrategy.class); bind(GetNodeMetadataStrategy.class).to(VCloudGetNodeMetadataStrategy.class); bind(new TypeLiteral() { diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVApp.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVApp.java index 324128d06f..47aeec4251 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVApp.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVApp.java @@ -19,70 +19,38 @@ package org.jclouds.vcloud.compute.functions; -import static com.google.common.collect.Iterables.filter; -import static com.google.common.collect.Iterables.find; -import static com.google.common.collect.Maps.newHashMap; -import static org.jclouds.vcloud.predicates.VCloudPredicates.resourceType; - import java.util.Map; import javax.annotation.Resource; +import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.logging.Logger; -import org.jclouds.vcloud.compute.internal.VCloudExpressComputeClientImpl; import org.jclouds.vcloud.domain.VApp; -import org.jclouds.vcloud.domain.Vm; -import org.jclouds.vcloud.domain.ovf.ResourceAllocation; -import org.jclouds.vcloud.domain.ovf.ResourceType; -import org.jclouds.vcloud.domain.ovf.VCloudHardDisk; -import org.jclouds.vcloud.domain.ovf.VCloudNetworkAdapter; import com.google.common.base.Function; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; /** - * Configures the {@link VCloudComputeServiceContext}; requires - * {@link VCloudExpressComputeClientImpl} bound. * * @author Adrian Cole */ @Singleton public class GetExtraFromVApp implements Function> { + private final GetExtraFromVm getExtraFromVm; + + @Inject + GetExtraFromVApp(GetExtraFromVm getExtraFromVm) { + this.getExtraFromVm = getExtraFromVm; + } @Resource protected Logger logger = Logger.NULL; public Map apply(VApp vApp) { - Map extra = newHashMap(); - try { - // TODO make this work with composite vApps - Vm vm = Iterables.get(vApp.getChildren(), 0); - extra.put("memory/mb", find(vm.getVirtualHardwareSection().getResourceAllocations(), resourceType(ResourceType.MEMORY)) - .getVirtualQuantity() - + ""); - extra.put("processor/count", find(vm.getVirtualHardwareSection().getResourceAllocations(), - resourceType(ResourceType.PROCESSOR)).getVirtualQuantity() - + ""); - for (ResourceAllocation disk : filter(vm.getVirtualHardwareSection().getResourceAllocations(), - resourceType(ResourceType.DISK_DRIVE))) { - if (disk instanceof VCloudHardDisk) { - VCloudHardDisk vDisk = VCloudHardDisk.class.cast(disk); - extra.put(String.format("disk_drive/%s/mb", disk.getAddressOnParent()), vDisk.getCapacity() + ""); - } else { - extra.put(String.format("disk_drive/%s/kb", disk.getAddressOnParent()), disk.getVirtualQuantity() + ""); - } - } - for (ResourceAllocation net : filter(vm.getVirtualHardwareSection().getResourceAllocations(), - resourceType(ResourceType.ETHERNET_ADAPTER))) { - if (net instanceof VCloudNetworkAdapter) { - VCloudNetworkAdapter vNet = VCloudNetworkAdapter.class.cast(net); - extra.put(String.format("network/%s/ip", net.getAddressOnParent()), vNet.getIpAddress()); - } - } - } catch (Exception e) { - logger.error(e, "error getting extra data for vApp: %s", vApp); - } - return extra; + // TODO make this work with composite vApps + return vApp.getChildren().size() == 0 ? ImmutableMap. of() : getExtraFromVm.apply(Iterables.get( + vApp.getChildren(), 0)); } } \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVm.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVm.java new file mode 100644 index 0000000000..7377141072 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/functions/GetExtraFromVm.java @@ -0,0 +1,81 @@ +/** + * + * 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.vcloud.compute.functions; + +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.find; +import static com.google.common.collect.Maps.newHashMap; +import static org.jclouds.vcloud.predicates.VCloudPredicates.resourceType; + +import java.util.Map; + +import javax.annotation.Resource; +import javax.inject.Singleton; + +import org.jclouds.logging.Logger; +import org.jclouds.vcloud.domain.Vm; +import org.jclouds.vcloud.domain.ovf.ResourceAllocation; +import org.jclouds.vcloud.domain.ovf.ResourceType; +import org.jclouds.vcloud.domain.ovf.VCloudHardDisk; +import org.jclouds.vcloud.domain.ovf.VCloudNetworkAdapter; + +import com.google.common.base.Function; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class GetExtraFromVm implements Function> { + + @Resource + protected Logger logger = Logger.NULL; + + public Map apply(Vm vm) { + Map extra = newHashMap(); + try { + extra.put("memory/mb", find(vm.getVirtualHardwareSection().getResourceAllocations(), + resourceType(ResourceType.MEMORY)).getVirtualQuantity() + + ""); + extra.put("processor/count", find(vm.getVirtualHardwareSection().getResourceAllocations(), + resourceType(ResourceType.PROCESSOR)).getVirtualQuantity() + + ""); + for (ResourceAllocation disk : filter(vm.getVirtualHardwareSection().getResourceAllocations(), + resourceType(ResourceType.DISK_DRIVE))) { + if (disk instanceof VCloudHardDisk) { + VCloudHardDisk vDisk = VCloudHardDisk.class.cast(disk); + extra.put(String.format("disk_drive/%s/mb", disk.getAddressOnParent()), vDisk.getCapacity() + ""); + } else { + extra.put(String.format("disk_drive/%s/kb", disk.getAddressOnParent()), disk.getVirtualQuantity() + ""); + } + } + for (ResourceAllocation net : filter(vm.getVirtualHardwareSection().getResourceAllocations(), + resourceType(ResourceType.ETHERNET_ADAPTER))) { + if (net instanceof VCloudNetworkAdapter) { + VCloudNetworkAdapter vNet = VCloudNetworkAdapter.class.cast(net); + extra.put(String.format("network/%s/ip", net.getAddressOnParent()), vNet.getIpAddress()); + } + } + } catch (Exception e) { + logger.error(e, "error getting extra data for vm: %s", vm); + } + return extra; + } +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/VCloudTemplateBuilderImpl.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/VCloudTemplateBuilderImpl.java new file mode 100644 index 0000000000..6c85f46089 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/VCloudTemplateBuilderImpl.java @@ -0,0 +1,63 @@ +/** + * + * 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.vcloud.compute.internal; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; + +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.domain.internal.TemplateBuilderImpl; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Location; +import org.jclouds.vcloud.compute.options.VCloudTemplateOptions; + +import com.google.common.base.Supplier; + +/** + * + * @author Adrian Cole + */ +public class VCloudTemplateBuilderImpl extends TemplateBuilderImpl { + + @Inject + protected VCloudTemplateBuilderImpl(Supplier> locations, + Supplier> images, Supplier> sizes, + Supplier defaultLocation, Provider optionsProvider, + @Named("DEFAULT") Provider defaultTemplateProvider) { + super(locations, images, sizes, defaultLocation, optionsProvider, defaultTemplateProvider); + } + + @Override + protected void copyTemplateOptions(TemplateOptions from, TemplateOptions to) { + super.copyTemplateOptions(from, to); + if (from instanceof VCloudTemplateOptions) { + VCloudTemplateOptions eFrom = VCloudTemplateOptions.class.cast(from); + VCloudTemplateOptions eTo = VCloudTemplateOptions.class.cast(to); + if (eFrom.getCustomizationScript() != null) + eTo.customizationScript(eFrom.getCustomizationScript()); + } + } + +} 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 new file mode 100644 index 0000000000..8a9758caba --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java @@ -0,0 +1,243 @@ +/** + * + * 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.vcloud.compute.options; + +import java.util.Arrays; + +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.io.Payload; +import org.jclouds.util.Utils; + +/** + * Contains options supported in the {@code ComputeService#runNode} operation on the "vcloud" + * provider.

+ * Usage

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

+ * + * import static org.jclouds.compute.options.VCloudTemplateOptions.Builder.*; + *

+ * ComputeService client = // get connection + * templateBuilder.options(inboundPorts(22, 80, 8080, 443)); + * Set set = client.runNodesWithTag(tag, 2, templateBuilder.build()); + * + * + * @author Adrian Cole + */ +public class VCloudTemplateOptions extends TemplateOptions { + + private String customizationScript = null; + + public static final VCloudTemplateOptions NONE = new VCloudTemplateOptions(); + + /** + * Specifies the customizationScript used to run instances with + */ + public VCloudTemplateOptions customizationScript(String customizationScript) { + Utils.checkNotEmpty(customizationScript, "customizationScript must be non-empty"); + this.customizationScript = customizationScript; + return this; + } + + public static class Builder { + + /** + * @see VCloudTemplateOptions#customizationScript + */ + public static VCloudTemplateOptions customizationScript(String customizationScript) { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + return VCloudTemplateOptions.class.cast(options.customizationScript(customizationScript)); + } + + // methods that only facilitate returning the correct object type + /** + * @see TemplateOptions#inboundPorts + */ + public static VCloudTemplateOptions inboundPorts(int... ports) { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + return VCloudTemplateOptions.class.cast(options.inboundPorts(ports)); + } + + /** + * @see TemplateOptions#port + */ + public static VCloudTemplateOptions blockOnPort(int port, int seconds) { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + return VCloudTemplateOptions.class.cast(options.blockOnPort(port, seconds)); + } + + /** + * @see TemplateOptions#runScript + */ + public static VCloudTemplateOptions runScript(Payload script) { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + return VCloudTemplateOptions.class.cast(options.runScript(script)); + } + + /** + * @see TemplateOptions#installPrivateKey + */ + public static VCloudTemplateOptions installPrivateKey(Payload rsaKey) { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + return VCloudTemplateOptions.class.cast(options.installPrivateKey(rsaKey)); + } + + /** + * @see TemplateOptions#authorizePublicKey + */ + public static VCloudTemplateOptions authorizePublicKey(Payload rsaKey) { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + return VCloudTemplateOptions.class.cast(options.authorizePublicKey(rsaKey)); + } + + /** + * @see TemplateOptions#withDetails + */ + public static VCloudTemplateOptions withDetails() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + return VCloudTemplateOptions.class.cast(options.withMetadata()); + } + + } + + /** + * @return customizationScript on the vms + */ + public String getCustomizationScript() { + return customizationScript; + } + + // methods that only facilitate returning the correct object type + + /** + * @see TemplateOptions#blockOnPort + */ + @Override + public VCloudTemplateOptions blockOnPort(int port, int seconds) { + return VCloudTemplateOptions.class.cast(super.blockOnPort(port, seconds)); + } + + /** + * + * 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 + */ + @Override + public VCloudTemplateOptions inboundPorts(int... ports) { + return VCloudTemplateOptions.class.cast(super.inboundPorts(ports)); + } + + /** + * @see TemplateOptions#authorizePublicKey(String) + */ + @Override + @Deprecated + public VCloudTemplateOptions authorizePublicKey(String publicKey) { + return VCloudTemplateOptions.class.cast(super.authorizePublicKey(publicKey)); + } + + /** + * @see TemplateOptions#authorizePublicKey(Payload) + */ + @Override + public VCloudTemplateOptions authorizePublicKey(Payload publicKey) { + return VCloudTemplateOptions.class.cast(super.authorizePublicKey(publicKey)); + } + + /** + * @see TemplateOptions#installPrivateKey(String) + */ + @Override + @Deprecated + public VCloudTemplateOptions installPrivateKey(String privateKey) { + return VCloudTemplateOptions.class.cast(super.installPrivateKey(privateKey)); + } + + /** + * @see TemplateOptions#installPrivateKey(Payload) + */ + @Override + public VCloudTemplateOptions installPrivateKey(Payload privateKey) { + return VCloudTemplateOptions.class.cast(super.installPrivateKey(privateKey)); + } + + /** + * @see TemplateOptions#runScript(Payload) + */ + @Override + public VCloudTemplateOptions runScript(Payload script) { + return VCloudTemplateOptions.class.cast(super.runScript(script)); + } + + /** + * @see TemplateOptions#runScript(byte[]) + */ + @Override + @Deprecated + public VCloudTemplateOptions runScript(byte[] script) { + return VCloudTemplateOptions.class.cast(super.runScript(script)); + } + + /** + * @see TemplateOptions#withMetadata + */ + @Override + public VCloudTemplateOptions withMetadata() { + return VCloudTemplateOptions.class.cast(super.withMetadata()); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((customizationScript == null) ? 0 : customizationScript.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + VCloudTemplateOptions other = (VCloudTemplateOptions) obj; + if (customizationScript == null) { + if (other.customizationScript != null) + return false; + } else if (!customizationScript.equals(other.customizationScript)) + return false; + return true; + } + + @Override + public String toString() { + return "[customizationScript=" + customizationScript + ", inboundPorts=" + Arrays.toString(inboundPorts) + + ", privateKey=" + (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript=" + + (script != null) + ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata + + "]"; + } + +} diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudAddNodeWithTagStrategy.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudAddNodeWithTagStrategy.java index ecfd8b3a97..5f3a465cf8 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudAddNodeWithTagStrategy.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudAddNodeWithTagStrategy.java @@ -35,11 +35,15 @@ import org.jclouds.compute.strategy.AddNodeWithTagStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.logging.Logger; import org.jclouds.vcloud.VCloudClient; +import org.jclouds.vcloud.compute.options.VCloudTemplateOptions; +import org.jclouds.vcloud.domain.GuestCustomizationSection; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; +import org.jclouds.vcloud.domain.Vm; import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; /** * @author Adrian Cole @@ -66,6 +70,17 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy { public NodeMetadata execute(String tag, String name, Template template) { InstantiateVAppTemplateOptions options = processorCount(Double.valueOf(template.getSize().getCores()).intValue()) .memory(template.getSize().getRam()).disk(template.getSize().getDisk() * 1024 * 1024l); + + String customizationScript = null; + if (template.getOptions() instanceof VCloudTemplateOptions) { + customizationScript = VCloudTemplateOptions.class.cast(template.getOptions()).getCustomizationScript(); + if (customizationScript != null) { + options.customizeOnInstantiate(false); + options.deploy(false); + options.powerOn(false); + } + } + if (!template.getOptions().shouldBlockUntilRunning()) options.block(false); @@ -78,6 +93,35 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy { logger.debug("<< instantiated VApp(%s)", vAppResponse.getName()); Task task = vAppResponse.getTasks().get(0); + + if (customizationScript == null) { + return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task); + } else { + if (!successTester.apply(task.getHref())) { + throw new RuntimeException(String + .format("failed to %s %s: %s", "instantiate", vAppResponse.getName(), task)); + } + Vm vm = Iterables.get(client.getVApp(vAppResponse.getHref()).getChildren(), 0); + GuestCustomizationSection guestConfiguration = vm.getGuestCustomizationSection(); + // guestConfiguration + // .setCustomizationScript(guestConfiguration.getCustomizationScript() != null ? + // guestConfiguration + // .getCustomizationScript() + // + "\n" + customizationScript : customizationScript); + guestConfiguration.setCustomizationScript(customizationScript); + task = client.updateGuestCustomizationOfVm(vm.getHref(), guestConfiguration); + if (!successTester.apply(task.getHref())) { + throw new RuntimeException(String.format("failed to %s %s: %s", "updateGuestCustomizationOfVm", vm + .getName(), task)); + } + task = client.deployAndPowerOnVAppOrVm(vAppResponse.getHref()); + return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task); + } + + } + + private NodeMetadata blockOnDeployAndPowerOnIfConfigured(InstantiateVAppTemplateOptions options, VApp vAppResponse, + Task task) { if (options.shouldBlock()) { if (!successTester.apply(task.getHref())) { throw new RuntimeException(String.format("failed to %s %s: %s", "deploy and power on", vAppResponse diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/GuestCustomizationSection.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/GuestCustomizationSection.java index 3b4dd4c205..581b7675a4 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/GuestCustomizationSection.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/GuestCustomizationSection.java @@ -21,30 +21,39 @@ package org.jclouds.vcloud.domain; import java.net.URI; +import org.jclouds.vcloud.VCloudMediaType; + /** - * The GuestCustomization of a Vm contains customization parameters for the guest - * operating system of the virtual machine. + * The GuestCustomization of a Vm contains customization parameters for the guest operating system + * of the virtual machine. */ public class GuestCustomizationSection { protected final String type; protected final URI href; - protected final String info; - protected final Boolean enabled; - protected final Boolean changeSid; - protected final String virtualMachineId; - protected final Boolean joinDomainEnabled; - protected final Boolean useOrgSettings; - protected final String domainName; - protected final String domainUserName; - protected final String domainUserPassword; - protected final Boolean adminPasswordEnabled; - protected final Boolean adminPasswordAuto; - protected final String adminPassword; - protected final Boolean resetPasswordRequired; - protected final String customizationScript; - protected final String computerName; + protected String info; + protected Boolean enabled; + protected Boolean changeSid; + protected String virtualMachineId; + protected Boolean joinDomainEnabled; + protected Boolean useOrgSettings; + protected String domainName; + protected String domainUserName; + protected String domainUserPassword; + protected Boolean adminPasswordEnabled; + protected Boolean adminPasswordAuto; + protected String adminPassword; + protected Boolean resetPasswordRequired; + protected String customizationScript; + protected String computerName; protected final ReferenceType edit; + public GuestCustomizationSection(URI href) { + this.href = href; + this.type = VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML; + this.info = "Specifies Guest OS Customization Settings"; + this.edit = null; + } + public GuestCustomizationSection(String type, URI href, String info, Boolean enabled, Boolean changeSid, String virtualMachineId, Boolean joinDomainEnabled, Boolean useOrgSettings, String domainName, String domainUserName, String domainUserPassword, Boolean adminPasswordEnabled, Boolean adminPasswordAuto, @@ -223,7 +232,7 @@ public class GuestCustomizationSection { @Override public int hashCode() { - final int prime = 31; + int prime = 31; int result = 1; result = prime * result + ((adminPassword == null) ? 0 : adminPassword.hashCode()); result = prime * result + ((adminPasswordAuto == null) ? 0 : adminPasswordAuto.hashCode()); @@ -347,4 +356,88 @@ public class GuestCustomizationSection { return false; return true; } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Boolean getChangeSid() { + return changeSid; + } + + public void setChangeSid(Boolean changeSid) { + this.changeSid = changeSid; + } + + public Boolean getJoinDomainEnabled() { + return joinDomainEnabled; + } + + public void setJoinDomainEnabled(Boolean joinDomainEnabled) { + this.joinDomainEnabled = joinDomainEnabled; + } + + public Boolean shouldUseOrgSettings() { + return useOrgSettings; + } + + public void setUseOrgSettings(Boolean useOrgSettings) { + this.useOrgSettings = useOrgSettings; + } + + public Boolean getAdminPasswordEnabled() { + return adminPasswordEnabled; + } + + public void setAdminPasswordEnabled(Boolean adminPasswordEnabled) { + this.adminPasswordEnabled = adminPasswordEnabled; + } + + public Boolean getAdminPasswordAuto() { + return adminPasswordAuto; + } + + public void setAdminPasswordAuto(Boolean adminPasswordAuto) { + this.adminPasswordAuto = adminPasswordAuto; + } + + public Boolean getResetPasswordRequired() { + return resetPasswordRequired; + } + + public void setResetPasswordRequired(Boolean resetPasswordRequired) { + this.resetPasswordRequired = resetPasswordRequired; + } + + public void setInfo(String info) { + this.info = info; + } + + public void setVirtualMachineId(String virtualMachineId) { + this.virtualMachineId = virtualMachineId; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + public void setDomainUserName(String domainUserName) { + this.domainUserName = domainUserName; + } + + public void setDomainUserPassword(String domainUserPassword) { + this.domainUserPassword = domainUserPassword; + } + + public void setAdminPassword(String adminPassword) { + this.adminPassword = adminPassword; + } + + public void setCustomizationScript(String customizationScript) { + this.customizationScript = customizationScript; + } + + public void setComputerName(String computerName) { + this.computerName = computerName; + } } \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptions.java b/vcloud/core/src/main/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptions.java index 7979674ddb..459fdc07e4 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptions.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptions.java @@ -26,8 +26,6 @@ import java.util.Set; import org.jclouds.vcloud.domain.network.NetworkConfig; - - import com.google.common.collect.Sets; /** @@ -38,6 +36,7 @@ import com.google.common.collect.Sets; public class InstantiateVAppTemplateOptions { private Set networkConfig = Sets.newLinkedHashSet(); + private Boolean customizeOnInstantiate; private String cpuCount; private String memorySizeMegabytes; private String diskSizeKilobytes; @@ -82,6 +81,15 @@ public class InstantiateVAppTemplateOptions { return this; } + /** + * If true, then customization is executed for all children that include a + * GuestCustomizationSection. + */ + public InstantiateVAppTemplateOptions customizeOnInstantiate(boolean customizeOnInstantiate) { + this.customizeOnInstantiate = customizeOnInstantiate; + return this; + } + public InstantiateVAppTemplateOptions processorCount(int cpuCount) { checkArgument(cpuCount >= 1, "cpuCount must be positive"); this.cpuCount = cpuCount + ""; @@ -126,6 +134,10 @@ public class InstantiateVAppTemplateOptions { return cpuCount; } + public Boolean shouldCustomizeOnInstantiate() { + return customizeOnInstantiate; + } + public String getMemorySizeMegabytes() { return memorySizeMegabytes; } @@ -168,6 +180,14 @@ public class InstantiateVAppTemplateOptions { return options.processorCount(cpuCount); } + /** + * @see InstantiateVAppTemplateOptions#customizeOnInstantiate + */ + public static InstantiateVAppTemplateOptions customizeOnInstantiate(Boolean customizeOnInstantiate) { + InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions(); + return options.customizeOnInstantiate(customizeOnInstantiate); + } + /** * @see InstantiateVAppTemplateOptions#memory(int) */ @@ -197,7 +217,9 @@ public class InstantiateVAppTemplateOptions { @Override public String toString() { return "InstantiateVAppTemplateOptions [cpuCount=" + cpuCount + ", memorySizeMegabytes=" + memorySizeMegabytes - + ", diskSizeKilobytes=" + diskSizeKilobytes + ", networkConfig=" + networkConfig + "]"; + + ", diskSizeKilobytes=" + diskSizeKilobytes + ", networkConfig=" + networkConfig + + ", customizeOnInstantiate=" + customizeOnInstantiate + ", deploy=" + (deploy) + ", powerOn=" + + (powerOn) + "]"; } @Override @@ -206,10 +228,11 @@ public class InstantiateVAppTemplateOptions { int result = 1; result = prime * result + (block ? 1231 : 1237); result = prime * result + ((cpuCount == null) ? 0 : cpuCount.hashCode()); + result = prime * result + ((customizeOnInstantiate == null) ? 0 : customizeOnInstantiate.hashCode()); result = prime * result + (deploy ? 1231 : 1237); result = prime * result + ((diskSizeKilobytes == null) ? 0 : diskSizeKilobytes.hashCode()); - result = prime * result + ((networkConfig == null) ? 0 : networkConfig.hashCode()); result = prime * result + ((memorySizeMegabytes == null) ? 0 : memorySizeMegabytes.hashCode()); + result = prime * result + ((networkConfig == null) ? 0 : networkConfig.hashCode()); result = prime * result + (powerOn ? 1231 : 1237); return result; } @@ -230,6 +253,11 @@ public class InstantiateVAppTemplateOptions { return false; } else if (!cpuCount.equals(other.cpuCount)) return false; + if (customizeOnInstantiate == null) { + if (other.customizeOnInstantiate != null) + return false; + } else if (!customizeOnInstantiate.equals(other.customizeOnInstantiate)) + return false; if (deploy != other.deploy) return false; if (diskSizeKilobytes == null) { @@ -237,16 +265,16 @@ public class InstantiateVAppTemplateOptions { return false; } else if (!diskSizeKilobytes.equals(other.diskSizeKilobytes)) return false; - if (networkConfig == null) { - if (other.networkConfig != null) - return false; - } else if (!networkConfig.equals(other.networkConfig)) - return false; if (memorySizeMegabytes == null) { if (other.memorySizeMegabytes != null) return false; } else if (!memorySizeMegabytes.equals(other.memorySizeMegabytes)) return false; + if (networkConfig == null) { + if (other.networkConfig != null) + return false; + } else if (!networkConfig.equals(other.networkConfig)) + return false; if (powerOn != other.powerOn) return false; return true; diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/xml/GuestCustomizationSectionHandler.java b/vcloud/core/src/main/java/org/jclouds/vcloud/xml/GuestCustomizationSectionHandler.java index 0c051ccbcd..0b341e1b20 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/xml/GuestCustomizationSectionHandler.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/xml/GuestCustomizationSectionHandler.java @@ -118,6 +118,9 @@ public class GuestCustomizationSectionHandler extends ParseSax.HandlerWithResult this.resetPasswordRequired = Boolean.parseBoolean(currentOrNull()); } else if (qName.endsWith("CustomizationScript")) { this.customizationScript = currentOrNull(); + if (this.customizationScript != null) + customizationScript = customizationScript.replace("<", "<").replace(">", ">").replace(""", "\"") + .replace("'", "'").replace(" ", "\r\n").replace(" ", "\n").replace("&", "&"); } else if (qName.endsWith("ComputerName")) { this.computerName = currentOrNull(); } else if (qName.endsWith("Name")) { diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java index 2bfa10a84f..d7b10ec51a 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java @@ -51,6 +51,7 @@ import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.util.Utils; import org.jclouds.vcloud.config.VCloudRestClientModule; +import org.jclouds.vcloud.domain.GuestCustomizationSection; import org.jclouds.vcloud.domain.Org; import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.Task; @@ -97,23 +98,45 @@ import domain.VCloudVersionsAsyncClient; */ @Test(groups = "unit", testName = "vcloud.VCloudAsyncClientTest") public class VCloudAsyncClientTest extends RestClientTest { - - public void testInstantiateVAppTemplateInVDCURIOptions() throws SecurityException, NoSuchMethodException, - IOException { - Method method = VCloudAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", URI.class, URI.class, - String.class, InstantiateVAppTemplateOptions[].class); - HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"), "my-vapp", - addNetworkConfig(new NetworkConfig("aloha", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), FenceMode.NAT_ROUTED))); + public void testUpdateGuestConfiguration() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("updateGuestCustomizationOfVm", URI.class, + GuestCustomizationSection.class); + GuestCustomizationSection guest = new GuestCustomizationSection(URI + .create("http://vcloud.example.com/api/v1.0/vApp/vm-12/guestCustomizationSection")); + guest.setCustomizationScript("cat > /tmp/foo.txt< { @Test(expectedExceptions = IllegalArgumentException.class) public void testInstantiateVAppTemplateInOrgOptionsIllegalName() throws SecurityException, NoSuchMethodException, - IOException { + IOException { Method method = VCloudAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", URI.class, URI.class, - String.class, InstantiateVAppTemplateOptions[].class); - processor - .createRequest(method, URI.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), "CentOS 01", processorCount(1).memory( - 512).disk(1024).addNetworkConfig( - new NetworkConfig(null, URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), null))); + String.class, InstantiateVAppTemplateOptions[].class); + processor.createRequest(method, URI.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), "CentOS 01", processorCount(1).memory(512) + .disk(1024).addNetworkConfig( + new NetworkConfig(null, URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), + null))); } public void testCloneVAppInVDC() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("cloneVAppInVDC", URI.class, URI.class, String.class, - CloneVAppOptions[].class); + CloneVAppOptions[].class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/4181"), "my-vapp"); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/4181"), "my-vapp"); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream("/cloneVApp-default.xml")), - "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); + "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -156,17 +179,17 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCloneVAppInVDCOptions() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("cloneVAppInVDC", URI.class, URI.class, String.class, - CloneVAppOptions[].class); + CloneVAppOptions[].class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/201"), "new-linux-server", new CloneVAppOptions() - .deploy().powerOn().withDescription("The description of the new vApp")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/201"), "new-linux-server", + new CloneVAppOptions().deploy().powerOn().withDescription("The description of the new vApp")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream("/cloneVApp.xml")), - "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); + "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -193,7 +216,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testOrg() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getOrg", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/org/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/org/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/org/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.org+xml\n"); @@ -224,7 +247,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCatalog() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getCatalog", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/catalog/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalog+xml\n"); @@ -255,7 +278,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testNetwork() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getNetwork", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/network/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/network/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/network/2 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.network+xml\n"); @@ -271,7 +294,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCatalogItemURI() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getCatalogItem", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalogItem+xml\n"); @@ -286,7 +309,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testFindCatalogItemInOrgCatalogNamed() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("findCatalogItemInOrgCatalogNamed", String.class, String.class, - String.class); + String.class); HttpRequest request = processor.createRequest(method, "org", "catalog", "item"); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1 HTTP/1.1"); @@ -302,7 +325,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testFindVAppTemplate() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("findVAppTemplateInOrgCatalogNamed", String.class, - String.class, String.class); + String.class, String.class); HttpRequest request = processor.createRequest(method, "org", "catalog", "template"); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2 HTTP/1.1"); @@ -319,7 +342,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testVAppTemplateURI() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVAppTemplate", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vAppTemplate+xml\n"); @@ -335,7 +358,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetOvfEnvelopeForVAppTemplate() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getOvfEnvelopeForVAppTemplate", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2/ovf HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: text/xml\n"); @@ -408,7 +431,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetVDC() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVDC", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vdc/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vdc+xml\n"); @@ -424,7 +447,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetTasksList() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getTasksList", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/tasksList/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.tasksList+xml\n"); @@ -455,12 +478,12 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testDeployVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("deployVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/deploy HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, "", - "application/vnd.vmware.vcloud.deployVAppParams+xml", false); + "application/vnd.vmware.vcloud.deployVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -472,12 +495,12 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testDeployAndPowerOnVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("deployAndPowerOnVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/deploy HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, "", - "application/vnd.vmware.vcloud.deployVAppParams+xml", false); + "application/vnd.vmware.vcloud.deployVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -489,7 +512,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetVApp() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVApp", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vApp/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n"); @@ -505,7 +528,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vm/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vm/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vm/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vm+xml\n"); @@ -521,10 +544,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testRebootVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("rebootVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reboot HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reboot HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); assertPayloadEquals(request, null, null, false); @@ -538,13 +561,13 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testUndeployVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("undeployVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, "", - "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); + "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -554,17 +577,17 @@ public class VCloudAsyncClientTest extends RestClientTest { } public void testUndeployAndSaveStateOfVAppOrVmSaveState() throws SecurityException, NoSuchMethodException, - IOException { + IOException { Method method = VCloudAsyncClient.class.getMethod("undeployAndSaveStateOfVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, - "", - "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); + "", + "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -576,7 +599,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testDeleteVApp() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("deleteVApp", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "DELETE https://vcenterprise.bluelock.com/api/v1.0/vApp/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); @@ -592,10 +615,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testPowerOnVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("powerOnVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOn HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOn HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -609,10 +632,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testPowerOffVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("powerOffVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOff HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOff HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -626,10 +649,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testResetVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("resetVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reset HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reset HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -643,10 +666,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testSuspendVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("suspendVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/suspend HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/suspend HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -660,10 +683,10 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testShutdownVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("shutdownVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/shutdown HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/shutdown HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); assertPayloadEquals(request, null, null, false); @@ -677,7 +700,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetTask() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getTask", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/task/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); @@ -693,7 +716,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCancelTask() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("cancelTask", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); assertRequestLineEquals(request, "POST https://vcenterprise.bluelock.com/api/v1.0/task/1/action/cancel HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); @@ -735,7 +758,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public static class VCloudRestClientModuleExtension extends VCloudRestClientModule { @Override protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService, - @Named(PROPERTY_API_VERSION) String version) { + @Named(PROPERTY_API_VERSION) String version) { return URI.create("https://vcenterprise.bluelock.com/api/v1.0/login"); } @@ -778,13 +801,13 @@ public class VCloudAsyncClientTest extends RestClientTest { @Override protected Supplier provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, - final VCloudLoginAsyncClient login) { + final VCloudLoginAsyncClient login) { return Suppliers. ofInstance(new VCloudSession() { @Override public Map getOrgs() { return ImmutableMap. of("org", new ReferenceTypeImpl("org", - VCloudMediaType.ORG_XML, URI.create("https://vcenterprise.bluelock.com/api/v1.0/org/1"))); + VCloudMediaType.ORG_XML, URI.create("https://vcenterprise.bluelock.com/api/v1.0/org/1"))); } @Override @@ -805,19 +828,44 @@ public class VCloudAsyncClientTest extends RestClientTest { } protected Supplier>> provideOrgVDCSupplierCache( - @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { + @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { - return Suppliers.>> ofInstance(ImmutableMap - .> of("org", + return Suppliers + .>> ofInstance(ImmutableMap + .> of( + "org", - ImmutableMap. of("vdc", new VDCImpl("vdc", null, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), null, null, "description", null, - null, null, null, null, ImmutableMap. of("vapp", new ReferenceTypeImpl( - "vapp", "application/vnd.vmware.vcloud.vApp+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/188849-1")), "network", - new ReferenceTypeImpl("network", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdcItem/2"))), null, 0, 0, 0, - false)))); + ImmutableMap + . of( + "vdc", + new VDCImpl( + "vdc", + null, + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), + null, + null, + "description", + null, + null, + null, + null, + null, + ImmutableMap + . of( + "vapp", + new ReferenceTypeImpl( + "vapp", + "application/vnd.vmware.vcloud.vApp+xml", + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/188849-1")), + "network", + new ReferenceTypeImpl( + "network", + "application/vnd.vmware.vcloud.vAppTemplate+xml", + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdcItem/2"))), + null, 0, 0, 0, false)))); } @@ -831,15 +879,18 @@ public class VCloudAsyncClientTest extends RestClientTest { @Override public Map get() { return ImmutableMap. of("org", new OrgImpl("org", null, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/org/1"), "org", "description", ImmutableMap - . of("catalog", new ReferenceTypeImpl("catalog", VCloudMediaType.CATALOG_XML, - URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"))), ImmutableMap - . of("vdc", new ReferenceTypeImpl("vdc", VCloudMediaType.VDC_XML, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"))), ImmutableMap - . of("network", new ReferenceTypeImpl("network", VCloudMediaType.NETWORK_XML, - URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1"))), new ReferenceTypeImpl( - "tasksList", VCloudMediaType.TASKSLIST_XML, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")), ImmutableList. of())); + .create("https://vcenterprise.bluelock.com/api/v1.0/org/1"), "org", "description", ImmutableMap + . of("catalog", new ReferenceTypeImpl("catalog", + VCloudMediaType.CATALOG_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"))), ImmutableMap + . of("vdc", new ReferenceTypeImpl("vdc", VCloudMediaType.VDC_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"))), ImmutableMap + . of("network", new ReferenceTypeImpl("network", + VCloudMediaType.NETWORK_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/network/1"))), + new ReferenceTypeImpl("tasksList", VCloudMediaType.TASKSLIST_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")), ImmutableList + . of())); } } @@ -855,13 +906,14 @@ public class VCloudAsyncClientTest extends RestClientTest { return ImmutableMap.> of("org", ImmutableMap. of("catalog", new CatalogImpl("catalog", "type", - URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"), null, "description", ImmutableMap - . of("item", new ReferenceTypeImpl("item", + URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"), null, "description", + ImmutableMap. of("item", new ReferenceTypeImpl("item", "application/vnd.vmware.vcloud.catalogItem+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1")), "template", - new ReferenceTypeImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"))), - ImmutableList. of(), true))); + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1")), + "template", new ReferenceTypeImpl("template", + "application/vnd.vmware.vcloud.vAppTemplate+xml", URI + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"))), + ImmutableList. of(), true))); } } @@ -873,14 +925,26 @@ public class VCloudAsyncClientTest extends RestClientTest { @Override public Map>> get() { - return ImmutableMap.>> of( - "org", ImmutableMap.> of( - "catalog", ImmutableMap. of("template", - new CatalogItemImpl("template", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"), "description", - new ReferenceTypeImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml", - URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")), - ImmutableMap. of())))); + return ImmutableMap + .>> of( + "org", + ImmutableMap + .> of( + "catalog", + ImmutableMap + . of( + "template", + new CatalogItemImpl( + "template", + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"), + "description", + new ReferenceTypeImpl( + "template", + "application/vnd.vmware.vcloud.vAppTemplate+xml", + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")), + ImmutableMap. of())))); } } diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java new file mode 100644 index 0000000000..6b28ba4130 --- /dev/null +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java @@ -0,0 +1,143 @@ +/** + * + * 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.vcloud; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.get; +import static org.testng.Assert.assertEquals; + +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.Constants; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.net.IPSocket; +import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.predicates.SocketOpen; +import org.jclouds.ssh.ExecResponse; +import org.jclouds.ssh.SshClient; +import org.jclouds.ssh.SshClient.Factory; +import org.jclouds.ssh.jsch.config.JschSshClientModule; +import org.jclouds.vcloud.compute.options.VCloudTemplateOptions; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; + +/** + * + * + * @author Adrian Cole + */ +@Test(groups = "live", enabled = true, sequential = true, testName = "vcloud.VCloudGuestCustomizationLiveTest") +public class VCloudGuestCustomizationLiveTest { + + protected String identity; + protected String provider; + protected String credential; + protected ComputeServiceContext context; + protected ComputeService client; + protected RetryablePredicate socketTester; + protected Factory sshFactory; + + protected void setupCredentials() { + provider = "vcloud"; + identity = checkNotNull(System.getProperty("vcloud.identity"), "vcloud.identity"); + credential = checkNotNull(System.getProperty("vcloud.credential"), "vcloud.credential"); + } + + @BeforeGroups(groups = { "live" }) + public void setupClient() { + setupCredentials(); + Properties props = new Properties(); + props.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); + props.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); + context = new ComputeServiceContextFactory().createContext(provider, identity, credential, ImmutableSet + . of(new Log4JLoggingModule()), props); + + client = context.getComputeService(); + + Injector injector = createSshClientInjector(); + sshFactory = injector.getInstance(SshClient.Factory.class); + SocketOpen socketOpen = injector.getInstance(SocketOpen.class); + socketTester = new RetryablePredicate(socketOpen, 60, 1, TimeUnit.SECONDS); + injector.injectMembers(socketOpen); // add logger + } + + protected Injector createSshClientInjector() { + return Guice.createInjector(getSshModule()); + } + + protected JschSshClientModule getSshModule() { + return new JschSshClientModule(); + } + + @Test + public void testExtendedOptionsWithCustomizationScript() throws Exception { + + String tag = "customize"; + + TemplateOptions options = client.templateOptions(); + + options.as(VCloudTemplateOptions.class).customizationScript("cat > /root/foo.txt< nodes = client.runNodesWithTag(tag, 1, options); + + NodeMetadata node = Iterables.get(nodes, 0); + nodeId = node.getId(); + IPSocket socket = new IPSocket(get(node.getPublicAddresses(), 0), 22); + socketTester.apply(socket); + + SshClient ssh = sshFactory.create(socket, node.getCredentials().identity, node.getCredentials().credential); + try { + ssh.connect(); + + System.out + .println(ssh + .exec("vmtoolsd --cmd=\"info-get guestinfo.ovfenv\" |grep vCloud_CustomizationInfo|sed 's/.*value=\"\\(.*\\)\".*/\\1/g'|base64 -d")); + + ExecResponse hello = ssh.exec("cat /root/foo.txt"); + assertEquals(hello.getOutput().trim(), "I love candy"); + + } finally { + if (ssh != null) + ssh.disconnect(); + } + + } finally { + if (nodeId != null) + client.destroyNode(nodeId); + } + } + +} \ No newline at end of file diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayloadTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayloadTest.java index e0e9243b36..e2096909eb 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayloadTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayloadTest.java @@ -25,6 +25,7 @@ import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.replay; import static org.easymock.classextension.EasyMock.verify; import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.addNetworkConfig; +import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.customizeOnInstantiate; import java.io.IOException; import java.net.URI; @@ -196,6 +197,46 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest { binder.bindToRequest(request, map); verify(request); + } + + public void testWithCustomization() throws IOException { + + URI templateUri = URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"); + VAppTemplate template = createMock(VAppTemplate.class); + VCloudNetworkSection net = createMock(VCloudNetworkSection.class); + InstantiateVAppTemplateOptions options = customizeOnInstantiate(true); + + String expected = Utils + .toStringAndClose(getClass().getResourceAsStream("/instantiationparams-customization.xml")); + + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); + expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); + expect(request.getArgs()).andReturn(new Object[] { options }).atLeastOnce(); + request.setPayload(expected); + + expect(template.getNetworkSection()).andReturn(net).atLeastOnce(); + expect(net.getNetworks()) + .andReturn( + ImmutableSet + . of(new org.jclouds.vcloud.domain.ovf.network.Network( + "vAppNet-vApp Internal", null))); + + replay(request); + replay(template); + replay(net); + + BindInstantiateVAppTemplateParamsToXmlPayload binder = createInjector(templateUri, template).getInstance( + BindInstantiateVAppTemplateParamsToXmlPayload.class); + + Map map = Maps.newHashMap(); + map.put("name", "my-vapp"); + map.put("template", "https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"); + + binder.bindToRequest(request, map); + + verify(request); + verify(template); + verify(net); } } diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/compute/VCloudComputeServiceLiveTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/compute/VCloudComputeServiceLiveTest.java index 77d34de59c..44f1d61721 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/compute/VCloudComputeServiceLiveTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/compute/VCloudComputeServiceLiveTest.java @@ -76,5 +76,4 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest { System.out.println(allData.getExtra()); } } - } \ No newline at end of file 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 new file mode 100644 index 0000000000..1883ae17d8 --- /dev/null +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java @@ -0,0 +1,182 @@ +/** + * + * 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.vcloud.compute.options; + +import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.authorizePublicKey; +import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.blockOnPort; +import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.customizationScript; +import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.inboundPorts; +import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.installPrivateKey; +import static org.testng.Assert.assertEquals; + +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; + +/** + * Tests possible uses of VCloudTemplateOptions and VCloudTemplateOptions.Builder.* + * + * @author Adrian Cole + */ +public class VCloudTemplateOptionsTest { + + public void testAs() { + TemplateOptions options = new VCloudTemplateOptions(); + assertEquals(options.as(VCloudTemplateOptions.class), options); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testcustomizationScriptBadFormat() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + options.customizationScript(""); + } + + @Test + public void testcustomizationScript() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + options.customizationScript("mykeypair"); + assertEquals(options.getCustomizationScript(), "mykeypair"); + } + + @Test + public void testNullcustomizationScript() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + assertEquals(options.getCustomizationScript(), null); + } + + @Test + public void testcustomizationScriptStatic() { + VCloudTemplateOptions options = customizationScript("mykeypair"); + assertEquals(options.getCustomizationScript(), "mykeypair"); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testcustomizationScriptNPE() { + customizationScript(null); + } + + @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-----"); + } + + @Test + public void testNullinstallPrivateKey() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + assertEquals(options.getPrivateKey(), null); + } + + @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-----"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testinstallPrivateKeyNPE() { + installPrivateKey(null); + } + + @Test + public void testauthorizePublicKey() throws IOException { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + options.authorizePublicKey(Payloads.newPayload("ssh-rsa")); + assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + } + + @Test + public void testNullauthorizePublicKey() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + assertEquals(options.getPublicKey(), null); + } + + @Test + public void testauthorizePublicKeyStatic() throws IOException { + VCloudTemplateOptions options = authorizePublicKey(Payloads.newPayload("ssh-rsa")); + assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testauthorizePublicKeyNPE() { + authorizePublicKey(null); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testblockOnPortBadFormat() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + options.blockOnPort(-1, -1); + } + + @Test + public void testblockOnPort() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + options.blockOnPort(22, 30); + assertEquals(options.getPort(), 22); + assertEquals(options.getSeconds(), 30); + + } + + @Test + public void testNullblockOnPort() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + assertEquals(options.getPort(), -1); + assertEquals(options.getSeconds(), -1); + } + + @Test + public void testblockOnPortStatic() { + VCloudTemplateOptions options = blockOnPort(22, 30); + assertEquals(options.getPort(), 22); + assertEquals(options.getSeconds(), 30); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testinboundPortsBadFormat() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + options.inboundPorts(-1, -1); + } + + @Test + public void testinboundPorts() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + options.inboundPorts(22, 30); + assertEquals(options.getInboundPorts()[0], 22); + assertEquals(options.getInboundPorts()[1], 30); + + } + + @Test + public void testDefaultOpen22() { + VCloudTemplateOptions options = new VCloudTemplateOptions(); + assertEquals(options.getInboundPorts()[0], 22); + } + + @Test + public void testinboundPortsStatic() { + VCloudTemplateOptions options = inboundPorts(22, 30); + assertEquals(options.getInboundPorts()[0], 22); + assertEquals(options.getInboundPorts()[1], 30); + } +} diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptionsTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptionsTest.java index c26ff7009c..d824c68615 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptionsTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptionsTest.java @@ -20,6 +20,7 @@ package org.jclouds.vcloud.options; import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.addNetworkConfig; +import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.customizeOnInstantiate; import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.disk; import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.memory; import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount; @@ -77,6 +78,19 @@ public class InstantiateVAppTemplateOptionsTest { assertEquals(options.getCpuCount(), "3"); } + @Test + public void testCustomizeOnInstantiate() { + InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions(); + options.customizeOnInstantiate(true); + assertEquals(options.shouldCustomizeOnInstantiate(), new Boolean(true)); + } + + @Test + public void testCustomizeOnInstantiateStatic() { + InstantiateVAppTemplateOptions options = customizeOnInstantiate(true); + assertEquals(options.shouldCustomizeOnInstantiate(), new Boolean(true)); + } + @Test public void testRam() { InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions(); diff --git a/vcloud/core/src/test/resources/guestCustomizationSection.xml b/vcloud/core/src/test/resources/guestCustomizationSection.xml new file mode 100644 index 0000000000..2fadb53120 --- /dev/null +++ b/vcloud/core/src/test/resources/guestCustomizationSection.xml @@ -0,0 +1,3 @@ +Specifies Guest OS Customization Settingscat > /tmp/foo.txt<<EOF +I love candy +EOF \ No newline at end of file diff --git a/vcloud/core/src/test/resources/instantiationparams-customization.xml b/vcloud/core/src/test/resources/instantiationparams-customization.xml new file mode 100644 index 0000000000..9df99619b8 --- /dev/null +++ b/vcloud/core/src/test/resources/instantiationparams-customization.xml @@ -0,0 +1 @@ +Configuration parameters for logical networksbridgedtrue \ No newline at end of file From 03fe0f3670a044eac14879f48306acf413136b3c Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sun, 5 Sep 2010 00:59:38 -0700 Subject: [PATCH 24/63] cleaned up test --- .../VCloudGuestCustomizationLiveTest.java | 56 +++++++------------ 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java index 6b28ba4130..0c46bcebe7 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java @@ -21,10 +21,10 @@ package org.jclouds.vcloud; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.get; +import static com.google.common.collect.Iterables.getOnlyElement; import static org.testng.Assert.assertEquals; import java.util.Properties; -import java.util.Set; import java.util.concurrent.TimeUnit; import org.jclouds.Constants; @@ -36,29 +36,30 @@ import org.jclouds.compute.options.TemplateOptions; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.net.IPSocket; import org.jclouds.predicates.RetryablePredicate; -import org.jclouds.predicates.SocketOpen; -import org.jclouds.ssh.ExecResponse; import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient.Factory; import org.jclouds.ssh.jsch.config.JschSshClientModule; +import org.jclouds.ssh.jsch.predicates.InetSocketAddressConnect; import org.jclouds.vcloud.compute.options.VCloudTemplateOptions; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.inject.Guice; -import com.google.inject.Injector; import com.google.inject.Module; /** - * + * This tests that we can use guest customization as an alternative to bootstrapping with ssh. There + * are a few advantages to this, including the fact that it can work inside google appengine where + * network sockets (ssh:22) are prohibited. * * @author Adrian Cole */ @Test(groups = "live", enabled = true, sequential = true, testName = "vcloud.VCloudGuestCustomizationLiveTest") public class VCloudGuestCustomizationLiveTest { + public static final String PARSE_VMTOOLSD = "vmtoolsd --cmd=\"info-get guestinfo.ovfenv\" |grep vCloud_CustomizationInfo|sed 's/.*value=\"\\(.*\\)\".*/\\1/g'|base64 -d"; + protected String identity; protected String provider; protected String credential; @@ -79,20 +80,10 @@ public class VCloudGuestCustomizationLiveTest { Properties props = new Properties(); props.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); props.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); - context = new ComputeServiceContextFactory().createContext(provider, identity, credential, ImmutableSet - . of(new Log4JLoggingModule()), props); - - client = context.getComputeService(); - - Injector injector = createSshClientInjector(); - sshFactory = injector.getInstance(SshClient.Factory.class); - SocketOpen socketOpen = injector.getInstance(SocketOpen.class); - socketTester = new RetryablePredicate(socketOpen, 60, 1, TimeUnit.SECONDS); - injector.injectMembers(socketOpen); // add logger - } - - protected Injector createSshClientInjector() { - return Guice.createInjector(getSshModule()); + client = new ComputeServiceContextFactory().createContext(provider, identity, credential, + ImmutableSet. of(new Log4JLoggingModule()), props).getComputeService(); + socketTester = new RetryablePredicate(new InetSocketAddressConnect(), 60, 1, TimeUnit.SECONDS); + sshFactory = Guice.createInjector(getSshModule()).getInstance(Factory.class); } protected JschSshClientModule getSshModule() { @@ -103,31 +94,26 @@ public class VCloudGuestCustomizationLiveTest { public void testExtendedOptionsWithCustomizationScript() throws Exception { String tag = "customize"; + String script = "cat > /root/foo.txt< /root/foo.txt< nodes = client.runNodesWithTag(tag, 1, options); + node = getOnlyElement(client.runNodesWithTag(tag, 1, options)); - NodeMetadata node = Iterables.get(nodes, 0); - nodeId = node.getId(); IPSocket socket = new IPSocket(get(node.getPublicAddresses(), 0), 22); - socketTester.apply(socket); + + assert socketTester.apply(socket); SshClient ssh = sshFactory.create(socket, node.getCredentials().identity, node.getCredentials().credential); try { ssh.connect(); - System.out - .println(ssh - .exec("vmtoolsd --cmd=\"info-get guestinfo.ovfenv\" |grep vCloud_CustomizationInfo|sed 's/.*value=\"\\(.*\\)\".*/\\1/g'|base64 -d")); - - ExecResponse hello = ssh.exec("cat /root/foo.txt"); - assertEquals(hello.getOutput().trim(), "I love candy"); + assertEquals(ssh.exec(PARSE_VMTOOLSD).getOutput(), script); + assertEquals(ssh.exec("cat /root/foo.txt").getOutput().trim(), "I love candy"); } finally { if (ssh != null) @@ -135,8 +121,8 @@ public class VCloudGuestCustomizationLiveTest { } } finally { - if (nodeId != null) - client.destroyNode(nodeId); + if (node != null) + client.destroyNode(node.getId()); } } From f4f714a2f4aac0524fe7a4801d1c521a8980f54b Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 6 Sep 2010 16:30:56 -0700 Subject: [PATCH 25/63] Issue 308: added spotInstanceRequestId to ec2 runninginstance --- .../aws/ec2/domain/RunningInstance.java | 67 +++++++++++++------ .../aws/ec2/xml/BaseReservationHandler.java | 7 +- .../DescribeInstancesResponseHandlerTest.java | 10 +-- .../xml/RunInstancesResponseHandlerTest.java | 8 +-- 4 files changed, 60 insertions(+), 32 deletions(-) diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/domain/RunningInstance.java b/aws/core/src/main/java/org/jclouds/aws/ec2/domain/RunningInstance.java index 2b6a9fb455..663a57b1f1 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/domain/RunningInstance.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/domain/RunningInstance.java @@ -152,6 +152,8 @@ public class RunningInstance implements Comparable { @Nullable private final String subnetId; @Nullable + private final String spotInstanceRequestId; + @Nullable private final String vpcId; private final RootDeviceType rootDeviceType; @Nullable @@ -168,8 +170,9 @@ public class RunningInstance implements Comparable { Date launchTime, MonitoringState monitoringState, String availabilityZone, @Nullable String placementGroup, String virtualizationType, @Nullable String platform, @Nullable String privateDnsName, @Nullable String privateIpAddress, Set productCodes, @Nullable String ramdiskId, - @Nullable String reason, @Nullable String subnetId, @Nullable String vpcId, RootDeviceType rootDeviceType, - @Nullable String rootDeviceName, Map ebsBlockDevices) { + @Nullable String reason, @Nullable String subnetId, @Nullable String spotInstanceRequestId, + @Nullable String vpcId, RootDeviceType rootDeviceType, @Nullable String rootDeviceName, + Map ebsBlockDevices) { Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds")); this.region = checkNotNull(region, "region"); this.amiLaunchIndex = amiLaunchIndex; // nullable on runinstances. @@ -193,6 +196,7 @@ public class RunningInstance implements Comparable { this.ramdiskId = ramdiskId; this.reason = reason; this.subnetId = subnetId; + this.spotInstanceRequestId = spotInstanceRequestId; this.vpcId = vpcId; this.rootDeviceType = checkNotNull(rootDeviceType, "rootDeviceType"); this.rootDeviceName = rootDeviceName; @@ -352,6 +356,13 @@ public class RunningInstance implements Comparable { return reason; } + /** + * The ID of the Spot Instance request + */ + public String getSpotInstanceRequestId() { + return spotInstanceRequestId; + } + /** * Specifies the subnet ID in which the instance is running (Amazon Virtual Private Cloud). */ @@ -394,20 +405,18 @@ public class RunningInstance implements Comparable { int result = 1; result = prime * result + ((amiLaunchIndex == null) ? 0 : amiLaunchIndex.hashCode()); result = prime * result + ((availabilityZone == null) ? 0 : availabilityZone.hashCode()); - result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); - result = prime * result + ((virtualizationType == null) ? 0 : virtualizationType.hashCode()); result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode()); result = prime * result + ((ebsBlockDevices == null) ? 0 : ebsBlockDevices.hashCode()); result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode()); result = prime * result + ((imageId == null) ? 0 : imageId.hashCode()); result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode()); - result = prime * result + ((instanceState == null) ? 0 : instanceState.hashCode()); result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode()); result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode()); result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode()); result = prime * result + ((keyName == null) ? 0 : keyName.hashCode()); result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode()); result = prime * result + ((monitoringState == null) ? 0 : monitoringState.hashCode()); + result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); result = prime * result + ((platform == null) ? 0 : platform.hashCode()); result = prime * result + ((privateDnsName == null) ? 0 : privateDnsName.hashCode()); result = prime * result + ((privateIpAddress == null) ? 0 : privateIpAddress.hashCode()); @@ -415,7 +424,11 @@ public class RunningInstance implements Comparable { result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode()); result = prime * result + ((reason == null) ? 0 : reason.hashCode()); result = prime * result + ((region == null) ? 0 : region.hashCode()); + result = prime * result + ((rootDeviceName == null) ? 0 : rootDeviceName.hashCode()); + result = prime * result + ((rootDeviceType == null) ? 0 : rootDeviceType.hashCode()); + result = prime * result + ((spotInstanceRequestId == null) ? 0 : spotInstanceRequestId.hashCode()); result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); + result = prime * result + ((virtualizationType == null) ? 0 : virtualizationType.hashCode()); result = prime * result + ((vpcId == null) ? 0 : vpcId.hashCode()); return result; } @@ -439,16 +452,6 @@ public class RunningInstance implements Comparable { return false; } else if (!availabilityZone.equals(other.availabilityZone)) return false; - if (placementGroup == null) { - if (other.placementGroup != null) - return false; - } else if (!placementGroup.equals(other.placementGroup)) - return false; - if (virtualizationType == null) { - if (other.virtualizationType != null) - return false; - } else if (!virtualizationType.equals(other.virtualizationType)) - return false; if (dnsName == null) { if (other.dnsName != null) return false; @@ -474,11 +477,6 @@ public class RunningInstance implements Comparable { return false; } else if (!instanceId.equals(other.instanceId)) return false; - if (instanceState == null) { - if (other.instanceState != null) - return false; - } else if (!instanceState.equals(other.instanceState)) - return false; if (instanceType == null) { if (other.instanceType != null) return false; @@ -509,6 +507,11 @@ public class RunningInstance implements Comparable { return false; } else if (!monitoringState.equals(other.monitoringState)) return false; + if (placementGroup == null) { + if (other.placementGroup != null) + return false; + } else if (!placementGroup.equals(other.placementGroup)) + return false; if (platform == null) { if (other.platform != null) return false; @@ -544,11 +547,31 @@ public class RunningInstance implements Comparable { return false; } else if (!region.equals(other.region)) return false; + if (rootDeviceName == null) { + if (other.rootDeviceName != null) + return false; + } else if (!rootDeviceName.equals(other.rootDeviceName)) + return false; + if (rootDeviceType == null) { + if (other.rootDeviceType != null) + return false; + } else if (!rootDeviceType.equals(other.rootDeviceType)) + return false; + if (spotInstanceRequestId == null) { + if (other.spotInstanceRequestId != null) + return false; + } else if (!spotInstanceRequestId.equals(other.spotInstanceRequestId)) + return false; if (subnetId == null) { if (other.subnetId != null) return false; } else if (!subnetId.equals(other.subnetId)) return false; + if (virtualizationType == null) { + if (other.virtualizationType != null) + return false; + } else if (!virtualizationType.equals(other.virtualizationType)) + return false; if (vpcId == null) { if (other.vpcId != null) return false; @@ -567,8 +590,8 @@ public class RunningInstance implements Comparable { + launchTime + ", monitoringState=" + monitoringState + ", platform=" + platform + ", privateDnsName=" + privateDnsName + ", privateIpAddress=" + privateIpAddress + ", productCodes=" + productCodes + ", ramdiskId=" + ramdiskId + ", reason=" + reason + ", region=" + region + ", rootDeviceName=" - + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", subnetId=" + subnetId + ", vpcId=" + vpcId - + "]"; + + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", spotInstanceRequestId=" + + spotInstanceRequestId + ", subnetId=" + subnetId + ", vpcId=" + vpcId + "]"; } } \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/xml/BaseReservationHandler.java b/aws/core/src/main/java/org/jclouds/aws/ec2/xml/BaseReservationHandler.java index 0bbda3e3ae..943f52a7d7 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/xml/BaseReservationHandler.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/xml/BaseReservationHandler.java @@ -86,6 +86,7 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque private Set productCodes = Sets.newHashSet(); private String ramdiskId; private String reason; + private String spotInstanceRequestId; private String subnetId; private String vpcId; protected boolean inInstances; @@ -183,6 +184,8 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque reason = currentOrNull(); } else if (qName.equals("subnetId")) { subnetId = currentOrNull(); + } else if (qName.equals("spotInstanceRequestId")) { + spotInstanceRequestId = currentOrNull(); } else if (qName.equals("vpcId")) { vpcId = currentOrNull(); } else if (qName.equals("productCode")) { @@ -244,7 +247,8 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque instances.add(new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instanceState, instanceType, ipAddress, kernelId, keyName, launchTime, monitoringState, availabilityZone, placementGroup, virtualizationType, platform, privateDnsName, privateIpAddress, - productCodes, ramdiskId, reason, subnetId, vpcId, rootDeviceType, rootDeviceName, ebsBlockDevices)); + productCodes, ramdiskId, reason, subnetId, spotInstanceRequestId, vpcId, rootDeviceType, + rootDeviceName, ebsBlockDevices)); this.amiLaunchIndex = null; this.dnsName = null; this.imageId = null; @@ -266,6 +270,7 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque this.ramdiskId = null; this.reason = null; this.subnetId = null; + this.spotInstanceRequestId = null; this.vpcId = null; this.rootDeviceType = RootDeviceType.INSTANCE_STORE; this.rootDeviceName = null; diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeInstancesResponseHandlerTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeInstancesResponseHandlerTest.java index 7e0423605c..ddb2db4ffe 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeInstancesResponseHandlerTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/xml/DescribeInstancesResponseHandlerTest.java @@ -77,7 +77,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { "adriancole.ec21", dateService.iso8601DateParse("2009-11-09T03:00:34.000Z"), MonitoringState.DISABLED, AvailabilityZone.US_EAST_1C, null, "paravirtual", null, "ip-10-243-42-70.ec2.internal", "10.243.42.70", ImmutableSet. of(), "ari-a51cf9cc", - null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap + null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap . of())), "993194456877", null, "r-a3c508cb")); Set> result = getReservations(is); @@ -96,14 +96,14 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-132.ec2.internal", null, - ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, RootDeviceType.INSTANCE_STORE, + ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of()), new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23", "ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64435", InstanceState.RUNNING, InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService.iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-134.ec2.internal", null, ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, - null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of())), + null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of())), "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d")); Set> result = getReservations(is); @@ -123,7 +123,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { "i-3FFA0762", InstanceState.SHUTTING_DOWN, InstanceType.M1_LARGE, null, "eki-6CBD12F2", "jclouds#euc-17", dateService.iso8601DateParse("2010-06-16T03:06:19.000Z"), MonitoringState.DISABLED, "open", null, "paravirtual", null, "10.7.0.179", null, ImmutableSet - . of(), "eri-A97113E4", null, null, null, RootDeviceType.INSTANCE_STORE, null, + . of(), "eri-A97113E4", null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of())), "jclouds", null, "r-4D2A08AD")); Set> result = getReservations(is); @@ -143,7 +143,7 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { "adriancole.ec2ebs1", dateService.iso8601DateParse("2009-12-30T04:06:23.000Z"), MonitoringState.DISABLED, AvailabilityZone.US_EAST_1B, "placement", "hvm", null, "domU-12-31-39-09-CE-53.compute-1.internal", "10.210.209.157", ImmutableSet. of(), - "ari-a51cf9cc", null, null, null, RootDeviceType.EBS, "/dev/sda1", ImmutableMap + "ari-a51cf9cc", null, null, null, null, RootDeviceType.EBS, "/dev/sda1", ImmutableMap . of("/dev/sda1", new EbsBlockDevice("vol-dc6ca8b5", Attachment.Status.ATTACHED, dateService .iso8601DateParse("2009-12-30T04:06:29.000Z"), true)))), diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java index b08b604513..2612a79735 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java @@ -71,17 +71,17 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { null, "ami-60a54009", "i-2ba64342", InstanceState.PENDING, InstanceType.M1_SMALL, (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets - . newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null, - ImmutableMap. of()), new RunningInstance(defaultRegion, ImmutableSet + . newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, + null, ImmutableMap. of()), new RunningInstance(defaultRegion, ImmutableSet .of("default"), "1", null, "ami-60a54009", "i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL, (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, - Sets. newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null, + Sets. newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of()), new RunningInstance(defaultRegion, ImmutableSet .of("default"), "2", null, "ami-60a54009", "i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL, (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, - Sets. newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null, + Sets. newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of()) ), "AIDADH4IGTRXXKCD", null, "r-47a5402e"); From 86fa8314caa534ea686780d25df5d8fabdf43904 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 6 Sep 2010 16:52:17 -0700 Subject: [PATCH 26/63] Issue 230: moving to sandbox as we don't have an account to finish this --- README.txt | 2 +- allcompute/pom.xml | 5 ----- compute/src/main/clojure/org/jclouds/compute.clj | 2 +- pom.xml | 1 - {ibmdev => sandbox/ibmdev}/pom.xml | 0 .../org/jclouds/ibmdev/IBMDeveloperCloudAsyncClient.java | 0 .../java/org/jclouds/ibmdev/IBMDeveloperCloudClient.java | 0 .../org/jclouds/ibmdev/IBMDeveloperCloudContextBuilder.java | 0 .../jclouds/ibmdev/IBMDeveloperCloudPropertiesBuilder.java | 0 .../config/IBMDeveloperCloudComputeServiceContextModule.java | 0 .../java/org/jclouds/ibmdev/compute/domain/IBMImage.java | 0 .../main/java/org/jclouds/ibmdev/compute/domain/IBMSize.java | 0 .../ibmdev/compute/functions/InstanceToNodeMetadata.java | 0 .../compute/options/IBMDeveloperCloudTemplateOptions.java | 0 .../CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet.java | 0 .../strategy/IBMDeveloperCloudAddNodeWithTagStrategy.java | 0 .../strategy/IBMDeveloperCloudDestroyNodeStrategy.java | 0 .../strategy/IBMDeveloperCloudGetNodeMetadataStrategy.java | 0 .../compute/strategy/IBMDeveloperCloudListNodesStrategy.java | 0 .../strategy/IBMDeveloperCloudRebootNodeStrategy.java | 0 .../compute/suppliers/IBMDeveloperCloudImageSupplier.java | 0 .../compute/suppliers/IBMDeveloperCloudLocationSupplier.java | 0 .../compute/suppliers/IBMDeveloperCloudSizeSupplier.java | 0 .../jclouds/ibmdev/config/IBMDeveloperCloudParserModule.java | 0 .../ibmdev/config/IBMDeveloperCloudRestClientModule.java | 0 .../src/main/java/org/jclouds/ibmdev/domain/Address.java | 0 .../src/main/java/org/jclouds/ibmdev/domain/Image.java | 0 .../src/main/java/org/jclouds/ibmdev/domain/Instance.java | 0 .../main/java/org/jclouds/ibmdev/domain/InstanceType.java | 0 .../ibmdev}/src/main/java/org/jclouds/ibmdev/domain/Key.java | 0 .../src/main/java/org/jclouds/ibmdev/domain/Location.java | 0 .../src/main/java/org/jclouds/ibmdev/domain/Offering.java | 0 .../src/main/java/org/jclouds/ibmdev/domain/Price.java | 0 .../main/java/org/jclouds/ibmdev/domain/StorageOffering.java | 0 .../src/main/java/org/jclouds/ibmdev/domain/Volume.java | 0 .../org/jclouds/ibmdev/functions/GetFirstInstanceInList.java | 0 .../org/jclouds/ibmdev/functions/ParseAddressFromJson.java | 0 .../org/jclouds/ibmdev/functions/ParseAddressesFromJson.java | 0 .../ibmdev/functions/ParseExpirationTimeFromJson.java | 0 .../org/jclouds/ibmdev/functions/ParseImageFromJson.java | 0 .../org/jclouds/ibmdev/functions/ParseImagesFromJson.java | 0 .../org/jclouds/ibmdev/functions/ParseInstanceFromJson.java | 0 .../org/jclouds/ibmdev/functions/ParseInstancesFromJson.java | 0 .../java/org/jclouds/ibmdev/functions/ParseKeysFromJson.java | 0 .../java/org/jclouds/ibmdev/functions/ParseLongFromDate.java | 0 .../main/java/org/jclouds/ibmdev/functions/ParseUtils.java | 0 .../org/jclouds/ibmdev/functions/ParseVolumeFromJson.java | 0 .../org/jclouds/ibmdev/functions/ParseVolumesFromJson.java | 0 .../ibmdev/handlers/IBMDeveloperCloudErrorHandler.java | 0 .../org/jclouds/ibmdev/options/CreateInstanceOptions.java | 0 .../org/jclouds/ibmdev/options/RestartInstanceOptions.java | 0 .../main/java/org/jclouds/ibmdev/predicates/AddressFree.java | 0 .../java/org/jclouds/ibmdev/predicates/InstanceActive.java | 0 .../jclouds/ibmdev/predicates/InstanceActiveOrFailed.java | 0 .../jclouds/ibmdev/predicates/InstanceRemovedOrNotFound.java | 0 .../java/org/jclouds/ibmdev/predicates/VolumeUnmounted.java | 0 .../jclouds/ibmdev/reference/IBMDeveloperCloudConstants.java | 0 .../main/java/org/jclouds/ibmdev/xml/LocationHandler.java | 0 .../main/java/org/jclouds/ibmdev/xml/LocationsHandler.java | 0 .../org/jclouds/ibmdev/IBMDeveloperCloudAsyncClientTest.java | 0 .../org/jclouds/ibmdev/IBMDeveloperCloudClientLiveTest.java | 0 .../java/org/jclouds/ibmdev/ProvidersInPropertiesTest.java | 0 .../IBMDeveloperCloudComputeServiceLiveTestDisabled.java | 0 .../IBMDeveloperCloudComputeServiceContextModuleTest.java | 0 .../jclouds/ibmdev/functions/ParseAddressFromJsonTest.java | 0 .../jclouds/ibmdev/functions/ParseAddressesFromJsonTest.java | 0 .../ibmdev/functions/ParseExpirationTimeFromJsonTest.java | 0 .../org/jclouds/ibmdev/functions/ParseImageFromJsonTest.java | 0 .../jclouds/ibmdev/functions/ParseImagesFromJsonTest.java | 0 .../jclouds/ibmdev/functions/ParseInstanceFromJsonTest.java | 0 .../jclouds/ibmdev/functions/ParseInstancesFromJsonTest.java | 0 .../org/jclouds/ibmdev/functions/ParseKeyFromJsonTest.java | 0 .../org/jclouds/ibmdev/functions/ParseKeysFromJsonTest.java | 0 .../ibmdev/functions/ParseStorageOfferingsFromJsonTest.java | 0 .../jclouds/ibmdev/functions/ParseVolumeFromJsonTest.java | 0 .../jclouds/ibmdev/functions/ParseVolumesFromJsonTest.java | 0 .../java/org/jclouds/ibmdev/xml/LocationHandlerTest.java | 0 .../java/org/jclouds/ibmdev/xml/LocationsHandlerTest.java | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/address.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/addresses.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/image.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/images.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/instance.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/instances.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/key.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/keys.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/location.xml | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/log4j.xml | 0 .../ibmdev}/src/test/resources/storage-offerings.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/volume.json | 0 {ibmdev => sandbox/ibmdev}/src/test/resources/volumes.json | 0 91 files changed, 2 insertions(+), 8 deletions(-) rename {ibmdev => sandbox/ibmdev}/pom.xml (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClient.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudClient.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudContextBuilder.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudPropertiesBuilder.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModule.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/domain/IBMImage.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/domain/IBMSize.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/functions/InstanceToNodeMetadata.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/options/IBMDeveloperCloudTemplateOptions.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/strategy/CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudAddNodeWithTagStrategy.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudDestroyNodeStrategy.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudGetNodeMetadataStrategy.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudListNodesStrategy.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudRebootNodeStrategy.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudImageSupplier.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudLocationSupplier.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudSizeSupplier.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudParserModule.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudRestClientModule.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/Address.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/Image.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/Instance.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/InstanceType.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/Key.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/Location.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/Offering.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/Price.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/StorageOffering.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/domain/Volume.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/GetFirstInstanceInList.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseAddressFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseAddressesFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseImageFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseImagesFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseInstanceFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseInstancesFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseKeysFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseLongFromDate.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseUtils.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseVolumeFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/functions/ParseVolumesFromJson.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/handlers/IBMDeveloperCloudErrorHandler.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/options/CreateInstanceOptions.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/options/RestartInstanceOptions.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/predicates/AddressFree.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/predicates/InstanceActive.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/predicates/InstanceActiveOrFailed.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/predicates/InstanceRemovedOrNotFound.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/predicates/VolumeUnmounted.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/reference/IBMDeveloperCloudConstants.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/xml/LocationHandler.java (100%) rename {ibmdev => sandbox/ibmdev}/src/main/java/org/jclouds/ibmdev/xml/LocationsHandler.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClientTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudClientLiveTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/ProvidersInPropertiesTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/compute/IBMDeveloperCloudComputeServiceLiveTestDisabled.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModuleTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseAddressFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseAddressesFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseImageFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseImagesFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseInstanceFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseInstancesFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseKeyFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseKeysFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseStorageOfferingsFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseVolumeFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/functions/ParseVolumesFromJsonTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/xml/LocationHandlerTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/java/org/jclouds/ibmdev/xml/LocationsHandlerTest.java (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/address.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/addresses.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/image.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/images.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/instance.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/instances.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/key.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/keys.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/location.xml (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/log4j.xml (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/storage-offerings.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/volume.json (100%) rename {ibmdev => sandbox/ibmdev}/src/test/resources/volumes.json (100%) diff --git a/README.txt b/README.txt index 20b8a9e591..f3a1cf5037 100644 --- a/README.txt +++ b/README.txt @@ -28,7 +28,7 @@ our dev version is 1.0-SNAPSHOT our compute api supports: ec2, gogrid, rackspace, rimuhosting, vcloud, trmk-ecloud, trmk-vcloudexpress, eucalyptus, bluelock-vclouddirector, - bluelock-vcloudexpress, ibmdev, slicehost + bluelock-vcloudexpress, slicehost * note * the pom dependency org.jclouds/jclouds-allcompute gives you access to to all of these providers diff --git a/allcompute/pom.xml b/allcompute/pom.xml index 760cb00133..000e927a1f 100644 --- a/allcompute/pom.xml +++ b/allcompute/pom.xml @@ -64,11 +64,6 @@ jclouds-gogrid ${project.version} - - ${project.groupId} - jclouds-ibmdev - ${project.version} - ${project.groupId} jclouds-slicehost diff --git a/compute/src/main/clojure/org/jclouds/compute.clj b/compute/src/main/clojure/org/jclouds/compute.clj index bfc99fb758..14065000f2 100644 --- a/compute/src/main/clojure/org/jclouds/compute.clj +++ b/compute/src/main/clojure/org/jclouds/compute.clj @@ -22,7 +22,7 @@ Current supported services are: [ec2, rimuhosting, cloudservers, trmk-ecloud, trmk-vcloudexpress, vcloud, bluelock, - ibmdev, eucalyptus, slicehost] + eucalyptus, slicehost] Here's an example of getting some compute configuration from rackspace: diff --git a/pom.xml b/pom.xml index 45f67aba87..d321f80014 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,6 @@ gogrid chef opscodeplatform - ibmdev boxdotnet slicehost allcompute diff --git a/ibmdev/pom.xml b/sandbox/ibmdev/pom.xml similarity index 100% rename from ibmdev/pom.xml rename to sandbox/ibmdev/pom.xml diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClient.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClient.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClient.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClient.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudClient.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudClient.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudClient.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudClient.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudContextBuilder.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudContextBuilder.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudContextBuilder.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudContextBuilder.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudPropertiesBuilder.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudPropertiesBuilder.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudPropertiesBuilder.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/IBMDeveloperCloudPropertiesBuilder.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModule.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModule.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModule.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModule.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/domain/IBMImage.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/domain/IBMImage.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/domain/IBMImage.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/domain/IBMImage.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/domain/IBMSize.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/domain/IBMSize.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/domain/IBMSize.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/domain/IBMSize.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/functions/InstanceToNodeMetadata.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/functions/InstanceToNodeMetadata.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/functions/InstanceToNodeMetadata.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/functions/InstanceToNodeMetadata.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/options/IBMDeveloperCloudTemplateOptions.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/options/IBMDeveloperCloudTemplateOptions.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/options/IBMDeveloperCloudTemplateOptions.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/options/IBMDeveloperCloudTemplateOptions.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudAddNodeWithTagStrategy.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudAddNodeWithTagStrategy.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudAddNodeWithTagStrategy.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudAddNodeWithTagStrategy.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudDestroyNodeStrategy.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudDestroyNodeStrategy.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudDestroyNodeStrategy.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudDestroyNodeStrategy.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudGetNodeMetadataStrategy.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudGetNodeMetadataStrategy.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudGetNodeMetadataStrategy.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudGetNodeMetadataStrategy.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudListNodesStrategy.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudListNodesStrategy.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudListNodesStrategy.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudListNodesStrategy.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudRebootNodeStrategy.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudRebootNodeStrategy.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudRebootNodeStrategy.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/strategy/IBMDeveloperCloudRebootNodeStrategy.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudImageSupplier.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudImageSupplier.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudImageSupplier.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudImageSupplier.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudLocationSupplier.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudLocationSupplier.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudLocationSupplier.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudLocationSupplier.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudSizeSupplier.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudSizeSupplier.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudSizeSupplier.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/compute/suppliers/IBMDeveloperCloudSizeSupplier.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudParserModule.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudParserModule.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudParserModule.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudParserModule.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudRestClientModule.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudRestClientModule.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudRestClientModule.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/config/IBMDeveloperCloudRestClientModule.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Address.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Address.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/Address.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Address.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Image.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Image.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/Image.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Image.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Instance.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Instance.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/Instance.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Instance.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/InstanceType.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/InstanceType.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/InstanceType.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/InstanceType.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Key.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Key.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/Key.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Key.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Location.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Location.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/Location.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Location.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Offering.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Offering.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/Offering.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Offering.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Price.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Price.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/Price.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Price.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/StorageOffering.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/StorageOffering.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/StorageOffering.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/StorageOffering.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Volume.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Volume.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/domain/Volume.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/domain/Volume.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/GetFirstInstanceInList.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/GetFirstInstanceInList.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/GetFirstInstanceInList.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/GetFirstInstanceInList.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseAddressFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseAddressFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseAddressFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseAddressFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseAddressesFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseAddressesFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseAddressesFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseAddressesFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImageFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImageFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImageFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImageFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImagesFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImagesFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImagesFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImagesFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseInstanceFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseInstanceFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseInstanceFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseInstanceFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseInstancesFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseInstancesFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseInstancesFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseInstancesFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseKeysFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseKeysFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseKeysFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseKeysFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseLongFromDate.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseLongFromDate.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseLongFromDate.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseLongFromDate.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseUtils.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseUtils.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseUtils.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseUtils.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseVolumeFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseVolumeFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseVolumeFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseVolumeFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseVolumesFromJson.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseVolumesFromJson.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseVolumesFromJson.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseVolumesFromJson.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/handlers/IBMDeveloperCloudErrorHandler.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/handlers/IBMDeveloperCloudErrorHandler.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/handlers/IBMDeveloperCloudErrorHandler.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/handlers/IBMDeveloperCloudErrorHandler.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/options/CreateInstanceOptions.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/options/CreateInstanceOptions.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/options/CreateInstanceOptions.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/options/CreateInstanceOptions.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/options/RestartInstanceOptions.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/options/RestartInstanceOptions.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/options/RestartInstanceOptions.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/options/RestartInstanceOptions.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/AddressFree.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/AddressFree.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/predicates/AddressFree.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/AddressFree.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceActive.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceActive.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceActive.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceActive.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceActiveOrFailed.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceActiveOrFailed.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceActiveOrFailed.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceActiveOrFailed.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceRemovedOrNotFound.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceRemovedOrNotFound.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceRemovedOrNotFound.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/InstanceRemovedOrNotFound.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/VolumeUnmounted.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/VolumeUnmounted.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/predicates/VolumeUnmounted.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/predicates/VolumeUnmounted.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/reference/IBMDeveloperCloudConstants.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/reference/IBMDeveloperCloudConstants.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/reference/IBMDeveloperCloudConstants.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/reference/IBMDeveloperCloudConstants.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/xml/LocationHandler.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/xml/LocationHandler.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/xml/LocationHandler.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/xml/LocationHandler.java diff --git a/ibmdev/src/main/java/org/jclouds/ibmdev/xml/LocationsHandler.java b/sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/xml/LocationsHandler.java similarity index 100% rename from ibmdev/src/main/java/org/jclouds/ibmdev/xml/LocationsHandler.java rename to sandbox/ibmdev/src/main/java/org/jclouds/ibmdev/xml/LocationsHandler.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClientTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClientTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClientTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudAsyncClientTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudClientLiveTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudClientLiveTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudClientLiveTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/IBMDeveloperCloudClientLiveTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/ProvidersInPropertiesTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/ProvidersInPropertiesTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/ProvidersInPropertiesTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/ProvidersInPropertiesTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/compute/IBMDeveloperCloudComputeServiceLiveTestDisabled.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/compute/IBMDeveloperCloudComputeServiceLiveTestDisabled.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/compute/IBMDeveloperCloudComputeServiceLiveTestDisabled.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/compute/IBMDeveloperCloudComputeServiceLiveTestDisabled.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModuleTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModuleTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModuleTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/compute/config/IBMDeveloperCloudComputeServiceContextModuleTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseAddressFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseAddressFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseAddressFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseAddressFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseAddressesFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseAddressesFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseAddressesFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseAddressesFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseExpirationTimeFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseImageFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseImageFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseImageFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseImageFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseImagesFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseImagesFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseImagesFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseImagesFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseInstanceFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseInstanceFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseInstanceFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseInstanceFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseInstancesFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseInstancesFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseInstancesFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseInstancesFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseKeyFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseKeyFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseKeyFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseKeyFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseKeysFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseKeysFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseKeysFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseKeysFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseStorageOfferingsFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseStorageOfferingsFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseStorageOfferingsFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseStorageOfferingsFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseVolumeFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseVolumeFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseVolumeFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseVolumeFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseVolumesFromJsonTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseVolumesFromJsonTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseVolumesFromJsonTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/functions/ParseVolumesFromJsonTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/xml/LocationHandlerTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/xml/LocationHandlerTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/xml/LocationHandlerTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/xml/LocationHandlerTest.java diff --git a/ibmdev/src/test/java/org/jclouds/ibmdev/xml/LocationsHandlerTest.java b/sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/xml/LocationsHandlerTest.java similarity index 100% rename from ibmdev/src/test/java/org/jclouds/ibmdev/xml/LocationsHandlerTest.java rename to sandbox/ibmdev/src/test/java/org/jclouds/ibmdev/xml/LocationsHandlerTest.java diff --git a/ibmdev/src/test/resources/address.json b/sandbox/ibmdev/src/test/resources/address.json similarity index 100% rename from ibmdev/src/test/resources/address.json rename to sandbox/ibmdev/src/test/resources/address.json diff --git a/ibmdev/src/test/resources/addresses.json b/sandbox/ibmdev/src/test/resources/addresses.json similarity index 100% rename from ibmdev/src/test/resources/addresses.json rename to sandbox/ibmdev/src/test/resources/addresses.json diff --git a/ibmdev/src/test/resources/image.json b/sandbox/ibmdev/src/test/resources/image.json similarity index 100% rename from ibmdev/src/test/resources/image.json rename to sandbox/ibmdev/src/test/resources/image.json diff --git a/ibmdev/src/test/resources/images.json b/sandbox/ibmdev/src/test/resources/images.json similarity index 100% rename from ibmdev/src/test/resources/images.json rename to sandbox/ibmdev/src/test/resources/images.json diff --git a/ibmdev/src/test/resources/instance.json b/sandbox/ibmdev/src/test/resources/instance.json similarity index 100% rename from ibmdev/src/test/resources/instance.json rename to sandbox/ibmdev/src/test/resources/instance.json diff --git a/ibmdev/src/test/resources/instances.json b/sandbox/ibmdev/src/test/resources/instances.json similarity index 100% rename from ibmdev/src/test/resources/instances.json rename to sandbox/ibmdev/src/test/resources/instances.json diff --git a/ibmdev/src/test/resources/key.json b/sandbox/ibmdev/src/test/resources/key.json similarity index 100% rename from ibmdev/src/test/resources/key.json rename to sandbox/ibmdev/src/test/resources/key.json diff --git a/ibmdev/src/test/resources/keys.json b/sandbox/ibmdev/src/test/resources/keys.json similarity index 100% rename from ibmdev/src/test/resources/keys.json rename to sandbox/ibmdev/src/test/resources/keys.json diff --git a/ibmdev/src/test/resources/location.xml b/sandbox/ibmdev/src/test/resources/location.xml similarity index 100% rename from ibmdev/src/test/resources/location.xml rename to sandbox/ibmdev/src/test/resources/location.xml diff --git a/ibmdev/src/test/resources/log4j.xml b/sandbox/ibmdev/src/test/resources/log4j.xml similarity index 100% rename from ibmdev/src/test/resources/log4j.xml rename to sandbox/ibmdev/src/test/resources/log4j.xml diff --git a/ibmdev/src/test/resources/storage-offerings.json b/sandbox/ibmdev/src/test/resources/storage-offerings.json similarity index 100% rename from ibmdev/src/test/resources/storage-offerings.json rename to sandbox/ibmdev/src/test/resources/storage-offerings.json diff --git a/ibmdev/src/test/resources/volume.json b/sandbox/ibmdev/src/test/resources/volume.json similarity index 100% rename from ibmdev/src/test/resources/volume.json rename to sandbox/ibmdev/src/test/resources/volume.json diff --git a/ibmdev/src/test/resources/volumes.json b/sandbox/ibmdev/src/test/resources/volumes.json similarity index 100% rename from ibmdev/src/test/resources/volumes.json rename to sandbox/ibmdev/src/test/resources/volumes.json From e8d07a9e91bdef76be7f9e6bbed1426a715df55e Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 6 Sep 2010 17:51:46 -0700 Subject: [PATCH 27/63] reorganized project so that unfinished components are in the sandbox --- README.txt | 5 +- all/pom.xml | 15 -- .../assemblies/package-descriptor.xml | 201 ++++++++++++++---- aws/extensions/pom.xml | 58 ----- aws/pom.xml | 1 - pom.xml | 3 - {boxdotnet => sandbox/boxdotnet}/pom.xml | 0 .../boxdotnet/BoxDotNetAsyncClient.java | 0 .../jclouds/boxdotnet/BoxDotNetClient.java | 0 .../boxdotnet/BoxDotNetContextBuilder.java | 0 .../boxdotnet/BoxDotNetPropertiesBuilder.java | 0 .../config/BoxDotNetRestClientModule.java | 0 .../handlers/BoxDotNetErrorHandler.java | 0 .../boxdotnet/BoxDotNetAsyncClientTest.java | 0 .../boxdotnet/BoxDotNetClientLiveTest.java | 0 .../boxdotnet}/src/test/resources/log4j.xml | 0 {aws/extensions => sandbox}/jets3t/README.txt | 0 {aws/extensions => sandbox}/jets3t/pom.xml | 0 .../aws/s3/jets3t/JCloudsS3Service.java | 0 .../java/org/jclouds/aws/s3/jets3t/Util.java | 0 .../s3/jets3t/JCloudsS3ServiceLiveTest.java | 0 {mezeo => sandbox/mezeo}/pcs2/core/.gitignore | 0 {mezeo => sandbox/mezeo}/pcs2/core/README.txt | 0 {mezeo => sandbox/mezeo}/pcs2/core/pom.xml | 0 .../jclouds/mezeo/pcs2/PCSAsyncClient.java | 0 .../org/jclouds/mezeo/pcs2/PCSClient.java | 0 .../mezeo/pcs2/PCSCloudAsyncClient.java | 0 .../jclouds/mezeo/pcs2/PCSContextBuilder.java | 0 .../BindContainerNameToXmlPayload.java | 0 .../binders/BindFileInfoToXmlPayload.java | 0 .../binders/BindPCSFileToMultipartForm.java | 0 .../blobstore/functions/BlobToFileInfo.java | 0 .../blobstore/functions/BlobToPCSFile.java | 0 .../functions/FileInfoToBlobMetadata.java | 0 .../blobstore/functions/PCSFileToBlob.java | 0 .../mezeo/pcs2/config/PCSObjectModule.java | 0 .../pcs2/config/PCSRestClientModule.java | 0 .../mezeo/pcs2/domain/ContainerInfo.java | 0 .../mezeo/pcs2/domain/ContainerList.java | 0 .../jclouds/mezeo/pcs2/domain/FileInfo.java | 0 .../pcs2/domain/FileInfoWithMetadata.java | 0 .../mezeo/pcs2/domain/MutableFileInfo.java | 0 .../pcs2/domain/MutableResourceInfo.java | 0 .../jclouds/mezeo/pcs2/domain/PCSFile.java | 0 .../mezeo/pcs2/domain/ResourceInfo.java | 0 .../domain/internal/ContainerInfoImpl.java | 0 .../domain/internal/ContainerListImpl.java | 0 .../pcs2/domain/internal/FileInfoImpl.java | 0 .../internal/FileInfoWithMetadataImpl.java | 0 .../domain/internal/MutableFileInfoImpl.java | 0 .../internal/MutableResourceInfoImpl.java | 0 .../pcs2/domain/internal/PCSFileImpl.java | 0 .../domain/internal/ResourceInfoImpl.java | 0 .../mezeo/pcs2/endpoints/Contacts.java | 0 .../mezeo/pcs2/endpoints/Metacontainers.java | 0 .../mezeo/pcs2/endpoints/Projects.java | 0 .../mezeo/pcs2/endpoints/Recyclebin.java | 0 .../mezeo/pcs2/endpoints/RootContainer.java | 0 .../jclouds/mezeo/pcs2/endpoints/Shares.java | 0 .../jclouds/mezeo/pcs2/endpoints/Tags.java | 0 .../jclouds/mezeo/pcs2/endpoints/WebDAV.java | 0 .../functions/AddMetadataItemIntoMap.java | 0 .../ReturnFalseIfContainerNotFound.java | 0 .../ReturnTrueIfContainerAlreadyExists.java | 0 .../handlers/PCSClientErrorRetryHandler.java | 0 .../mezeo/pcs2/options/PutBlockOptions.java | 0 .../mezeo/pcs2/xml/CloudXlinkHandler.java | 0 .../mezeo/pcs2/xml/ContainerHandler.java | 0 .../jclouds/mezeo/pcs2/xml/FileHandler.java | 0 .../mezeo/pcs2/PCSAsyncClientTest.java | 0 .../jclouds/mezeo/pcs2/PCSClientLiveTest.java | 0 .../org/jclouds/mezeo/pcs2/PCSCloudTest.java | 0 .../mezeo/pcs2/ProvidersInPropertiesTest.java | 0 .../BindContainerNameToXmlPayloadTest.java | 0 .../binders/BindFileInfoToXmlPayloadTest.java | 0 .../functions/AddMetadataAndReturnIdTest.java | 0 .../AssembleBlobFromBlobMetadataCallTest.java | 0 .../pcs2/internal/StubPCSAsyncClient.java | 0 .../pcs2/options/PutBlockOptionsTest.java | 0 .../mezeo/pcs2/xml/CloudXlinkHanderTest.java | 0 .../mezeo/pcs2/xml/ContainerHandlerTest.java | 0 .../pcs2/xml/FileMetadataHandlerTest.java | 0 .../core/src/test/resources/discovery.xml | 0 .../pcs2/core/src/test/resources/log4j.xml | 0 .../src/test/resources/test_file_metadata.xml | 0 .../test/resources/test_root_container.xml | 0 {mezeo => sandbox/mezeo}/pcs2/pom.xml | 0 {mezeo => sandbox/mezeo}/pom.xml | 0 {nirvanix => sandbox/nirvanix}/pom.xml | 0 .../nirvanix}/sdn/core/.gitignore | 0 .../nirvanix}/sdn/core/README.txt | 0 .../nirvanix}/sdn/core/pom.xml | 0 .../jclouds/nirvanix/sdn/SDNAsyncClient.java | 0 .../nirvanix/sdn/SDNAuthAsyncClient.java | 0 .../org/jclouds/nirvanix/sdn/SDNClient.java | 0 .../nirvanix/sdn/SDNContextBuilder.java | 0 .../nirvanix/sdn/SDNPropertiesBuilder.java | 0 .../jclouds/nirvanix/sdn/SessionToken.java | 0 .../binders/BindMetadataToQueryParams.java | 0 .../sdn/config/SDNAuthRestClientModule.java | 0 .../sdn/config/SDNRestClientModule.java | 0 .../nirvanix/sdn/domain/UploadInfo.java | 0 .../sdn/filters/AddSessionTokenToRequest.java | 0 .../filters/InsertUserContextIntoPath.java | 0 .../ParseMetadataFromJsonResponse.java | 0 .../ParseSessionTokenFromJsonResponse.java | 0 .../ParseUploadInfoFromJsonResponse.java | 0 .../nirvanix/sdn/reference/SDNConstants.java | 0 .../sdn/reference/SDNQueryParams.java | 0 .../sdn/ProvidersInPropertiesTest.java | 0 .../nirvanix/sdn/SDNAsyncClientTest.java | 0 .../nirvanix/sdn/SDNAuthAsyncClientTest.java | 0 .../sdn/SDNAuthenticationLiveTest.java | 0 .../nirvanix/sdn/SDNClientLiveTest.java | 0 .../BindMetadataToQueryParamsTest.java | 0 .../filters/AddSessionTokenToRequestTest.java | 0 .../InsertUserContextIntoPathTest.java | 0 .../ParseMetadataFromJsonResponseTest.java | 0 ...ParseSessionTokenFromJsonResponseTest.java | 0 .../ParseUploadInfoFromJsonResponseTest.java | 0 .../core/src/test/resources/authtoken.json | 0 .../sdn/core/src/test/resources/log4j.xml | 0 .../sdn/core/src/test/resources/login.json | 0 .../sdn/core/src/test/resources/metadata.json | 0 {nirvanix => sandbox/nirvanix}/sdn/pom.xml | 0 125 files changed, 165 insertions(+), 118 deletions(-) delete mode 100644 aws/extensions/pom.xml rename {boxdotnet => sandbox/boxdotnet}/pom.xml (100%) rename {boxdotnet => sandbox/boxdotnet}/src/main/java/org/jclouds/boxdotnet/BoxDotNetAsyncClient.java (100%) rename {boxdotnet => sandbox/boxdotnet}/src/main/java/org/jclouds/boxdotnet/BoxDotNetClient.java (100%) rename {boxdotnet => sandbox/boxdotnet}/src/main/java/org/jclouds/boxdotnet/BoxDotNetContextBuilder.java (100%) rename {boxdotnet => sandbox/boxdotnet}/src/main/java/org/jclouds/boxdotnet/BoxDotNetPropertiesBuilder.java (100%) rename {boxdotnet => sandbox/boxdotnet}/src/main/java/org/jclouds/boxdotnet/config/BoxDotNetRestClientModule.java (100%) rename {boxdotnet => sandbox/boxdotnet}/src/main/java/org/jclouds/boxdotnet/handlers/BoxDotNetErrorHandler.java (100%) rename {boxdotnet => sandbox/boxdotnet}/src/test/java/org/jclouds/boxdotnet/BoxDotNetAsyncClientTest.java (100%) rename {boxdotnet => sandbox/boxdotnet}/src/test/java/org/jclouds/boxdotnet/BoxDotNetClientLiveTest.java (100%) rename {boxdotnet => sandbox/boxdotnet}/src/test/resources/log4j.xml (100%) rename {aws/extensions => sandbox}/jets3t/README.txt (100%) rename {aws/extensions => sandbox}/jets3t/pom.xml (100%) rename {aws/extensions => sandbox}/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/JCloudsS3Service.java (100%) rename {aws/extensions => sandbox}/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/Util.java (100%) rename {aws/extensions => sandbox}/jets3t/src/test/java/org/jclouds/aws/s3/jets3t/JCloudsS3ServiceLiveTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/.gitignore (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/README.txt (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/pom.xml (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSAsyncClient.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSClient.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSCloudAsyncClient.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSContextBuilder.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayload.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayload.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindPCSFileToMultipartForm.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToFileInfo.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToPCSFile.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/FileInfoToBlobMetadata.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/PCSFileToBlob.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSObjectModule.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSRestClientModule.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerInfo.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerList.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfo.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfoWithMetadata.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableFileInfo.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableResourceInfo.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/PCSFile.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ResourceInfo.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerInfoImpl.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerListImpl.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoImpl.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoWithMetadataImpl.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableFileInfoImpl.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableResourceInfoImpl.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/PCSFileImpl.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ResourceInfoImpl.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Contacts.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Metacontainers.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Projects.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Recyclebin.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/RootContainer.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Shares.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Tags.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/WebDAV.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddMetadataItemIntoMap.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnFalseIfContainerNotFound.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnTrueIfContainerAlreadyExists.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/handlers/PCSClientErrorRetryHandler.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/options/PutBlockOptions.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHandler.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/ContainerHandler.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/FileHandler.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSAsyncClientTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSClientLiveTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSCloudTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/ProvidersInPropertiesTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayloadTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayloadTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndReturnIdTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromBlobMetadataCallTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/internal/StubPCSAsyncClient.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/options/PutBlockOptionsTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHanderTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/ContainerHandlerTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/FileMetadataHandlerTest.java (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/resources/discovery.xml (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/resources/log4j.xml (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/resources/test_file_metadata.xml (100%) rename {mezeo => sandbox/mezeo}/pcs2/core/src/test/resources/test_root_container.xml (100%) rename {mezeo => sandbox/mezeo}/pcs2/pom.xml (100%) rename {mezeo => sandbox/mezeo}/pom.xml (100%) rename {nirvanix => sandbox/nirvanix}/pom.xml (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/.gitignore (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/README.txt (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/pom.xml (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAsyncClient.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClient.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNClient.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNContextBuilder.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNPropertiesBuilder.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SessionToken.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParams.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNAuthRestClientModule.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNRestClientModule.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/domain/UploadInfo.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPath.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponse.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponse.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponse.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNConstants.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNQueryParams.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/ProvidersInPropertiesTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAsyncClientTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClientTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthenticationLiveTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNClientLiveTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParamsTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequestTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPathTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponseTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponseTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponseTest.java (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/resources/authtoken.json (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/resources/log4j.xml (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/resources/login.json (100%) rename {nirvanix => sandbox/nirvanix}/sdn/core/src/test/resources/metadata.json (100%) rename {nirvanix => sandbox/nirvanix}/sdn/pom.xml (100%) diff --git a/README.txt b/README.txt index f3a1cf5037..8232bbf10b 100644 --- a/README.txt +++ b/README.txt @@ -28,7 +28,7 @@ our dev version is 1.0-SNAPSHOT our compute api supports: ec2, gogrid, rackspace, rimuhosting, vcloud, trmk-ecloud, trmk-vcloudexpress, eucalyptus, bluelock-vclouddirector, - bluelock-vcloudexpress, slicehost + bluelock-vcloudexpress, slicehost, stub (in-memory) * note * the pom dependency org.jclouds/jclouds-allcompute gives you access to to all of these providers @@ -39,7 +39,8 @@ our blobstore api supports: s3, rackspace, azure, atmos online, att synaptic, * note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to to all of these providers -we also have rest clients for: chef, opscodeplatform, pcs2 (mezeo), sdn (nirvanix), twitter +we also have rest clients for: chef, opscodeplatform, twitter, as well a number of features + in the sandbox If you want access to all jclouds components, include the maven dependency org.jclouds/jclouds-all diff --git a/all/pom.xml b/all/pom.xml index c29afbf3ab..8235fbb327 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -39,16 +39,6 @@ jclouds-allblobstore ${project.version} - - ${project.groupId} - jclouds-pcs2 - ${project.version} - - - ${project.groupId} - jclouds-sdn - ${project.version} - ${project.groupId} jclouds-twitter @@ -64,10 +54,5 @@ jclouds-opscodeplatform ${project.version} - - ${project.groupId} - jclouds-boxdotnet - ${project.version} - diff --git a/assemblies/src/main/resources/assemblies/package-descriptor.xml b/assemblies/src/main/resources/assemblies/package-descriptor.xml index 9afba8c97c..301cb16a0e 100644 --- a/assemblies/src/main/resources/assemblies/package-descriptor.xml +++ b/assemblies/src/main/resources/assemblies/package-descriptor.xml @@ -243,59 +243,32 @@ providers/azure - + - mezeo/pcs2/target + slicehost/target - jclouds-pcs2-${project.version}.jar + jclouds-slicehost-${project.version}.jar - providers/mezeo/lib + providers/slicehost/lib - mezeo/pcs2/target + slicehost/target - jclouds-pcs2-${project.version}-sources.jar + jclouds-slicehost-${project.version}-sources.jar - providers/mezeo/src + providers/slicehost/src - mezeo/pcs2/target/apidocs - providers/mezeo/docs + slicehost/target/apidocs + providers/slicehost/docs - mezeo/pcs2 + slicehost README.txt - providers/mezeo - - - - - nirvanix/sdn/target - - jclouds-sdn-${project.version}.jar - - providers/nirvanix/lib - - - nirvanix/sdn/target - - jclouds-sdn-${project.version}-sources.jar - - providers/nirvanix/src - - - nirvanix/sdn/target/apidocs - providers/nirvanix/docs - - - nirvanix/sdn - - README.txt - - providers/nirvanix - + providers/slicehost + @@ -324,6 +297,33 @@ providers/rackspace + + + gogrid/target + + jclouds-gogrid-${project.version}.jar + + providers/gogrid/lib + + + gogrid/target + + jclouds-gogrid-${project.version}-sources.jar + + providers/gogrid/src + + + gogrid/target/apidocs + providers/gogrid/docs + + + gogrid + + README.txt + + providers/gogrid + + rimuhosting/target @@ -351,7 +351,62 @@ providers/rimuhosting + + + vcloud/core/target + + jclouds-vcloud-${project.version}.jar + + providers/bluelock/lib + + + vcloud/core/target + + jclouds-vcloud-${project.version}-sources.jar + + providers/bluelock/src + + + vcloud/bluelock/target + + jclouds-bluelock-${project.version}.jar + + providers/bluelock/lib + + + vcloud/bluelock/target + + jclouds-bluelock-${project.version}-sources.jar + + providers/bluelock/src + + + vcloud/bluelock/target/apidocs + providers/bluelock/docs + + + vcloud/bluelock + + README.txt + + providers/bluelock + + + + vcloud/core/target + + jclouds-vcloud-${project.version}.jar + + providers/terremark/lib + + + vcloud/core/target + + jclouds-vcloud-${project.version}-sources.jar + + providers/terremark/src + vcloud/terremark/target @@ -378,6 +433,74 @@ providers/terremark + + + chef/target + + jclouds-chef-${project.version}.jar + + providers/chef/lib + + + chef/target + + jclouds-chef-${project.version}-sources.jar + + providers/chef/src + + + chef/target/apidocs + providers/chef/docs + + + chef + + README.txt + + providers/chef + + + + + chef/target + + jclouds-chef-${project.version}.jar + + providers/opscodeplatform/lib + + + chef/target + + jclouds-chef-${project.version}-sources.jar + + providers/opscodeplatform/src + + + opscodeplatform/target + + jclouds-opscodeplatform-${project.version}.jar + + providers/opscodeplatform/lib + + + opscodeplatform/target + + jclouds-opscodeplatform-${project.version}-sources.jar + + providers/opscodeplatform/src + + + opscodeplatform/target/apidocs + providers/opscodeplatform/docs + + + opscodeplatform + + README.txt + + providers/opscodeplatform + + twitter/target diff --git a/aws/extensions/pom.xml b/aws/extensions/pom.xml deleted file mode 100644 index e401ade46f..0000000000 --- a/aws/extensions/pom.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - 4.0.0 - - jclouds-aws-project - org.jclouds - 1.0-SNAPSHOT - - jclouds-aws-extensions-project - pom - jclouds AWS extensions aggregator - - jets3t - - - - - ${project.groupId} - jclouds-aws - ${project.version} - - - ${project.groupId} - jclouds-blobstore - ${project.version} - test-jar - test - - - ${project.groupId} - jclouds-aws - ${project.version} - test-jar - test - - - diff --git a/aws/pom.xml b/aws/pom.xml index 6750534dbf..83215e64e2 100644 --- a/aws/pom.xml +++ b/aws/pom.xml @@ -33,7 +33,6 @@ jclouds AWS project core - extensions demos diff --git a/pom.xml b/pom.xml index d321f80014..e6289553a2 100644 --- a/pom.xml +++ b/pom.xml @@ -44,8 +44,6 @@ aws azure atmos - mezeo - nirvanix rackspace rimuhosting twitter @@ -53,7 +51,6 @@ gogrid chef opscodeplatform - boxdotnet slicehost allcompute allblobstore diff --git a/boxdotnet/pom.xml b/sandbox/boxdotnet/pom.xml similarity index 100% rename from boxdotnet/pom.xml rename to sandbox/boxdotnet/pom.xml diff --git a/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetAsyncClient.java b/sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetAsyncClient.java similarity index 100% rename from boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetAsyncClient.java rename to sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetAsyncClient.java diff --git a/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetClient.java b/sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetClient.java similarity index 100% rename from boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetClient.java rename to sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetClient.java diff --git a/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetContextBuilder.java b/sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetContextBuilder.java similarity index 100% rename from boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetContextBuilder.java rename to sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetContextBuilder.java diff --git a/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetPropertiesBuilder.java b/sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetPropertiesBuilder.java similarity index 100% rename from boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetPropertiesBuilder.java rename to sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/BoxDotNetPropertiesBuilder.java diff --git a/boxdotnet/src/main/java/org/jclouds/boxdotnet/config/BoxDotNetRestClientModule.java b/sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/config/BoxDotNetRestClientModule.java similarity index 100% rename from boxdotnet/src/main/java/org/jclouds/boxdotnet/config/BoxDotNetRestClientModule.java rename to sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/config/BoxDotNetRestClientModule.java diff --git a/boxdotnet/src/main/java/org/jclouds/boxdotnet/handlers/BoxDotNetErrorHandler.java b/sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/handlers/BoxDotNetErrorHandler.java similarity index 100% rename from boxdotnet/src/main/java/org/jclouds/boxdotnet/handlers/BoxDotNetErrorHandler.java rename to sandbox/boxdotnet/src/main/java/org/jclouds/boxdotnet/handlers/BoxDotNetErrorHandler.java diff --git a/boxdotnet/src/test/java/org/jclouds/boxdotnet/BoxDotNetAsyncClientTest.java b/sandbox/boxdotnet/src/test/java/org/jclouds/boxdotnet/BoxDotNetAsyncClientTest.java similarity index 100% rename from boxdotnet/src/test/java/org/jclouds/boxdotnet/BoxDotNetAsyncClientTest.java rename to sandbox/boxdotnet/src/test/java/org/jclouds/boxdotnet/BoxDotNetAsyncClientTest.java diff --git a/boxdotnet/src/test/java/org/jclouds/boxdotnet/BoxDotNetClientLiveTest.java b/sandbox/boxdotnet/src/test/java/org/jclouds/boxdotnet/BoxDotNetClientLiveTest.java similarity index 100% rename from boxdotnet/src/test/java/org/jclouds/boxdotnet/BoxDotNetClientLiveTest.java rename to sandbox/boxdotnet/src/test/java/org/jclouds/boxdotnet/BoxDotNetClientLiveTest.java diff --git a/boxdotnet/src/test/resources/log4j.xml b/sandbox/boxdotnet/src/test/resources/log4j.xml similarity index 100% rename from boxdotnet/src/test/resources/log4j.xml rename to sandbox/boxdotnet/src/test/resources/log4j.xml diff --git a/aws/extensions/jets3t/README.txt b/sandbox/jets3t/README.txt similarity index 100% rename from aws/extensions/jets3t/README.txt rename to sandbox/jets3t/README.txt diff --git a/aws/extensions/jets3t/pom.xml b/sandbox/jets3t/pom.xml similarity index 100% rename from aws/extensions/jets3t/pom.xml rename to sandbox/jets3t/pom.xml diff --git a/aws/extensions/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/JCloudsS3Service.java b/sandbox/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/JCloudsS3Service.java similarity index 100% rename from aws/extensions/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/JCloudsS3Service.java rename to sandbox/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/JCloudsS3Service.java diff --git a/aws/extensions/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/Util.java b/sandbox/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/Util.java similarity index 100% rename from aws/extensions/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/Util.java rename to sandbox/jets3t/src/main/java/org/jclouds/aws/s3/jets3t/Util.java diff --git a/aws/extensions/jets3t/src/test/java/org/jclouds/aws/s3/jets3t/JCloudsS3ServiceLiveTest.java b/sandbox/jets3t/src/test/java/org/jclouds/aws/s3/jets3t/JCloudsS3ServiceLiveTest.java similarity index 100% rename from aws/extensions/jets3t/src/test/java/org/jclouds/aws/s3/jets3t/JCloudsS3ServiceLiveTest.java rename to sandbox/jets3t/src/test/java/org/jclouds/aws/s3/jets3t/JCloudsS3ServiceLiveTest.java diff --git a/mezeo/pcs2/core/.gitignore b/sandbox/mezeo/pcs2/core/.gitignore similarity index 100% rename from mezeo/pcs2/core/.gitignore rename to sandbox/mezeo/pcs2/core/.gitignore diff --git a/mezeo/pcs2/core/README.txt b/sandbox/mezeo/pcs2/core/README.txt similarity index 100% rename from mezeo/pcs2/core/README.txt rename to sandbox/mezeo/pcs2/core/README.txt diff --git a/mezeo/pcs2/core/pom.xml b/sandbox/mezeo/pcs2/core/pom.xml similarity index 100% rename from mezeo/pcs2/core/pom.xml rename to sandbox/mezeo/pcs2/core/pom.xml diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSAsyncClient.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSAsyncClient.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSAsyncClient.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSAsyncClient.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSClient.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSClient.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSClient.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSClient.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSCloudAsyncClient.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSCloudAsyncClient.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSCloudAsyncClient.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSCloudAsyncClient.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSContextBuilder.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSContextBuilder.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSContextBuilder.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/PCSContextBuilder.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayload.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayload.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayload.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayload.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayload.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayload.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayload.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayload.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindPCSFileToMultipartForm.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindPCSFileToMultipartForm.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindPCSFileToMultipartForm.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/binders/BindPCSFileToMultipartForm.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToFileInfo.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToFileInfo.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToFileInfo.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToFileInfo.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToPCSFile.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToPCSFile.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToPCSFile.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/BlobToPCSFile.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/FileInfoToBlobMetadata.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/FileInfoToBlobMetadata.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/FileInfoToBlobMetadata.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/FileInfoToBlobMetadata.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/PCSFileToBlob.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/PCSFileToBlob.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/PCSFileToBlob.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/blobstore/functions/PCSFileToBlob.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSObjectModule.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSObjectModule.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSObjectModule.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSObjectModule.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSRestClientModule.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSRestClientModule.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSRestClientModule.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/config/PCSRestClientModule.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerInfo.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerInfo.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerInfo.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerInfo.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerList.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerList.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerList.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ContainerList.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfo.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfo.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfo.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfo.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfoWithMetadata.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfoWithMetadata.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfoWithMetadata.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/FileInfoWithMetadata.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableFileInfo.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableFileInfo.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableFileInfo.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableFileInfo.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableResourceInfo.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableResourceInfo.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableResourceInfo.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/MutableResourceInfo.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/PCSFile.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/PCSFile.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/PCSFile.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/PCSFile.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ResourceInfo.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ResourceInfo.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ResourceInfo.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/ResourceInfo.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerInfoImpl.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerInfoImpl.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerInfoImpl.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerInfoImpl.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerListImpl.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerListImpl.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerListImpl.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ContainerListImpl.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoImpl.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoImpl.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoImpl.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoImpl.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoWithMetadataImpl.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoWithMetadataImpl.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoWithMetadataImpl.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/FileInfoWithMetadataImpl.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableFileInfoImpl.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableFileInfoImpl.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableFileInfoImpl.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableFileInfoImpl.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableResourceInfoImpl.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableResourceInfoImpl.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableResourceInfoImpl.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/MutableResourceInfoImpl.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/PCSFileImpl.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/PCSFileImpl.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/PCSFileImpl.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/PCSFileImpl.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ResourceInfoImpl.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ResourceInfoImpl.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ResourceInfoImpl.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/domain/internal/ResourceInfoImpl.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Contacts.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Contacts.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Contacts.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Contacts.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Metacontainers.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Metacontainers.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Metacontainers.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Metacontainers.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Projects.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Projects.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Projects.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Projects.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Recyclebin.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Recyclebin.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Recyclebin.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Recyclebin.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/RootContainer.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/RootContainer.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/RootContainer.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/RootContainer.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Shares.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Shares.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Shares.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Shares.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Tags.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Tags.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Tags.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/Tags.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/WebDAV.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/WebDAV.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/WebDAV.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/endpoints/WebDAV.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddMetadataItemIntoMap.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddMetadataItemIntoMap.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddMetadataItemIntoMap.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/AddMetadataItemIntoMap.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnFalseIfContainerNotFound.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnFalseIfContainerNotFound.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnFalseIfContainerNotFound.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnFalseIfContainerNotFound.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnTrueIfContainerAlreadyExists.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnTrueIfContainerAlreadyExists.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnTrueIfContainerAlreadyExists.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/functions/ReturnTrueIfContainerAlreadyExists.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/handlers/PCSClientErrorRetryHandler.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/handlers/PCSClientErrorRetryHandler.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/handlers/PCSClientErrorRetryHandler.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/handlers/PCSClientErrorRetryHandler.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/options/PutBlockOptions.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/options/PutBlockOptions.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/options/PutBlockOptions.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/options/PutBlockOptions.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHandler.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHandler.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHandler.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHandler.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/ContainerHandler.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/ContainerHandler.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/ContainerHandler.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/ContainerHandler.java diff --git a/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/FileHandler.java b/sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/FileHandler.java similarity index 100% rename from mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/FileHandler.java rename to sandbox/mezeo/pcs2/core/src/main/java/org/jclouds/mezeo/pcs2/xml/FileHandler.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSAsyncClientTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSAsyncClientTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSAsyncClientTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSAsyncClientTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSClientLiveTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSClientLiveTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSClientLiveTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSClientLiveTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSCloudTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSCloudTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSCloudTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/PCSCloudTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/ProvidersInPropertiesTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/ProvidersInPropertiesTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/ProvidersInPropertiesTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/ProvidersInPropertiesTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayloadTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayloadTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayloadTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindContainerNameToXmlPayloadTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayloadTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayloadTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayloadTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/binders/BindFileInfoToXmlPayloadTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndReturnIdTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndReturnIdTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndReturnIdTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AddMetadataAndReturnIdTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromBlobMetadataCallTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromBlobMetadataCallTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromBlobMetadataCallTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/functions/AssembleBlobFromBlobMetadataCallTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/internal/StubPCSAsyncClient.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/internal/StubPCSAsyncClient.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/internal/StubPCSAsyncClient.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/internal/StubPCSAsyncClient.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/options/PutBlockOptionsTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/options/PutBlockOptionsTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/options/PutBlockOptionsTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/options/PutBlockOptionsTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHanderTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHanderTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHanderTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/CloudXlinkHanderTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/ContainerHandlerTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/ContainerHandlerTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/ContainerHandlerTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/ContainerHandlerTest.java diff --git a/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/FileMetadataHandlerTest.java b/sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/FileMetadataHandlerTest.java similarity index 100% rename from mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/FileMetadataHandlerTest.java rename to sandbox/mezeo/pcs2/core/src/test/java/org/jclouds/mezeo/pcs2/xml/FileMetadataHandlerTest.java diff --git a/mezeo/pcs2/core/src/test/resources/discovery.xml b/sandbox/mezeo/pcs2/core/src/test/resources/discovery.xml similarity index 100% rename from mezeo/pcs2/core/src/test/resources/discovery.xml rename to sandbox/mezeo/pcs2/core/src/test/resources/discovery.xml diff --git a/mezeo/pcs2/core/src/test/resources/log4j.xml b/sandbox/mezeo/pcs2/core/src/test/resources/log4j.xml similarity index 100% rename from mezeo/pcs2/core/src/test/resources/log4j.xml rename to sandbox/mezeo/pcs2/core/src/test/resources/log4j.xml diff --git a/mezeo/pcs2/core/src/test/resources/test_file_metadata.xml b/sandbox/mezeo/pcs2/core/src/test/resources/test_file_metadata.xml similarity index 100% rename from mezeo/pcs2/core/src/test/resources/test_file_metadata.xml rename to sandbox/mezeo/pcs2/core/src/test/resources/test_file_metadata.xml diff --git a/mezeo/pcs2/core/src/test/resources/test_root_container.xml b/sandbox/mezeo/pcs2/core/src/test/resources/test_root_container.xml similarity index 100% rename from mezeo/pcs2/core/src/test/resources/test_root_container.xml rename to sandbox/mezeo/pcs2/core/src/test/resources/test_root_container.xml diff --git a/mezeo/pcs2/pom.xml b/sandbox/mezeo/pcs2/pom.xml similarity index 100% rename from mezeo/pcs2/pom.xml rename to sandbox/mezeo/pcs2/pom.xml diff --git a/mezeo/pom.xml b/sandbox/mezeo/pom.xml similarity index 100% rename from mezeo/pom.xml rename to sandbox/mezeo/pom.xml diff --git a/nirvanix/pom.xml b/sandbox/nirvanix/pom.xml similarity index 100% rename from nirvanix/pom.xml rename to sandbox/nirvanix/pom.xml diff --git a/nirvanix/sdn/core/.gitignore b/sandbox/nirvanix/sdn/core/.gitignore similarity index 100% rename from nirvanix/sdn/core/.gitignore rename to sandbox/nirvanix/sdn/core/.gitignore diff --git a/nirvanix/sdn/core/README.txt b/sandbox/nirvanix/sdn/core/README.txt similarity index 100% rename from nirvanix/sdn/core/README.txt rename to sandbox/nirvanix/sdn/core/README.txt diff --git a/nirvanix/sdn/core/pom.xml b/sandbox/nirvanix/sdn/core/pom.xml similarity index 100% rename from nirvanix/sdn/core/pom.xml rename to sandbox/nirvanix/sdn/core/pom.xml diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAsyncClient.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAsyncClient.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAsyncClient.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAsyncClient.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClient.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClient.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClient.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClient.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNClient.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNClient.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNClient.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNClient.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNContextBuilder.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNContextBuilder.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNContextBuilder.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNContextBuilder.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNPropertiesBuilder.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNPropertiesBuilder.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNPropertiesBuilder.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SDNPropertiesBuilder.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SessionToken.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SessionToken.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SessionToken.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/SessionToken.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParams.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParams.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParams.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParams.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNAuthRestClientModule.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNAuthRestClientModule.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNAuthRestClientModule.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNAuthRestClientModule.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNRestClientModule.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNRestClientModule.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNRestClientModule.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/config/SDNRestClientModule.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/domain/UploadInfo.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/domain/UploadInfo.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/domain/UploadInfo.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/domain/UploadInfo.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequest.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequest.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequest.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequest.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPath.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPath.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPath.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPath.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponse.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponse.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponse.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponse.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponse.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponse.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponse.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponse.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponse.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponse.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponse.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponse.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNConstants.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNConstants.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNConstants.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNConstants.java diff --git a/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNQueryParams.java b/sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNQueryParams.java similarity index 100% rename from nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNQueryParams.java rename to sandbox/nirvanix/sdn/core/src/main/java/org/jclouds/nirvanix/sdn/reference/SDNQueryParams.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/ProvidersInPropertiesTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/ProvidersInPropertiesTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/ProvidersInPropertiesTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/ProvidersInPropertiesTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAsyncClientTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAsyncClientTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAsyncClientTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAsyncClientTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClientTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClientTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClientTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthAsyncClientTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthenticationLiveTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthenticationLiveTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthenticationLiveTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNAuthenticationLiveTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNClientLiveTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNClientLiveTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNClientLiveTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/SDNClientLiveTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParamsTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParamsTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParamsTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/binders/BindMetadataToQueryParamsTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequestTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequestTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequestTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/AddSessionTokenToRequestTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPathTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPathTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPathTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/filters/InsertUserContextIntoPathTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponseTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponseTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponseTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseMetadataFromJsonResponseTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponseTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponseTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponseTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseSessionTokenFromJsonResponseTest.java diff --git a/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponseTest.java b/sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponseTest.java similarity index 100% rename from nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponseTest.java rename to sandbox/nirvanix/sdn/core/src/test/java/org/jclouds/nirvanix/sdn/functions/ParseUploadInfoFromJsonResponseTest.java diff --git a/nirvanix/sdn/core/src/test/resources/authtoken.json b/sandbox/nirvanix/sdn/core/src/test/resources/authtoken.json similarity index 100% rename from nirvanix/sdn/core/src/test/resources/authtoken.json rename to sandbox/nirvanix/sdn/core/src/test/resources/authtoken.json diff --git a/nirvanix/sdn/core/src/test/resources/log4j.xml b/sandbox/nirvanix/sdn/core/src/test/resources/log4j.xml similarity index 100% rename from nirvanix/sdn/core/src/test/resources/log4j.xml rename to sandbox/nirvanix/sdn/core/src/test/resources/log4j.xml diff --git a/nirvanix/sdn/core/src/test/resources/login.json b/sandbox/nirvanix/sdn/core/src/test/resources/login.json similarity index 100% rename from nirvanix/sdn/core/src/test/resources/login.json rename to sandbox/nirvanix/sdn/core/src/test/resources/login.json diff --git a/nirvanix/sdn/core/src/test/resources/metadata.json b/sandbox/nirvanix/sdn/core/src/test/resources/metadata.json similarity index 100% rename from nirvanix/sdn/core/src/test/resources/metadata.json rename to sandbox/nirvanix/sdn/core/src/test/resources/metadata.json diff --git a/nirvanix/sdn/pom.xml b/sandbox/nirvanix/sdn/pom.xml similarity index 100% rename from nirvanix/sdn/pom.xml rename to sandbox/nirvanix/sdn/pom.xml From 4c0fc5d0e0c9bd1462efcfd7bcb379e90418ec1b Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Wed, 8 Sep 2010 18:53:38 -0700 Subject: [PATCH 28/63] Issue 176: remove interim vcloud express support --- core/src/main/resources/rest.properties | 3 - .../build.properties.bluelock-vcloudexpress | 5 - .../cargooverssh/build.properties.ibmdev | 5 - .../antcontrib/samples/cargooverssh/build.xml | 2 +- .../build.properties.bluelock-vcloudexpress | 5 - .../samples/compute/build.properties.ibmdev | 5 - tools/antcontrib/samples/compute/build.xml | 2 +- vcloud/bluelock/README.txt | 2 +- vcloud/bluelock/pom.xml | 20 ---- .../BlueLockVCloudExpressContextBuilder.java | 63 ---------- ...lueLockVCloudExpressPropertiesBuilder.java | 46 -------- .../BlueLockVCloudExpressComputeClient.java | 63 ---------- ...oudExpressComputeServiceContextModule.java | 57 --------- .../suppliers/ParseSizeFromImageSupplier.java | 111 ------------------ .../BlueLockVCloudImageForVAppTemplate.java | 47 -------- ...efaultLoginCredentialsFromBlueLockFAQ.java | 57 --------- ...BlueLockVCloudExpressRestClientModule.java | 60 ---------- .../BlueLockVCloudExpressClientLiveTest.java | 54 --------- .../bluelock/ProvidersInPropertiesTest.java | 2 - ...ckVCloudExpressComputeServiceLiveTest.java | 70 ----------- 20 files changed, 3 insertions(+), 676 deletions(-) delete mode 100644 tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vcloudexpress delete mode 100644 tools/antcontrib/samples/cargooverssh/build.properties.ibmdev delete mode 100644 tools/antcontrib/samples/compute/build.properties.bluelock-vcloudexpress delete mode 100644 tools/antcontrib/samples/compute/build.properties.ibmdev delete mode 100644 vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressContextBuilder.java delete mode 100644 vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressPropertiesBuilder.java delete mode 100644 vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudExpressComputeClient.java delete mode 100644 vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/config/BlueLockVCloudExpressComputeServiceContextModule.java delete mode 100644 vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/config/suppliers/ParseSizeFromImageSupplier.java delete mode 100644 vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/functions/BlueLockVCloudImageForVAppTemplate.java delete mode 100644 vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/strategy/DefaultLoginCredentialsFromBlueLockFAQ.java delete mode 100644 vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/config/BlueLockVCloudExpressRestClientModule.java delete mode 100644 vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressClientLiveTest.java delete mode 100644 vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudExpressComputeServiceLiveTest.java diff --git a/core/src/main/resources/rest.properties b/core/src/main/resources/rest.properties index 520c44adc7..c65c3b11bd 100644 --- a/core/src/main/resources/rest.properties +++ b/core/src/main/resources/rest.properties @@ -83,9 +83,6 @@ cloudservers.propertiesbuilder=org.jclouds.rackspace.RackspacePropertiesBuilder bluelock-vclouddirector.contextbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudDirectorContextBuilder bluelock-vclouddirector.propertiesbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudDirectorPropertiesBuilder -bluelock-vcloudexpress.contextbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudExpressContextBuilder -bluelock-vcloudexpress.propertiesbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudExpressPropertiesBuilder - gogrid.propertiesbuilder=org.jclouds.gogrid.GoGridPropertiesBuilder gogrid.contextbuilder=org.jclouds.gogrid.GoGridContextBuilder diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vcloudexpress b/tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vcloudexpress deleted file mode 100644 index 3103999af4..0000000000 --- a/tools/antcontrib/samples/cargooverssh/build.properties.bluelock-vcloudexpress +++ /dev/null @@ -1,5 +0,0 @@ -provider=bluelock-vcloudexpress -driver=bluelock -identity=user@youregistered.com -credential=password -tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/cargooverssh/build.properties.ibmdev b/tools/antcontrib/samples/cargooverssh/build.properties.ibmdev deleted file mode 100644 index 8e3e7b5b9d..0000000000 --- a/tools/antcontrib/samples/cargooverssh/build.properties.ibmdev +++ /dev/null @@ -1,5 +0,0 @@ -provider=ibmdev -driver=ibmdev -identity=user@youregistered.com -credential=password -tag=name_of_your_server diff --git a/tools/antcontrib/samples/cargooverssh/build.xml b/tools/antcontrib/samples/cargooverssh/build.xml index 042c67636c..05e0294846 100644 --- a/tools/antcontrib/samples/cargooverssh/build.xml +++ b/tools/antcontrib/samples/cargooverssh/build.xml @@ -38,7 +38,7 @@ diff --git a/tools/antcontrib/samples/compute/build.properties.bluelock-vcloudexpress b/tools/antcontrib/samples/compute/build.properties.bluelock-vcloudexpress deleted file mode 100644 index 3103999af4..0000000000 --- a/tools/antcontrib/samples/compute/build.properties.bluelock-vcloudexpress +++ /dev/null @@ -1,5 +0,0 @@ -provider=bluelock-vcloudexpress -driver=bluelock -identity=user@youregistered.com -credential=password -tag=name_of_your_vapp diff --git a/tools/antcontrib/samples/compute/build.properties.ibmdev b/tools/antcontrib/samples/compute/build.properties.ibmdev deleted file mode 100644 index 8e3e7b5b9d..0000000000 --- a/tools/antcontrib/samples/compute/build.properties.ibmdev +++ /dev/null @@ -1,5 +0,0 @@ -provider=ibmdev -driver=ibmdev -identity=user@youregistered.com -credential=password -tag=name_of_your_server diff --git a/tools/antcontrib/samples/compute/build.xml b/tools/antcontrib/samples/compute/build.xml index a188b60483..b914b1456d 100644 --- a/tools/antcontrib/samples/compute/build.xml +++ b/tools/antcontrib/samples/compute/build.xml @@ -31,7 +31,7 @@ diff --git a/vcloud/bluelock/README.txt b/vcloud/bluelock/README.txt index 4b8c0dfbcc..3eb7e8335e 100644 --- a/vcloud/bluelock/README.txt +++ b/vcloud/bluelock/README.txt @@ -18,7 +18,7 @@ ==== # -# The jclouds provider for Hosting.com's vCloud Express (http://www.bluelock/vcloudexpress/) platform. +# The jclouds provider for BlueLock's vCloud Director platform. # # TODO: Implementation status. # TODO: Supported features. diff --git a/vcloud/bluelock/pom.xml b/vcloud/bluelock/pom.xml index 4794df66f5..234dfe213f 100644 --- a/vcloud/bluelock/pom.xml +++ b/vcloud/bluelock/pom.xml @@ -35,10 +35,6 @@ - https://express.bluelock.com/api - 0.8 - FIXME - FIXME https://vcenterprise.bluelock.com/api 1.0 FIXME @@ -82,22 +78,6 @@ - - bluelock-vcloudexpress.endpoint - ${bluelock-vcloudexpress.endpoint} - - - bluelock-vcloudexpress.apiversion - ${bluelock-vcloudexpress.apiversion} - - - bluelock-vcloudexpress.identity - ${bluelock-vcloudexpress.identity} - - - bluelock-vcloudexpress.credential - ${bluelock-vcloudexpress.credential} - bluelock-vclouddirector.endpoint ${bluelock-vclouddirector.endpoint} diff --git a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressContextBuilder.java b/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressContextBuilder.java deleted file mode 100644 index 7dd776267c..0000000000 --- a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressContextBuilder.java +++ /dev/null @@ -1,63 +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.vcloud.bluelock; - -import java.util.List; -import java.util.Properties; - -import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; -import org.jclouds.logging.jdk.config.JDKLoggingModule; -import org.jclouds.vcloud.VCloudExpressContextBuilder; -import org.jclouds.vcloud.bluelock.compute.config.BlueLockVCloudExpressComputeServiceContextModule; -import org.jclouds.vcloud.bluelock.config.BlueLockVCloudExpressRestClientModule; - -import com.google.inject.Injector; -import com.google.inject.Module; - -/** - * Creates {@link BlueLockVCloudComputeServiceContext} or {@link Injector} instances based on the - * most commonly requested arguments. - *

- * Note that Threadsafe objects will be bound as singletons to the Injector or Context provided. - *

- *

- * If no Modules are specified, the default {@link JDKLoggingModule logging} and - * {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed. - * - * @author Adrian Cole - * @see BlueLockVCloudComputeServiceContext - */ -public class BlueLockVCloudExpressContextBuilder extends VCloudExpressContextBuilder { - - public BlueLockVCloudExpressContextBuilder(Properties props) { - super(props); - } - - @Override - protected void addContextModule(List modules) { - modules.add(new BlueLockVCloudExpressComputeServiceContextModule()); - } - - @Override - protected void addClientModule(List modules) { - modules.add(new BlueLockVCloudExpressRestClientModule()); - } - -} diff --git a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressPropertiesBuilder.java b/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressPropertiesBuilder.java deleted file mode 100644 index c8a5e99529..0000000000 --- a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressPropertiesBuilder.java +++ /dev/null @@ -1,46 +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.vcloud.bluelock; - -import static org.jclouds.Constants.PROPERTY_ENDPOINT; -import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_NETWORK; - -import java.util.Properties; - -import org.jclouds.vcloud.VCloudExpressPropertiesBuilder; - -/** - * Builds properties used in bluelock VCloud Clients - * - * @author Adrian Cole - */ -public class BlueLockVCloudExpressPropertiesBuilder extends VCloudExpressPropertiesBuilder { - @Override - protected Properties defaultProperties() { - Properties properties = super.defaultProperties(); - properties.setProperty(PROPERTY_ENDPOINT, "https://express.bluelock.com/api"); - properties.setProperty(PROPERTY_VCLOUD_DEFAULT_NETWORK, "Internal In and Out"); - return properties; - } - - public BlueLockVCloudExpressPropertiesBuilder(Properties properties) { - super(properties); - } -} diff --git a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudExpressComputeClient.java b/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudExpressComputeClient.java deleted file mode 100644 index c12cc1247b..0000000000 --- a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudExpressComputeClient.java +++ /dev/null @@ -1,63 +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.vcloud.bluelock.compute; - -import java.net.URI; -import java.util.Map; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import org.jclouds.compute.domain.NodeState; -import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; -import org.jclouds.domain.Credentials; -import org.jclouds.vcloud.VCloudExpressClient; -import org.jclouds.vcloud.compute.internal.VCloudExpressComputeClientImpl; -import org.jclouds.vcloud.domain.Status; -import org.jclouds.vcloud.domain.VCloudExpressVApp; -import org.jclouds.vcloud.domain.VCloudExpressVAppTemplate; - -import com.google.common.base.Predicate; - -/** - * @author Adrian Cole - */ -@Singleton -public class BlueLockVCloudExpressComputeClient extends VCloudExpressComputeClientImpl { - private final PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider; - - @Inject - protected BlueLockVCloudExpressComputeClient(PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider, - VCloudExpressClient client, Predicate successTester, Map vAppStatusToNodeState) { - super(client, successTester, vAppStatusToNodeState); - this.credentialsProvider = credentialsProvider; - } - - @Override - protected Map parseAndValidateResponse(VCloudExpressVAppTemplate template, - VCloudExpressVApp vAppResponse) { - Credentials credentials = credentialsProvider.execute(template); - Map toReturn = super.parseResponse(template, vAppResponse); - toReturn.put("username", credentials.identity); - toReturn.put("password", credentials.credential); - return toReturn; - } - -} \ No newline at end of file diff --git a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/config/BlueLockVCloudExpressComputeServiceContextModule.java b/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/config/BlueLockVCloudExpressComputeServiceContextModule.java deleted file mode 100644 index 702b52c8b3..0000000000 --- a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/config/BlueLockVCloudExpressComputeServiceContextModule.java +++ /dev/null @@ -1,57 +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.vcloud.bluelock.compute.config; - -import java.util.Set; - -import org.jclouds.compute.domain.Size; -import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; -import org.jclouds.vcloud.bluelock.compute.BlueLockVCloudExpressComputeClient; -import org.jclouds.vcloud.bluelock.compute.config.suppliers.ParseSizeFromImageSupplier; -import org.jclouds.vcloud.bluelock.compute.functions.BlueLockVCloudImageForVAppTemplate; -import org.jclouds.vcloud.bluelock.compute.strategy.DefaultLoginCredentialsFromBlueLockFAQ; -import org.jclouds.vcloud.compute.VCloudExpressComputeClient; -import org.jclouds.vcloud.compute.config.VCloudExpressComputeServiceContextModule; -import org.jclouds.vcloud.compute.functions.ImageForVCloudExpressVAppTemplate; - -import com.google.common.base.Supplier; -import com.google.inject.Injector; - -/** - * Configures the {@link BlueLockVCloudComputeServiceContext}; requires - * {@link BlueLockVCloudExpressComputeClient} bound. - * - * @author Adrian Cole - */ -public class BlueLockVCloudExpressComputeServiceContextModule extends VCloudExpressComputeServiceContextModule { - - @Override - protected void configure() { - super.configure(); - bind(ImageForVCloudExpressVAppTemplate.class).to(BlueLockVCloudImageForVAppTemplate.class); - bind(VCloudExpressComputeClient.class).to(BlueLockVCloudExpressComputeClient.class); - bind(PopulateDefaultLoginCredentialsForImageStrategy.class).to(DefaultLoginCredentialsFromBlueLockFAQ.class); - } - - @Override - protected Supplier> getSourceSizeSupplier(Injector injector) { - return injector.getInstance(ParseSizeFromImageSupplier.class); - } -} diff --git a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/config/suppliers/ParseSizeFromImageSupplier.java b/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/config/suppliers/ParseSizeFromImageSupplier.java deleted file mode 100644 index c144b5d31a..0000000000 --- a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/config/suppliers/ParseSizeFromImageSupplier.java +++ /dev/null @@ -1,111 +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.vcloud.bluelock.compute.config.suppliers; - -import static com.google.common.collect.Iterables.filter; -import static com.google.common.collect.Iterables.transform; -import static com.google.common.collect.Sets.newLinkedHashSet; - -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.domain.Size; -import org.jclouds.compute.domain.internal.SizeImpl; -import org.jclouds.compute.predicates.ImagePredicates; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.logging.Logger; -import org.jclouds.vcloud.compute.domain.VCloudExpressImage; -import org.jclouds.vcloud.domain.VCloudExpressVAppTemplate; - -import com.google.common.base.Function; -import com.google.common.base.Predicates; -import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableMap; - -/** - * @author Adrian Cole - */ -@Singleton -public class ParseSizeFromImageSupplier implements Supplier> { - // ex Ubuntu904Serverx64 1CPUx16GBx20GB - public static final Pattern GBRAM_PATTERN = Pattern.compile("[^ ] ([0-9]+)CPUx([0-9]+)GBx([0-9]+)GB"); - - // ex Windows2008stdx64 1CPUx512MBx30GB - public static final Pattern MBRAM_PATTERN = Pattern.compile("[^ ] ([0-9]+)CPUx([0-9]+)MBx([0-9]+)GB"); - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - public Logger logger = Logger.NULL; - - private final Supplier> images; - - @Inject - ParseSizeFromImageSupplier(Supplier> images) { - this.images = images; - } - - @Override - public Set get() { - - return newLinkedHashSet(filter(transform(images.get(), new Function() { - - @Override - public Size apply(Image from) { - try { - VCloudExpressVAppTemplate template = VCloudExpressImage.class.cast(from).getVAppTemplate(); - Matcher matcher = getMatcherAndFind(template.getName()); - double cores = Double.parseDouble(matcher.group(1)); - int ram = Integer.parseInt(matcher.group(2)); - if (matcher.pattern().equals(GBRAM_PATTERN)) - ram *= 1024; - int disk = Integer.parseInt(matcher.group(3)); - String name = template.getName().split(" ")[1]; - return new SizeImpl(from.getId(), name, from.getId(), from.getLocation(), null, ImmutableMap - . of(), cores, ram, disk, ImagePredicates.idEquals(from.getId())); - } catch (NoSuchElementException e) { - logger.debug("<< didn't match at all(%s)", from); - return null; - } - } - }), Predicates.notNull())); - } - - /** - * - * @throws NoSuchElementException - * if no configured matcher matches the name. - */ - private Matcher getMatcherAndFind(String name) { - for (Pattern pattern : new Pattern[] { GBRAM_PATTERN, MBRAM_PATTERN }) { - Matcher matcher = pattern.matcher(name); - if (matcher.find()) - return matcher; - } - throw new NoSuchElementException(name); - } -} \ No newline at end of file diff --git a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/functions/BlueLockVCloudImageForVAppTemplate.java b/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/functions/BlueLockVCloudImageForVAppTemplate.java deleted file mode 100644 index f6bc9c1b87..0000000000 --- a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/functions/BlueLockVCloudImageForVAppTemplate.java +++ /dev/null @@ -1,47 +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.vcloud.bluelock.compute.functions; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; -import org.jclouds.vcloud.compute.functions.FindLocationForResource; -import org.jclouds.vcloud.compute.functions.ImageForVCloudExpressVAppTemplate; - -/** - * - * @author Adrian Cole - */ -@Singleton -public class BlueLockVCloudImageForVAppTemplate extends ImageForVCloudExpressVAppTemplate { - - @Inject - protected BlueLockVCloudImageForVAppTemplate(FindLocationForResource findLocationForResource, - PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider) { - super(findLocationForResource, credentialsProvider); - } - - // Extremely important, as otherwise the size encoded into the name will throw off the - // template matching, accidentally choosing the largest size by default - protected String getName(String name) { - return name.split(" ")[0]; - } -} \ No newline at end of file diff --git a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/strategy/DefaultLoginCredentialsFromBlueLockFAQ.java b/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/strategy/DefaultLoginCredentialsFromBlueLockFAQ.java deleted file mode 100644 index 4c60e0f867..0000000000 --- a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/compute/strategy/DefaultLoginCredentialsFromBlueLockFAQ.java +++ /dev/null @@ -1,57 +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.vcloud.bluelock.compute.strategy; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import javax.inject.Singleton; - -import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; -import org.jclouds.domain.Credentials; -import org.jclouds.vcloud.domain.VCloudExpressVAppTemplate; - -/** - * - * from https://forums.bluelock.com/faq.php?faq=vcloudexpressfaq - * - * @author Adrian Cole - * - */ -@Singleton -public class DefaultLoginCredentialsFromBlueLockFAQ implements PopulateDefaultLoginCredentialsForImageStrategy { - - @Override - public Credentials execute(Object resourceToAuthenticate) { - checkNotNull(resourceToAuthenticate); - checkArgument(resourceToAuthenticate instanceof VCloudExpressVAppTemplate, - "Resource must be an VCloudExpressVAppTemplate (for Bluelock vCloud Express)"); - VCloudExpressVAppTemplate template = (VCloudExpressVAppTemplate) resourceToAuthenticate; - if (template.getDescription().indexOf("Windows") >= 0) { - return new Credentials("expressuser", "ExpressPassword#1"); - } else { - if (template.getDescription().indexOf("buntu") != -1) { - return new Credentials("express", "ExpressPassword#1"); - } else { - return new Credentials("root", "ExpressPassword#1"); - } - } - } -} diff --git a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/config/BlueLockVCloudExpressRestClientModule.java b/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/config/BlueLockVCloudExpressRestClientModule.java deleted file mode 100644 index d5e09048cc..0000000000 --- a/vcloud/bluelock/src/main/java/org/jclouds/vcloud/bluelock/config/BlueLockVCloudExpressRestClientModule.java +++ /dev/null @@ -1,60 +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.vcloud.bluelock.config; - -import static com.google.common.base.Preconditions.checkState; -import static org.jclouds.Constants.PROPERTY_IDENTITY; - -import java.net.URI; - -import javax.inject.Named; - -import org.jclouds.http.RequiresHttp; -import org.jclouds.rest.ConfiguresRestClient; -import org.jclouds.vcloud.config.VCloudExpressRestClientModule; -import org.jclouds.vcloud.domain.Org; -import org.jclouds.vcloud.domain.ReferenceType; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; - -/** - * Configures the VCloud authentication service connection, including logging and http transport. - * - * @author Adrian Cole - */ -@RequiresHttp -@ConfiguresRestClient -public class BlueLockVCloudExpressRestClientModule extends VCloudExpressRestClientModule { - - - @Override - protected URI provideCatalog(Org org, @Named(PROPERTY_IDENTITY) final String user) { - checkState(org.getCatalogs().size() > 0, "No catalogs present in org: " + org.getName()); - return Iterables.getOnlyElement(Iterables.filter(org.getCatalogs().values(), new Predicate() { - - @Override - public boolean apply(ReferenceType input) { - return input.getName().startsWith(user); - } - - })).getHref(); - } -} diff --git a/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressClientLiveTest.java b/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressClientLiveTest.java deleted file mode 100644 index 0b6412b02f..0000000000 --- a/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/BlueLockVCloudExpressClientLiveTest.java +++ /dev/null @@ -1,54 +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.vcloud.bluelock; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Properties; - -import org.jclouds.compute.ComputeServiceContextFactory; -import org.jclouds.logging.log4j.config.Log4JLoggingModule; -import org.jclouds.vcloud.VCloudExpressClientLiveTest; -import org.testng.annotations.BeforeGroups; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableSet; -import com.google.inject.Module; - -/** - * Tests behavior of {@code BlueLockVCloudClient} - * - * @author Adrian Cole - */ -@Test(groups = "live", sequential = true, testName = "vcloud.BlueLockVCloudClientLiveTest") -public class BlueLockVCloudExpressClientLiveTest extends VCloudExpressClientLiveTest { - - @BeforeGroups(groups = { "live" }) - @Override - public void setupClient() { - identity = checkNotNull(System.getProperty("bluelock-vcloudexpress.identity"), "bluelock-vcloudexpress.identity"); - String credential = checkNotNull(System.getProperty("bluelock-vcloudexpress.credential"), - "bluelock-vcloudexpress.credential"); - context = new ComputeServiceContextFactory().createContext("bluelock-vcloudexpress", identity, credential, - ImmutableSet. of(new Log4JLoggingModule()), new Properties()).getProviderSpecificContext(); - connection = context.getApi(); - } - -} diff --git a/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/ProvidersInPropertiesTest.java b/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/ProvidersInPropertiesTest.java index 67e6511e09..cf2f3367a1 100644 --- a/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/ProvidersInPropertiesTest.java +++ b/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/ProvidersInPropertiesTest.java @@ -36,7 +36,6 @@ public class ProvidersInPropertiesTest { @Test public void testSupportedProviders() { Iterable providers = Utils.getSupportedProviders(); - assert Iterables.contains(providers, "bluelock-vcloudexpress") : providers; assert Iterables.contains(providers, "bluelock-vclouddirector") : providers; } @@ -44,7 +43,6 @@ public class ProvidersInPropertiesTest { @Test public void testSupportedComputeServiceProviders() { Iterable providers = ComputeServiceUtils.getSupportedProviders(); - assert Iterables.contains(providers, "bluelock-vcloudexpress") : providers; assert Iterables.contains(providers, "bluelock-vclouddirector") : providers; } diff --git a/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudExpressComputeServiceLiveTest.java b/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudExpressComputeServiceLiveTest.java deleted file mode 100644 index 4b0d1ef294..0000000000 --- a/vcloud/bluelock/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudExpressComputeServiceLiveTest.java +++ /dev/null @@ -1,70 +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.vcloud.bluelock.compute; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.testng.Assert.assertEquals; - -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.domain.TemplateBuilder; -import org.jclouds.vcloud.compute.VCloudExpressComputeServiceLiveTest; -import org.testng.annotations.Test; - -/** - * - * - * @author Adrian Cole - */ -@Test(groups = "live", enabled = true, sequential = true, testName = "bluelock.BlueLockVCloudExpressComputeServiceLiveTest") -public class BlueLockVCloudExpressComputeServiceLiveTest extends VCloudExpressComputeServiceLiveTest { - @Override - public void setServiceDefaults() { - provider = "bluelock-vcloudexpress"; - tag = "vcx"; - } - - @Override - protected void setupCredentials() { - identity = checkNotNull(System.getProperty("bluelock-vcloudexpress.identity"), "bluelock-vcloudexpress.identity"); - credential = checkNotNull(System.getProperty("bluelock-vcloudexpress.credential"), - "bluelock-vcloudexpress.credential"); - } - - @Test - public void testTemplateBuilder() { - Template defaultTemplate = client.templateBuilder().build(); - assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); - assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); - assertEquals(defaultTemplate.getLocation().getId(), "https://express3.bluelock.com/api/v0.8/vdc/133"); - assertEquals(defaultTemplate.getSize().getCores(), 1.0d); - } - - @Override - protected Template buildTemplate(TemplateBuilder templateBuilder) { - Template template = super.buildTemplate(templateBuilder); - Image image = template.getImage(); - assert image.getDefaultCredentials().identity != null : image; - assert image.getDefaultCredentials().credential != null : image; - return template; - } - -} From ef1c57509a82775f0c8950ed658f3c4f5388daa9 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Thu, 9 Sep 2010 12:44:14 -0700 Subject: [PATCH 29/63] Issue 342: preparation for ssl testing --- core/pom.xml | 2 +- extensions/apachehc/pom.xml | 2 +- extensions/enterprise/pom.xml | 2 +- project/pom.xml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index d91bcb3547..e1dce7b633 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -92,7 +92,7 @@ org.mortbay.jetty - jetty + jetty-ssl test diff --git a/extensions/apachehc/pom.xml b/extensions/apachehc/pom.xml index 77b2176d26..302c8a5f3e 100644 --- a/extensions/apachehc/pom.xml +++ b/extensions/apachehc/pom.xml @@ -46,7 +46,7 @@ org.mortbay.jetty - jetty + jetty-ssl test diff --git a/extensions/enterprise/pom.xml b/extensions/enterprise/pom.xml index a5942dcfb2..8ffe1d38aa 100644 --- a/extensions/enterprise/pom.xml +++ b/extensions/enterprise/pom.xml @@ -44,7 +44,7 @@ org.mortbay.jetty - jetty + jetty-ssl test diff --git a/project/pom.xml b/project/pom.xml index 2909909cbf..a77876b27e 100644 --- a/project/pom.xml +++ b/project/pom.xml @@ -230,8 +230,8 @@ org.mortbay.jetty - jetty - 7.0.0pre3 + jetty-ssl + 7.0.0.pre5 From 2b682c5dbbed35f5c1ff65284a825fab3090949c Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Thu, 9 Sep 2010 12:44:42 -0700 Subject: [PATCH 30/63] Issue 345: added t1 micro instance and made it the default instance size in ec2 --- .../EC2ComputeServiceContextModule.java | 4 +- .../aws/ec2/compute/domain/EC2Size.java | 37 ++++++++++++++ .../ec2/compute/functions/ImageParser.java | 3 +- .../compute/suppliers/EC2SizeSupplier.java | 4 +- .../jclouds/aws/ec2/domain/InstanceType.java | 10 ++++ .../aws/ec2/domain/RootDeviceType.java | 4 ++ .../compute/EC2ComputeServiceLiveTest.java | 2 +- .../ec2/compute/EC2ComputeServiceTest.java | 4 +- .../compute/EC2TemplateBuilderLiveTest.java | 26 +++++++++- .../compute/functions/ImageParserTest.java | 51 +++++++++++++++---- .../test/resources/ec2/alestic_canonical.xml | 24 +++++++++ .../compute/domain/TemplateBuilder.java | 6 +-- .../compute/BaseComputeServiceLiveTest.java | 2 +- 13 files changed, 153 insertions(+), 24 deletions(-) diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java index 283a1b6f92..5bd736b07c 100755 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java @@ -169,8 +169,8 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod @Override protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) { String region = injector.getInstance(Key.get(String.class, Region.class)); - return "Eucalyptus".equals(region) ? template.osFamily(CENTOS).smallest() : template.os64Bit(false).osFamily( - UBUNTU).osVersionMatches(".*10\\.?04.*").osDescriptionMatches("^ubuntu-images.*"); + return "Eucalyptus".equals(region) ? template.osFamily(CENTOS).smallest() : template.osFamily( + UBUNTU).osVersionMatches("10.04").os64Bit(true).osDescriptionMatches(".*ubuntu-images.*"); } @Provides diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/domain/EC2Size.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/domain/EC2Size.java index 6b1b7957dc..5dc7e56222 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/domain/EC2Size.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/domain/EC2Size.java @@ -19,6 +19,7 @@ package org.jclouds.aws.ec2.compute.domain; +import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Predicates.not; import static org.jclouds.compute.predicates.ImagePredicates.idIn; import static org.jclouds.compute.predicates.ImagePredicates.is64Bit; @@ -26,9 +27,12 @@ import static org.jclouds.compute.predicates.ImagePredicates.is64Bit; import java.util.Arrays; import org.jclouds.aws.ec2.domain.InstanceType; +import org.jclouds.aws.ec2.domain.RootDeviceType; +import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.internal.SizeImpl; import org.jclouds.domain.Location; +import com.google.common.base.Predicate; import com.google.common.collect.ImmutableMap; /** @@ -40,6 +44,34 @@ public class EC2Size extends SizeImpl { private static final long serialVersionUID = 8605688733788974797L; private final String instanceType; + /** + * evaluates true if the Image has the following rootDeviceType + * + * @param type + * rootDeviceType of the image + * @return predicate + */ + public static Predicate hasRootDeviceType(final RootDeviceType type) { + checkNotNull(type, "type must be defined"); + return new Predicate() { + @Override + public boolean apply(Image image) { + return type.toString().equals(image.getUserMetadata().get("rootDeviceType")); + } + + @Override + public String toString() { + return "hasRootDeviceType(" + type + ")"; + } + }; + } + + EC2Size(String instanceType, Double cores, Integer ram, Integer disk, RootDeviceType rootDeviceType) { + super(instanceType, instanceType, instanceType, null, null, ImmutableMap. of(), cores, ram, disk, + hasRootDeviceType(rootDeviceType)); + this.instanceType = instanceType; + } + EC2Size(String instanceType, Double cores, Integer ram, Integer disk, boolean is64Bit) { super(instanceType, instanceType, instanceType, null, null, ImmutableMap. of(), cores, ram, disk, is64Bit ? is64Bit() : not(is64Bit())); @@ -59,10 +91,15 @@ public class EC2Size extends SizeImpl { return instanceType; } + /** * @see InstanceType#M1_SMALL */ public static final EC2Size M1_SMALL = new EC2Size(InstanceType.M1_SMALL, 1.0, 1740, 160, false); + /** + * @see InstanceType#T1_MICRO + */ + public static final EC2Size T1_MICRO = new EC2Size(InstanceType.T1_MICRO, 1.0, 630, 0, RootDeviceType.EBS); /** * @see InstanceType#M1_LARGE */ diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/ImageParser.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/ImageParser.java index 5fb2d1103e..0b1238d78e 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/ImageParser.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/ImageParser.java @@ -136,7 +136,8 @@ public class ImageParser implements Function of("owner", from.getImageOwnerId()), os, description, version, defaultCredentials); + . of("owner", from.getImageOwnerId(), "rootDeviceType", from.getRootDeviceType() + .toString()), os, description, version, defaultCredentials); } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/suppliers/EC2SizeSupplier.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/suppliers/EC2SizeSupplier.java index 68a43d5849..b39f8aa386 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/suppliers/EC2SizeSupplier.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/suppliers/EC2SizeSupplier.java @@ -75,8 +75,8 @@ public class EC2SizeSupplier implements Supplier> { }); sizes.add(new EC2Size(location, InstanceType.CC1_4XLARGE, 33.5, 23 * 1024, 1690, ccAmis)); } - sizes.addAll(ImmutableSet. of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE, EC2Size.M1_SMALL, - EC2Size.M1_XLARGE, EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE)); + sizes.addAll(ImmutableSet. of(EC2Size.T1_MICRO, EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE, + EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE)); return sizes; } } \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/domain/InstanceType.java b/aws/core/src/main/java/org/jclouds/aws/ec2/domain/InstanceType.java index 40eecd2257..6c7e203e5c 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/domain/InstanceType.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/domain/InstanceType.java @@ -32,6 +32,16 @@ import org.jclouds.aws.ec2.EC2AsyncClient; * */ public class InstanceType { + /** + * Micro Instance + *

    + *
  • 613 MB of memory
  • + *
  • up to 2 ECUs (for short periodic bursts)
  • + *
  • No instance storage (EBS storage only)
  • + *
  • 32-bit or 64-bit platform
  • + *
+ */ + public static final String T1_MICRO = "t1.micro"; /** * Small Instance *