Issue 27: added 'walrus' blobstore and 'eucalyptus' compute providers

This commit is contained in:
Adrian Cole 2010-06-15 15:22:32 -04:00
parent 55fa55a0dc
commit cba3f660fb
19 changed files with 939 additions and 395 deletions

View File

@ -0,0 +1,51 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2;
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_ENDPOINT;
import java.util.Properties;
/**
* Builds properties used in Eucalyptus Clients
*
* @author Adrian Cole
*/
public class EucalyptusPropertiesBuilder extends EC2PropertiesBuilder {
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_EC2_ENDPOINT,
"http://173.205.188.130:8773/services/Eucalyptus");
// TODO
// properties.setProperty(PROPERTY_ELB_ENDPOINT,
// "https://elasticloadbalancing.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "admin");
return properties;
}
public EucalyptusPropertiesBuilder(Properties properties) {
super(properties);
}
public EucalyptusPropertiesBuilder(String id, String secret) {
super(id, secret);
}
}

View File

@ -22,6 +22,7 @@ import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.ownedBy;
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
import static org.jclouds.aws.ec2.util.EC2Utils.getAllRunningInstancesInRegion; import static org.jclouds.aws.ec2.util.EC2Utils.getAllRunningInstancesInRegion;
import static org.jclouds.aws.ec2.util.EC2Utils.parseHandle; import static org.jclouds.aws.ec2.util.EC2Utils.parseHandle;
import static org.jclouds.compute.domain.OsFamily.CENTOS;
import static org.jclouds.compute.domain.OsFamily.UBUNTU; import static org.jclouds.compute.domain.OsFamily.UBUNTU;
import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion;
@ -64,6 +65,7 @@ import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.domain.Image.ImageType; import org.jclouds.aws.ec2.domain.Image.ImageType;
import org.jclouds.aws.ec2.functions.RunningInstanceToStorageMappingUnix; import org.jclouds.aws.ec2.functions.RunningInstanceToStorageMappingUnix;
import org.jclouds.aws.ec2.options.DescribeImagesOptions;
import org.jclouds.aws.ec2.predicates.InstancePresent; import org.jclouds.aws.ec2.predicates.InstancePresent;
import org.jclouds.aws.ec2.services.InstanceClient; import org.jclouds.aws.ec2.services.InstanceClient;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
@ -127,10 +129,9 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
@Named("PRESENT") @Named("PRESENT")
protected Predicate<RunningInstance> instancePresent(InstancePresent present) { protected Predicate<RunningInstance> instancePresent(InstancePresent present) {
return new RetryablePredicate<RunningInstance>(present, 3000, 200, return new RetryablePredicate<RunningInstance>(present, 3000, 200,
TimeUnit.MILLISECONDS); TimeUnit.MILLISECONDS);
} }
@Override @Override
protected void configure() { protected void configure() {
super.configure(); super.configure();
@ -174,9 +175,12 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
@Provides @Provides
@Named("DEFAULT") @Named("DEFAULT")
protected TemplateBuilder provideTemplate(TemplateBuilder template) { protected TemplateBuilder provideTemplate(@EC2 String region,
return template.architecture(Architecture.X86_32).osFamily(UBUNTU) TemplateBuilder template) {
.imageNameMatches(".*10\\.?04.*").osDescriptionMatches("^ubuntu-images.*"); return "Eucalyptus".equals(region) ? template.osFamily(CENTOS).smallest()
: template.architecture(Architecture.X86_32).osFamily(UBUNTU)
.imageNameMatches(".*10\\.?04.*").osDescriptionMatches(
"^ubuntu-images.*");
} }
// TODO make this more efficient for listNodes(); currently // TODO make this more efficient for listNodes(); currently
@ -402,7 +406,11 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
holder.logger.debug(">> providing images"); holder.logger.debug(">> providing images");
Map<String, ListenableFuture<?>> parallelResponses = Maps.newHashMap(); Map<String, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
final DescribeImagesOptions options;
if (amiOwners.length == 1 && amiOwners[0].equals("*"))
options = new DescribeImagesOptions();
else
options = ownedBy(amiOwners);
for (final String region : regionMap.keySet()) { for (final String region : regionMap.keySet()) {
parallelResponses.put(region, ConcurrentUtils.makeListenable( parallelResponses.put(region, ConcurrentUtils.makeListenable(
executor.submit(new Callable<Void>() { executor.submit(new Callable<Void>() {
@ -410,7 +418,7 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
public Void call() throws Exception { public Void call() throws Exception {
for (final org.jclouds.aws.ec2.domain.Image from : sync for (final org.jclouds.aws.ec2.domain.Image from : sync
.getAMIServices().describeImagesInRegion(region, .getAMIServices().describeImagesInRegion(region,
ownedBy(amiOwners))) { options)) {
Image image = parser.apply(from); Image image = parser.apply(from);
if (image != null) if (image != null)
images.put(new RegionAndName(region, image images.put(new RegionAndName(region, image

View File

@ -19,8 +19,9 @@
package org.jclouds.aws.ec2.compute.functions; package org.jclouds.aws.ec2.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeUtils.parseOsFamilyOrNull;
import static org.jclouds.compute.util.ComputeUtils.parseVersionOrReturnEmptyString;
import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -53,26 +54,22 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, Image> { public class ImageParser implements
Function<org.jclouds.aws.ec2.domain.Image, Image> {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
public static final Pattern CANONICAL_PATTERN = Pattern public static final Pattern CANONICAL_PATTERN = Pattern
.compile(".*/([^-]*)-([^-]*)-.*-(.*)(\\.manifest.xml)?"); .compile(".*/([^-]*)-([^-]*)-.*-(.*)(\\.manifest.xml)?");
// ex rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml // ex rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml
public static final Pattern RIGHTSCALE_PATTERN = Pattern public static final Pattern RIGHTSCALE_PATTERN = Pattern
.compile("[^/]*/([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?"); .compile("[^/]*/([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?");
// ex 411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha // ex 411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha
public static final Pattern RIGHTIMAGE_PATTERN = Pattern public static final Pattern RIGHTIMAGE_PATTERN = Pattern
.compile("[^/]*/RightImage_([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?"); .compile("[^/]*/RightImage_([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?");
public static final Map<String, String> NAME_VERSION_MAP = ImmutableMap
.<String, String> builder().put("hardy", "8.04").put("intrepid", "8.10").put("jaunty",
"9.04").put("karmic", "9.10").put("lucid", "10.04").put("maverick", "10.10")
.build();
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider; private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
private final Set<? extends Location> locations; private final Set<? extends Location> locations;
@ -80,9 +77,11 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
private final Location defaultLocation; private final Location defaultLocation;
@Inject @Inject
ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider, ImageParser(
Set<? extends Location> locations, Location defaultLocation) { PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider"); Set<? extends Location> locations, Location defaultLocation) {
this.credentialProvider = checkNotNull(credentialProvider,
"credentialProvider");
this.locations = checkNotNull(locations, "locations"); this.locations = checkNotNull(locations, "locations");
this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation"); this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
@ -98,20 +97,17 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
logger.trace("skipping as not a machine image(%s)", from.getId()); logger.trace("skipping as not a machine image(%s)", from.getId());
return null; return null;
} }
OsFamily os = null; OsFamily os = parseOsFamilyOrNull(from.getImageLocation());
String name = ""; String name = parseVersionOrReturnEmptyString(os, from.getImageLocation());
String description = from.getDescription() != null ? from.getDescription() : from String description = from.getDescription() != null ? from
.getImageLocation(); .getDescription() : from.getImageLocation();
String osDescription = from.getImageLocation(); String osDescription = from.getImageLocation();
String version = ""; String version = "";
try { try {
Matcher matcher = getMatcherAndFind(from.getImageLocation()); Matcher matcher = getMatcherAndFind(from.getImageLocation());
os = OsFamily.fromValue(matcher.group(1)); os = OsFamily.fromValue(matcher.group(1));
name = matcher.group(2);// TODO no field for os version name = parseVersionOrReturnEmptyString(os, matcher.group(2));
// normalize versions across ubuntu from alestic and canonical
if (NAME_VERSION_MAP.containsKey(name))
name = NAME_VERSION_MAP.get(name);
version = matcher.group(3).replace(".manifest.xml", ""); version = matcher.group(3).replace(".manifest.xml", "");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
logger.debug("<< didn't match os(%s)", from.getImageLocation()); logger.debug("<< didn't match os(%s)", from.getImageLocation());
@ -132,24 +128,24 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
}); });
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
System.err.printf("unknown region %s for image %s; not in %s", from.getRegion(), from System.err.printf("unknown region %s for image %s; not in %s", from
.getId(), locations); .getRegion(), from.getId(), locations);
location = new LocationImpl(LocationScope.REGION, from.getRegion(), from.getRegion(), location = new LocationImpl(LocationScope.REGION, from.getRegion(),
defaultLocation.getParent()); from.getRegion(), defaultLocation.getParent());
} }
return new ImageImpl( return new ImageImpl(
from.getId(), from.getId(),
name, name,
from.getRegion() + "/" + from.getId(), from.getRegion() + "/" + from.getId(),
location, location,
null, null,
ImmutableMap.<String, String> of("owner", from.getImageOwnerId()), ImmutableMap.<String, String> of("owner", from.getImageOwnerId()),
description, description,
version, version,
os, os,
osDescription, osDescription,
from.getArchitecture() == org.jclouds.aws.ec2.domain.Image.Architecture.I386 ? Architecture.X86_32 from.getArchitecture() == org.jclouds.aws.ec2.domain.Image.Architecture.I386 ? Architecture.X86_32
: Architecture.X86_64, defaultCredentials); : Architecture.X86_64, defaultCredentials);
} }
@ -159,8 +155,8 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
* if no configured matcher matches the manifest. * if no configured matcher matches the manifest.
*/ */
private Matcher getMatcherAndFind(String manifest) { private Matcher getMatcherAndFind(String manifest) {
for (Pattern pattern : new Pattern[] { CANONICAL_PATTERN, RIGHTIMAGE_PATTERN, for (Pattern pattern : new Pattern[] { CANONICAL_PATTERN,
RIGHTSCALE_PATTERN }) { RIGHTIMAGE_PATTERN, RIGHTSCALE_PATTERN }) {
Matcher matcher = pattern.matcher(manifest); Matcher matcher = pattern.matcher(manifest);
if (matcher.find()) if (matcher.find())
return matcher; return matcher;

View File

@ -36,91 +36,100 @@ import org.jclouds.concurrent.Timeout;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Timeout(duration = 45, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 90, timeUnit = TimeUnit.SECONDS)
public interface InstanceClient { public interface InstanceClient {
/** /**
* Returns information about instances that you own. * Returns information about instances that you own.
* <p/> * <p/>
* *
* If you specify one or more instance IDs, Amazon EC2 returns information for those instances. * If you specify one or more instance IDs, Amazon EC2 returns information
* If you do not specify instance IDs, Amazon EC2 returns information for all relevant instances. * for those instances. If you do not specify instance IDs, Amazon EC2
* If you specify an invalid instance ID, a fault is returned. If you specify an instance that * returns information for all relevant instances. If you specify an invalid
* you do not own, it will not be included in the returned results. * instance ID, a fault is returned. If you specify an instance that you do
* not own, it will not be included in the returned results.
* <p/> * <p/>
* Recently terminated instances might appear in the returned results.This interval is usually * Recently terminated instances might appear in the returned results.This
* less than one hour. * interval is usually less than one hour.
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* *
* @see #runInstancesInRegion * @see #runInstancesInRegion
* @see #terminateInstancesInRegion * @see #terminateInstancesInRegion
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html"
* /> * />
*/ */
Set<Reservation> describeInstancesInRegion(@Nullable String region, String... instanceIds); Set<Reservation> describeInstancesInRegion(@Nullable String region,
String... instanceIds);
/** /**
* Launches a specified number of instances of an AMI for which you have permissions. * Launches a specified number of instances of an AMI for which you have
* permissions.
* <p/> * <p/>
* *
* If Amazon EC2 cannot launch the minimum number AMIs you request, no instances will be * If Amazon EC2 cannot launch the minimum number AMIs you request, no
* launched. If there is insufficient capacity to launch the maximum number of AMIs you request, * instances will be launched. If there is insufficient capacity to launch
* Amazon EC2 launches the minimum number specified for each AMI and allocate the remaining * the maximum number of AMIs you request, Amazon EC2 launches the minimum
* available instances using round robin. * number specified for each AMI and allocate the remaining available
* instances using round robin.
* <p/> * <p/>
* <h4>Security Groups</h4> * <h4>Security Groups</h4>
* <b>Note:</b> Every instance is launched in a security group (created using the * <b>Note:</b> Every instance is launched in a security group (created using
* CreateSecurityGroup operation. * the CreateSecurityGroup operation.
* <h4>Key Pair</h4> * <h4>Key Pair</h4>
* You can provide an optional key pair ID for each image in the launch request (created using * You can provide an optional key pair ID for each image in the launch
* the CreateKeyPair operation). All instances that are created from images that use this key * request (created using the CreateKeyPair operation). All instances that
* pair will have access to the associated public key at boot. You can use this key to provide * are created from images that use this key pair will have access to the
* secure access to an instance of an image on a per-instance basis. Amazon EC2 public images use * associated public key at boot. You can use this key to provide secure
* this feature to provide secure access without passwords. * access to an instance of an image on a per-instance basis. Amazon EC2
* public images use this feature to provide secure access without passwords.
* <p/> * <p/>
* <b>Note:</b> Launching public images without a key pair ID will leave them inaccessible. * <b>Note:</b> Launching public images without a key pair ID will leave them
* inaccessible.
* <p/> * <p/>
* The public key material is made available to the instance at boot time by placing it in the * The public key material is made available to the instance at boot time by
* openssh_id.pub file on a logical device that is exposed to the instance as /dev/sda2 (the * placing it in the openssh_id.pub file on a logical device that is exposed
* instance store). The format of this file is suitable for use as an entry within * to the instance as /dev/sda2 (the instance store). The format of this file
* ~/.ssh/authorized_keys (the OpenSSH format). This can be done at boot (e.g., as part of * is suitable for use as an entry within ~/.ssh/authorized_keys (the OpenSSH
* rc.local) allowing for secure access without passwords. * format). This can be done at boot (e.g., as part of rc.local) allowing for
* secure access without passwords.
* <h4>User Data</h4> * <h4>User Data</h4>
* Optional user data can be provided in the launch request. All instances that collectively * Optional user data can be provided in the launch request. All instances
* comprise the launch request have access to this data. For more information, go the Amazon * that collectively comprise the launch request have access to this data.
* Elastic Compute Cloud Developer Guide. * For more information, go the Amazon Elastic Compute Cloud Developer Guide.
* <h4>Product Codes</h4> * <h4>Product Codes</h4>
* *
* <b>Note:</b> If any of the AMIs have a product code attached for which the user has not * <b>Note:</b> If any of the AMIs have a product code attached for which the
* subscribed, the RunInstances call will fail. * user has not subscribed, the RunInstances call will fail.
* <h4>Kernel</h4> * <h4>Kernel</h4>
* *
* <b>Important:</b> We strongly recommend using the 2.6.18 Xen stock kernel with High-CPU and * <b>Important:</b> We strongly recommend using the 2.6.18 Xen stock kernel
* High-Memory instances. Although the default Amazon EC2 kernels will work, the new kernels * with High-CPU and High-Memory instances. Although the default Amazon EC2
* provide greater stability and performance for these instance types. For more information about * kernels will work, the new kernels provide greater stability and
* kernels, go the Amazon Elastic Compute Cloud Developer Guide. * performance for these instance types. For more information about kernels,
* go the Amazon Elastic Compute Cloud Developer Guide.
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param nullableAvailabilityZone * @param nullableAvailabilityZone
* Specifies the placement constraints (Availability Zones) for launching the * Specifies the placement constraints (Availability Zones) for
* instances. If null, Amazon will determine the best availability zone to place the * launching the instances. If null, Amazon will determine the best
* instance. * availability zone to place the instance.
* @param imageId * @param imageId
* Unique ID of a machine image, returned by a call to * Unique ID of a machine image, returned by a call to
* @param minCount * @param minCount
* Minimum number of instances to launch. If the value is more than Amazon EC2 can * Minimum number of instances to launch. If the value is more than
* launch, no instances a re launched at all. Constraints: Between 1 and the maximum * Amazon EC2 can launch, no instances a re launched at all.
* number allowed for your account (default: 20). * Constraints: Between 1 and the maximum number allowed for your
* account (default: 20).
* @param maxCount * @param maxCount
* Maximum number of instances to launch. If the value is more than Amazon EC2 can * Maximum number of instances to launch. If the value is more than
* launch, the largest possible number above minCount will be launched instead. * Amazon EC2 can launch, the largest possible number above
* Constraints: Between 1 and the maximum number allowed for your account (default: * minCount will be launched instead. Constraints: Between 1 and
* 20). * the maximum number allowed for your account (default: 20).
* @see #describeInstancesInRegion * @see #describeInstancesInRegion
* @see #terminateInstancesInRegion * @see #terminateInstancesInRegion
* @see #authorizeSecurityGroupIngressInRegion * @see #authorizeSecurityGroupIngressInRegion
@ -128,55 +137,58 @@ public interface InstanceClient {
* @see #describeSecurityGroupsInRegion * @see #describeSecurityGroupsInRegion
* @see #createSecurityGroupInRegion * @see #createSecurityGroupInRegion
* @see #createKeyPairInRegion * @see #createKeyPairInRegion
* @see <a href= * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RunInstances.html"
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RunInstances.html"
* /> * />
* @see RunInstancesOptions * @see RunInstancesOptions
*/ */
Reservation runInstancesInRegion(@Nullable String region, Reservation runInstancesInRegion(@Nullable String region,
@Nullable String nullableAvailabilityZone, String imageId, int minCount, @Nullable String nullableAvailabilityZone, String imageId,
int maxCount, RunInstancesOptions... options); int minCount, int maxCount, RunInstancesOptions... options);
/** /**
* Shuts down one or more instances. This operation is idempotent; if you terminate an instance * Shuts down one or more instances. This operation is idempotent; if you
* more than once, each call will succeed. * terminate an instance more than once, each call will succeed.
* <p/> * <p/>
* Terminated instances will remain visible after termination (approximately one hour). * Terminated instances will remain visible after termination (approximately
* one hour).
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceIds * @param instanceIds
* Instance ID to terminate. * Instance ID to terminate.
* @see #describeInstancesInRegion * @see #describeInstancesInRegion
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-TerminateInstances.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-TerminateInstances.html"
* /> * />
*/ */
Set<InstanceStateChange> terminateInstancesInRegion(@Nullable String region, String... instanceIds); Set<InstanceStateChange> terminateInstancesInRegion(@Nullable String region,
String... instanceIds);
/** /**
* Stops an instance that uses an Amazon EBS volume as its root device. * Stops an instance that uses an Amazon EBS volume as its root device.
* <p/> * <p/>
* Instances that use Amazon EBS volumes as their root devices can be quickly stopped and * Instances that use Amazon EBS volumes as their root devices can be quickly
* started. When an instance is stopped, the compute resources are released and you are not * stopped and started. When an instance is stopped, the compute resources
* billed for hourly instance usage. However, your root partition Amazon EBS volume remains, * are released and you are not billed for hourly instance usage. However,
* continues to persist your data, and you are charged for Amazon EBS volume usage. You can * your root partition Amazon EBS volume remains, continues to persist your
* restart your instance at any time. * data, and you are charged for Amazon EBS volume usage. You can restart
* your instance at any time.
* <h3>Note</h3> * <h3>Note</h3>
* Before stopping an instance, make sure it is in a state from which it can be restarted. * Before stopping an instance, make sure it is in a state from which it can
* Stopping an instance does not preserve data stored in RAM. * be restarted. Stopping an instance does not preserve data stored in RAM.
* <p/> * <p/>
* Performing this operation on an instance that uses an instance store as its root device * Performing this operation on an instance that uses an instance store as
* returns an error. * its root device returns an error.
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param force * @param force
* Forces the instance to stop. The instance will not have an opportunity to flush file * Forces the instance to stop. The instance will not have an
* system caches nor file system meta data. If you use this option, you must perform * opportunity to flush file system caches nor file system meta
* file system check and repair procedures. This option is not recommended for Windows * data. If you use this option, you must perform file system check
* instances. * and repair procedures. This option is not recommended for
* Windows instances.
* @param instanceIds * @param instanceIds
* Instance ID to stop. * Instance ID to stop.
* *
@ -184,23 +196,23 @@ public interface InstanceClient {
* @see #runInstancesInRegion * @see #runInstancesInRegion
* @see #describeInstancesInRegion * @see #describeInstancesInRegion
* @see #terminateInstancesInRegion * @see #terminateInstancesInRegion
* @see <a href= * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-StopInstances.html"
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-StopInstances.html"
* /> * />
*/ */
Set<InstanceStateChange> stopInstancesInRegion(@Nullable String region, boolean force, Set<InstanceStateChange> stopInstancesInRegion(@Nullable String region,
String... instanceIds); boolean force, String... instanceIds);
/** /**
* Requests a reboot of one or more instances. This operation is asynchronous; it only queues a * Requests a reboot of one or more instances. This operation is
* request to reboot the specified instance(s). The operation will succeed if the instances are * asynchronous; it only queues a request to reboot the specified
* valid and belong to you. Requests to reboot terminated instances are ignored. <h3>Note</h3> If * instance(s). The operation will succeed if the instances are valid and
* a Linux/UNIX instance does not cleanly shut down within four minutes, Amazon EC2 will perform * belong to you. Requests to reboot terminated instances are ignored. <h3>
* a hard reboot. * Note</h3> If a Linux/UNIX instance does not cleanly shut down within four
* minutes, Amazon EC2 will perform a hard reboot.
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* *
* @param instanceIds * @param instanceIds
* Instance ID to reboot. * Instance ID to reboot.
@ -209,8 +221,7 @@ public interface InstanceClient {
* @see #runInstancesInRegion * @see #runInstancesInRegion
* @see #describeInstancesInRegion * @see #describeInstancesInRegion
* @see #terminateInstancesInRegion * @see #terminateInstancesInRegion
* @see <a href= * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-StopInstances.html"
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-StopInstances.html"
* /> * />
*/ */
void rebootInstancesInRegion(@Nullable String region, String... instanceIds); void rebootInstancesInRegion(@Nullable String region, String... instanceIds);
@ -218,21 +229,22 @@ public interface InstanceClient {
/** /**
* Starts an instance that uses an Amazon EBS volume as its root device. * Starts an instance that uses an Amazon EBS volume as its root device.
* <p/> * <p/>
* Instances that use Amazon EBS volumes as their root devices can be quickly stopped and * Instances that use Amazon EBS volumes as their root devices can be quickly
* started. When an instance is stopped, the compute resources are released and you are not * stopped and started. When an instance is stopped, the compute resources
* billed for hourly instance usage. However, your root partition Amazon EBS volume remains, * are released and you are not billed for hourly instance usage. However,
* continues to persist your data, and you are charged for Amazon EBS volume usage. You can * your root partition Amazon EBS volume remains, continues to persist your
* restart your instance at any time. * data, and you are charged for Amazon EBS volume usage. You can restart
* your instance at any time.
* <h3>Note</h3> * <h3>Note</h3>
* Before stopping an instance, make sure it is in a state from which it can be restarted. * Before stopping an instance, make sure it is in a state from which it can
* Stopping an instance does not preserve data stored in RAM. * be restarted. Stopping an instance does not preserve data stored in RAM.
* <p/> * <p/>
* Performing this operation on an instance that uses an instance store as its root device * Performing this operation on an instance that uses an instance store as
* returns an error. * its root device returns an error.
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceIds * @param instanceIds
* Instance ID to start. * Instance ID to start.
* *
@ -243,129 +255,140 @@ public interface InstanceClient {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-StartInstances.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-StartInstances.html"
* /> * />
*/ */
Set<InstanceStateChange> startInstancesInRegion(@Nullable String region, String... instanceIds); Set<InstanceStateChange> startInstancesInRegion(@Nullable String region,
String... instanceIds);
/** /**
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to describe the attribute of * which instance to describe the attribute of
* @return unencoded user data * @return unencoded user data
*/ */
String getUserDataForInstanceInRegion(@Nullable String region, String instanceId); String getUserDataForInstanceInRegion(@Nullable String region,
String instanceId);
/** /**
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to describe the attribute of * which instance to describe the attribute of
* @return The root device name (e.g., /dev/sda1). * @return The root device name (e.g., /dev/sda1).
*/ */
String getRootDeviceNameForInstanceInRegion(@Nullable String region, String instanceId); String getRootDeviceNameForInstanceInRegion(@Nullable String region,
String instanceId);
/** /**
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to describe the attribute of * which instance to describe the attribute of
* @return the ID of the RAM disk associated with the AMI. * @return the ID of the RAM disk associated with the AMI.
*/ */
String getRamdiskForInstanceInRegion(@Nullable String region, String instanceId); String getRamdiskForInstanceInRegion(@Nullable String region,
String instanceId);
/** /**
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to describe the attribute of * which instance to describe the attribute of
* @return the ID of the kernel associated with the AMI. * @return the ID of the kernel associated with the AMI.
*/ */
String getKernelForInstanceInRegion(@Nullable String region, String instanceId); String getKernelForInstanceInRegion(@Nullable String region,
String instanceId);
/** /**
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to describe the attribute of * which instance to describe the attribute of
* @return Specifies whether the instance can be terminated using the APIs. You must modify this * @return Specifies whether the instance can be terminated using the APIs.
* attribute before you can terminate any "locked" instances from the APIs. * You must modify this attribute before you can terminate any
* "locked" instances from the APIs.
*/ */
boolean isApiTerminationDisabledForInstanceInRegion(@Nullable String region, String instanceId); boolean isApiTerminationDisabledForInstanceInRegion(@Nullable String region,
String instanceId);
/** /**
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to describe the attribute of * which instance to describe the attribute of
* @return The instance type of the instance. * @return The instance type of the instance.
*/ */
String getInstanceTypeForInstanceInRegion(@Nullable String region, String instanceId); String getInstanceTypeForInstanceInRegion(@Nullable String region,
String instanceId);
/** /**
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to describe the attribute of * which instance to describe the attribute of
* @return whether the instance's Amazon EBS volumes are stopped or terminated when the instance * @return whether the instance's Amazon EBS volumes are stopped or
* is shut down. * terminated when the instance is shut down.
*/ */
InstanceInitiatedShutdownBehavior getInstanceInitiatedShutdownBehaviorForInstanceInRegion( InstanceInitiatedShutdownBehavior getInstanceInitiatedShutdownBehaviorForInstanceInRegion(
String region, String instanceId); String region, String instanceId);
/** /**
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to describe the attribute of * which instance to describe the attribute of
* @return Describes the mapping that defines native device names to use when exposing virtual * @return Describes the mapping that defines native device names to use when
* devices. * exposing virtual devices.
*/ */
Map<String, EbsBlockDevice> getBlockDeviceMappingForInstanceInRegion(@Nullable String region, Map<String, EbsBlockDevice> getBlockDeviceMappingForInstanceInRegion(
String instanceId); @Nullable String region, String instanceId);
/** /**
* Resets an attribute of an instance to its default value. * Resets an attribute of an instance to its default value.
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to reset the attribute of * which instance to reset the attribute of
* @return the ID of the RAM disk associated with the AMI. * @return the ID of the RAM disk associated with the AMI.
*/ */
String resetRamdiskForInstanceInRegion(@Nullable String region, String instanceId); String resetRamdiskForInstanceInRegion(@Nullable String region,
String instanceId);
/** /**
* Resets an attribute of an instance to its default value. * Resets an attribute of an instance to its default value.
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to reset the attribute of * which instance to reset the attribute of
* @return the ID of the kernel associated with the AMI. * @return the ID of the kernel associated with the AMI.
*/ */
String resetKernelForInstanceInRegion(@Nullable String region, String instanceId); String resetKernelForInstanceInRegion(@Nullable String region,
String instanceId);
/** /**
* Sets the userData used for starting the instance. * Sets the userData used for starting the instance.
* <p/> * <p/>
* The instance needs to be in a {@link InstanceState#STOPPED} state, which implies two things: * The instance needs to be in a {@link InstanceState#STOPPED} state, which
* implies two things:
* <ol> * <ol>
* <li>The instance was launched from an EBS-backed AMI so that it can stop</li> * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
* <li>You have stopped and waited for the instance to transition from * <li>You have stopped and waited for the instance to transition from
@ -373,8 +396,8 @@ public interface InstanceClient {
* </ol> * </ol>
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to change the attribute of * which instance to change the attribute of
* @param unencodedData * @param unencodedData
@ -382,12 +405,14 @@ public interface InstanceClient {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
* /> * />
*/ */
void setUserDataForInstanceInRegion(@Nullable String region, String instanceId, byte[] unencodedData); void setUserDataForInstanceInRegion(@Nullable String region,
String instanceId, byte[] unencodedData);
/** /**
* Sets the ramdisk used for starting the instance. * Sets the ramdisk used for starting the instance.
* <p/> * <p/>
* The instance needs to be in a {@link InstanceState#STOPPED} state, which implies two things: * The instance needs to be in a {@link InstanceState#STOPPED} state, which
* implies two things:
* <ol> * <ol>
* <li>The instance was launched from an EBS-backed AMI so that it can stop</li> * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
* <li>You have stopped and waited for the instance to transition from * <li>You have stopped and waited for the instance to transition from
@ -395,8 +420,8 @@ public interface InstanceClient {
* </ol> * </ol>
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to change the attribute of * which instance to change the attribute of
* @param ramdisk * @param ramdisk
@ -404,12 +429,14 @@ public interface InstanceClient {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
* /> * />
*/ */
void setRamdiskForInstanceInRegion(@Nullable String region, String instanceId, String ramdisk); void setRamdiskForInstanceInRegion(@Nullable String region,
String instanceId, String ramdisk);
/** /**
* Sets the kernelId used for starting the instance. * Sets the kernelId used for starting the instance.
* <p/> * <p/>
* The instance needs to be in a {@link InstanceState#STOPPED} state, which implies two things: * The instance needs to be in a {@link InstanceState#STOPPED} state, which
* implies two things:
* <ol> * <ol>
* <li>The instance was launched from an EBS-backed AMI so that it can stop</li> * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
* <li>You have stopped and waited for the instance to transition from * <li>You have stopped and waited for the instance to transition from
@ -417,8 +444,8 @@ public interface InstanceClient {
* </ol> * </ol>
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to change the attribute of * which instance to change the attribute of
* @param kernel * @param kernel
@ -426,15 +453,16 @@ public interface InstanceClient {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
* /> * />
*/ */
void setKernelForInstanceInRegion(@Nullable String region, String instanceId, String kernel); void setKernelForInstanceInRegion(@Nullable String region,
String instanceId, String kernel);
/** /**
* This command works while the instance is running and controls whether or not the api can be * This command works while the instance is running and controls whether or
* used to terminate the instance. * not the api can be used to terminate the instance.
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to reset the attribute of * which instance to reset the attribute of
* @param apiTerminationDisabled * @param apiTerminationDisabled
@ -442,13 +470,14 @@ public interface InstanceClient {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
* /> * />
*/ */
void setApiTerminationDisabledForInstanceInRegion(@Nullable String region, String instanceId, void setApiTerminationDisabledForInstanceInRegion(@Nullable String region,
boolean apiTerminationDisabled); String instanceId, boolean apiTerminationDisabled);
/** /**
* Sets the instanceType used for starting the instance. * Sets the instanceType used for starting the instance.
* <p/> * <p/>
* The instance needs to be in a {@link InstanceState#STOPPED} state, which implies two things: * The instance needs to be in a {@link InstanceState#STOPPED} state, which
* implies two things:
* <ol> * <ol>
* <li>The instance was launched from an EBS-backed AMI so that it can stop</li> * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
* <li>You have stopped and waited for the instance to transition from * <li>You have stopped and waited for the instance to transition from
@ -456,8 +485,8 @@ public interface InstanceClient {
* </ol> * </ol>
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to change the attribute of * which instance to change the attribute of
* @param instanceType * @param instanceType
@ -465,14 +494,15 @@ public interface InstanceClient {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
* /> * />
*/ */
void setInstanceTypeForInstanceInRegion(@Nullable String region, String instanceId, void setInstanceTypeForInstanceInRegion(@Nullable String region,
String instanceType); String instanceId, String instanceType);
/** /**
* Specifies whether the instance's Amazon EBS volumes are stopped or terminated when the * Specifies whether the instance's Amazon EBS volumes are stopped or
* instance is shut down. * terminated when the instance is shut down.
* <p/> * <p/>
* The instance needs to be in a {@link InstanceState#STOPPED} state, which implies two things: * The instance needs to be in a {@link InstanceState#STOPPED} state, which
* implies two things:
* <ol> * <ol>
* <li>The instance was launched from an EBS-backed AMI so that it can stop</li> * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
* <li>You have stopped and waited for the instance to transition from * <li>You have stopped and waited for the instance to transition from
@ -480,56 +510,58 @@ public interface InstanceClient {
* </ol> * </ol>
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to change the attribute of * which instance to change the attribute of
* @param instanceInitiatedShutdownBehavior * @param instanceInitiatedShutdownBehavior
* whether the instance's Amazon EBS volumes are stopped or terminated when the * whether the instance's Amazon EBS volumes are stopped or
* instance is shut down. * terminated when the instance is shut down.
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
* /> * />
*/ */
void setInstanceInitiatedShutdownBehaviorForInstanceInRegion(@Nullable String region, String instanceId, void setInstanceInitiatedShutdownBehaviorForInstanceInRegion(
InstanceInitiatedShutdownBehavior instanceInitiatedShutdownBehavior); @Nullable String region, String instanceId,
InstanceInitiatedShutdownBehavior instanceInitiatedShutdownBehavior);
/** /**
* Sets the blockDeviceMapping used for an instance. * Sets the blockDeviceMapping used for an instance.
* <p/> * <p/>
* The instance needs to be in a {@link InstanceState#STOPPED} state, which implies two things: * The instance needs to be in a {@link InstanceState#STOPPED} state, which
* implies two things:
* <ol> * <ol>
* <li>The instance was launched from an EBS-backed AMI so that it can stop</li> * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
* <li>You have stopped and waited for the instance to transition from * <li>You have stopped and waited for the instance to transition from
* {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li> * {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
* </ol> * </ol>
* *
* To create the instances of {@link RunningInstance.EbsBlockDevice}, * To create the instances of {@link RunningInstance.EbsBlockDevice}, the
* the constructor can be used with the following parameters: * constructor can be used with the following parameters:
* {@link RunningInstance.EbsBlockDevice#EbsBlockDevice(String, String, boolean)}, * {@link RunningInstance.EbsBlockDevice#EbsBlockDevice(String, String, boolean)}
* that are: * , that are:
* <ol> * <ol>
* <li>Volume id (required), for instance, "vol-blah"</li> * <li>Volume id (required), for instance, "vol-blah"</li>
* <li>Device name (optional), for instance, "/dev/sda1". To find out more about * <li>Device name (optional), for instance, "/dev/sda1". To find out more
* device names, read the next paragraph.</li> * about device names, read the next paragraph.</li>
* <li>Delete on termination flag (optional), which defines whether the volume will be * <li>Delete on termination flag (optional), which defines whether the
* deleted upon instance's termination.</li> * volume will be deleted upon instance's termination.</li>
* </ol> * </ol>
* <p/> * <p/>
* Note that the device names between Linux and Windows differ. For Linux, ensure that your * Note that the device names between Linux and Windows differ. For Linux,
* device name is in the form /dev/sd[a-z] . For example, /dev/sda , /dev/sdb and /dev/sdh are * ensure that your device name is in the form /dev/sd[a-z] . For example,
* all valid device names. * /dev/sda , /dev/sdb and /dev/sdh are all valid device names.
* <p/> * <p/>
* For Windows, the root device is still referred to as /dev/sda1 . For other devices, ensure * For Windows, the root device is still referred to as /dev/sda1 . For other
* that they are in the form /xvd[c-p] . For example, /xvde , /xvdf and /xvdp are all valid * devices, ensure that they are in the form /xvd[c-p] . For example, /xvde ,
* Windows device names. * /xvdf and /xvdp are all valid Windows device names.
* <p/> * <p/>
* <b>NOTE</b>: As of now 02/20/2010, this command only works to change the * <b>NOTE</b>: As of now 02/20/2010, this command only works to change the
* DeleteOnTermination property of the device. The volume must be <i>attached</i> to a * DeleteOnTermination property of the device. The volume must be
* stopped instance. * <i>attached</i> to a stopped instance.
* *
* @param region * @param region
* Instances are tied to Availability Zones. However, the instance ID is tied to the * Instances are tied to Availability Zones. However, the instance
* Region. * ID is tied to the Region.
* @param instanceId * @param instanceId
* which instance to change the attribute of * which instance to change the attribute of
* @param blockDeviceMapping * @param blockDeviceMapping
@ -537,6 +569,6 @@ public interface InstanceClient {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html" * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
* /> * />
*/ */
void setBlockDeviceMappingForInstanceInRegion(@Nullable String region, String instanceId, void setBlockDeviceMappingForInstanceInRegion(@Nullable String region,
BlockDeviceMapping blockDeviceMapping); String instanceId, BlockDeviceMapping blockDeviceMapping);
} }

View File

@ -32,7 +32,8 @@ import com.google.common.collect.Maps;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class DescribeRegionsResponseHandler extends ParseSax.HandlerWithResult<Map<String, URI>> { public class DescribeRegionsResponseHandler extends
ParseSax.HandlerWithResult<Map<String, URI>> {
private StringBuilder currentText = new StringBuilder(); private StringBuilder currentText = new StringBuilder();
private Map<String, URI> regionEndpoints = Maps.newHashMap(); private Map<String, URI> regionEndpoints = Maps.newHashMap();
@ -47,10 +48,15 @@ public class DescribeRegionsResponseHandler extends ParseSax.HandlerWithResult<M
public void endElement(String uri, String name, String qName) { public void endElement(String uri, String name, String qName) {
if (qName.equals("regionName")) { if (qName.equals("regionName")) {
region = currentText.toString().trim(); String pending = currentText.toString().trim();
if (pending.indexOf("Walrus") == -1)
region = pending;
} else if (qName.equals("regionEndpoint")) { } else if (qName.equals("regionEndpoint")) {
regionEndpoint = URI.create(String.format("https://%s", currentText.toString().trim())); String pending = currentText.toString().trim();
} else if (qName.equals("item")) { if (pending.indexOf("Walrus") == -1)
regionEndpoint = URI.create(pending.startsWith("http") ? pending
: String.format("https://%s", pending));
} else if (qName.equals("item") && region != null) {
regionEndpoints.put(region, regionEndpoint); regionEndpoints.put(region, regionEndpoint);
this.region = null; this.region = null;
this.regionEndpoint = null; this.regionEndpoint = null;

View File

@ -72,6 +72,7 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
exception); exception);
break; break;
case 401: case 401:
case 403:
exception = new AuthorizationException(command.getRequest(), exception = new AuthorizationException(command.getRequest(),
error != null ? error.getMessage() : response.getStatusLine()); error != null ? error.getMessage() : response.getStatusLine());
break; break;

View File

@ -23,10 +23,7 @@ import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_ACCESSKEYID;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AWS_SECRETACCESSKEY;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT_AP_SOUTHEAST_1; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_REGIONS;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT_EU_WEST_1;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT_US_STANDARD;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT_US_WEST_1;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL;
import static org.jclouds.blobstore.reference.BlobStoreConstants.DIRECTORY_SUFFIX_FOLDER; import static org.jclouds.blobstore.reference.BlobStoreConstants.DIRECTORY_SUFFIX_FOLDER;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX;
@ -36,8 +33,11 @@ import java.net.URI;
import java.util.Properties; import java.util.Properties;
import org.jclouds.PropertiesBuilder; import org.jclouds.PropertiesBuilder;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.s3.reference.S3Constants; import org.jclouds.aws.s3.reference.S3Constants;
import com.google.common.base.Joiner;
/** /**
* Builds properties used in S3 Connections * Builds properties used in S3 Connections
* *
@ -49,14 +49,28 @@ public class S3PropertiesBuilder extends PropertiesBuilder {
Properties properties = super.defaultProperties(); Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_RELAX_HOSTNAME, "true"); properties.setProperty(PROPERTY_RELAX_HOSTNAME, "true");
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-"); properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-amz-meta-");
properties.setProperty(PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com"); addEndpointProperties(properties);
properties.setProperty(PROPERTY_S3_ENDPOINT_US_STANDARD, "https://s3.amazonaws.com");
properties.setProperty(PROPERTY_S3_ENDPOINT_US_WEST_1, "https://s3-us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_S3_ENDPOINT_EU_WEST_1, "https://s3-eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_S3_ENDPOINT_AP_SOUTHEAST_1,
"https://s3-ap-southeast-1.amazonaws.com");
properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60"); properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60");
properties.setProperty(PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX, DIRECTORY_SUFFIX_FOLDER); properties.setProperty(PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX,
DIRECTORY_SUFFIX_FOLDER);
return properties;
}
protected Properties addEndpointProperties(Properties properties) {
properties.setProperty(PROPERTY_S3_REGIONS, Joiner.on(',').join(
Region.US_STANDARD, Region.US_WEST_1, Region.EU_WEST_1,
Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + Region.US_STANDARD,
"https://s3.amazonaws.com");
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + Region.US_WEST_1,
"https://s3-us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_S3_ENDPOINT + "." + Region.EU_WEST_1,
"https://s3-eu-west-1.amazonaws.com");
properties.setProperty(
PROPERTY_S3_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
"https://s3-ap-southeast-1.amazonaws.com");
return properties; return properties;
} }
@ -71,15 +85,16 @@ public class S3PropertiesBuilder extends PropertiesBuilder {
@Override @Override
public S3PropertiesBuilder withCredentials(String id, String secret) { public S3PropertiesBuilder withCredentials(String id, String secret) {
properties.setProperty(PROPERTY_AWS_ACCESSKEYID, checkNotNull(id, "awsAccessKeyId")); properties.setProperty(PROPERTY_AWS_ACCESSKEYID, checkNotNull(id,
"awsAccessKeyId"));
properties.setProperty(PROPERTY_AWS_SECRETACCESSKEY, checkNotNull(secret, properties.setProperty(PROPERTY_AWS_SECRETACCESSKEY, checkNotNull(secret,
"awsSecretAccessKey")); "awsSecretAccessKey"));
return this; return this;
} }
public S3PropertiesBuilder withEndpoint(URI endpoint) { public S3PropertiesBuilder withEndpoint(URI endpoint) {
properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, checkNotNull(endpoint, "endpoint") properties.setProperty(S3Constants.PROPERTY_S3_ENDPOINT, checkNotNull(
.toString()); endpoint, "endpoint").toString());
return this; return this;
} }

View File

@ -0,0 +1,31 @@
package org.jclouds.aws.s3;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_ENDPOINT;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_REGIONS;
import java.util.Properties;
/**
* Builds properties used in Walrus Clients
*
* @author Adrian Cole
*/
public class WalrusPropertiesBuilder extends S3PropertiesBuilder {
@Override
protected Properties addEndpointProperties(Properties properties) {
properties.setProperty(PROPERTY_S3_REGIONS, "Walrus");
properties.setProperty(PROPERTY_S3_ENDPOINT,
"http://173.205.188.130:8773/services/Walrus");
properties.setProperty(PROPERTY_S3_ENDPOINT + ".Walrus",
"http://173.205.188.130:8773/services/Walrus");
return properties;
}
public WalrusPropertiesBuilder(Properties properties) {
super(properties);
}
public WalrusPropertiesBuilder(String id, String secret) {
super(id, secret);
}
}

View File

@ -26,7 +26,6 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler; import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler; import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent; import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
@ -48,11 +47,15 @@ import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RequestSigner; import org.jclouds.rest.RequestSigner;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.Scopes; import com.google.inject.Scopes;
import com.google.inject.name.Names;
/** /**
* Configures the S3 connection, including logging and http transport. * Configures the S3 connection, including logging and http transport.
@ -61,7 +64,8 @@ import com.google.inject.Scopes;
*/ */
@ConfiguresRestClient @ConfiguresRestClient
@RequiresHttp @RequiresHttp
public class S3RestClientModule extends RestClientModule<S3Client, S3AsyncClient> { public class S3RestClientModule extends
RestClientModule<S3Client, S3AsyncClient> {
public S3RestClientModule() { public S3RestClientModule() {
super(S3Client.class, S3AsyncClient.class); super(S3Client.class, S3AsyncClient.class);
} }
@ -91,8 +95,8 @@ public class S3RestClientModule extends RestClientModule<S3Client, S3AsyncClient
@Provides @Provides
@TimeStamp @TimeStamp
Supplier<String> provideTimeStampCache( Supplier<String> provideTimeStampCache(
@Named(S3Constants.PROPERTY_S3_SESSIONINTERVAL) long seconds, @Named(S3Constants.PROPERTY_S3_SESSIONINTERVAL) long seconds,
final DateService dateService) { final DateService dateService) {
return new ExpirableSupplier<String>(new Supplier<String>() { return new ExpirableSupplier<String>(new Supplier<String>() {
public String get() { public String get() {
return dateService.rfc822DateFormat(); return dateService.rfc822DateFormat();
@ -104,13 +108,15 @@ public class S3RestClientModule extends RestClientModule<S3Client, S3AsyncClient
@Singleton @Singleton
@S3 @S3
Map<String, URI> provideRegions( Map<String, URI> provideRegions(
@Named(S3Constants.PROPERTY_S3_ENDPOINT_US_STANDARD) String usstandard, @Named(S3Constants.PROPERTY_S3_REGIONS) String regionString,
@Named(S3Constants.PROPERTY_S3_ENDPOINT_US_WEST_1) String uswest, Injector injector) {
@Named(S3Constants.PROPERTY_S3_ENDPOINT_AP_SOUTHEAST_1) String southeast, Map<String, URI> regions = Maps.newLinkedHashMap();
@Named(S3Constants.PROPERTY_S3_ENDPOINT_EU_WEST_1) String euwest) { for (String region : Splitter.on(',').split(regionString)) {
return ImmutableMap.<String, URI> of(Region.US_STANDARD, URI.create(usstandard), regions.put(region, URI.create(injector.getInstance(Key.get(
Region.AP_SOUTHEAST_1, URI.create(southeast), Region.US_WEST_1, URI.create(uswest), String.class, Names.named(S3Constants.PROPERTY_S3_ENDPOINT + "."
Region.EU_WEST_1, URI.create(euwest)); + region)))));
}
return regions;
} }
@Provides @Provides
@ -123,7 +129,8 @@ public class S3RestClientModule extends RestClientModule<S3Client, S3AsyncClient
@Provides @Provides
@Singleton @Singleton
@S3 @S3
protected URI provideS3URI(@Named(S3Constants.PROPERTY_S3_ENDPOINT) String endpoint) { protected URI provideS3URI(
@Named(S3Constants.PROPERTY_S3_ENDPOINT) String endpoint) {
return URI.create(endpoint); return URI.create(endpoint);
} }
@ -131,24 +138,25 @@ public class S3RestClientModule extends RestClientModule<S3Client, S3AsyncClient
@Singleton @Singleton
@S3 @S3
String getDefaultRegion(@S3 URI uri, @S3 Map<String, URI> map) { String getDefaultRegion(@S3 URI uri, @S3 Map<String, URI> map) {
return ImmutableBiMap.<String, URI> builder().putAll(map).build().inverse().get(uri); return ImmutableBiMap.<String, URI> builder().putAll(map).build()
.inverse().get(uri);
} }
@Override @Override
protected void bindErrorHandlers() { protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to( bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
ParseAWSErrorFromXmlContent.class); ParseAWSErrorFromXmlContent.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to( bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
ParseAWSErrorFromXmlContent.class); ParseAWSErrorFromXmlContent.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to( bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
ParseAWSErrorFromXmlContent.class); ParseAWSErrorFromXmlContent.class);
} }
@Override @Override
protected void bindRetryHandlers() { protected void bindRetryHandlers() {
bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to( bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to(
AWSRedirectionRetryHandler.class); AWSRedirectionRetryHandler.class);
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to( bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(
AWSClientErrorRetryHandler.class); AWSClientErrorRetryHandler.class);
} }
} }

View File

@ -36,14 +36,10 @@ public interface S3Constants extends AWSConstants, S3Headers {
public static final String MAX_KEYS = "max-keys"; public static final String MAX_KEYS = "max-keys";
public static final String DELIMITER = "delimiter"; public static final String DELIMITER = "delimiter";
public static final String PROPERTY_S3_ENDPOINT = "jclouds.s3.endpoint"; public static final String PROPERTY_S3_ENDPOINT = "jclouds.s3.endpoint";
public static final String PROPERTY_S3_REGIONS = "jclouds.s3.regions";
/** /**
* how long do we wait before obtaining a new timestamp for requests. * how long do we wait before obtaining a new timestamp for requests.
*/ */
public static final String PROPERTY_S3_SESSIONINTERVAL = "jclouds.s3.sessioninterval"; public static final String PROPERTY_S3_SESSIONINTERVAL = "jclouds.s3.sessioninterval";
public static final String PROPERTY_S3_ENDPOINT_EU_WEST_1 = "jclouds.s3.endpoint.eu_west_1";
public static final String PROPERTY_S3_ENDPOINT_US_STANDARD = "jclouds.s3.endpoint.us_standard";
public static final String PROPERTY_S3_ENDPOINT_US_WEST_1 = "jclouds.s3.endpoint.us_west_1";
public static final String PROPERTY_S3_ENDPOINT_AP_SOUTHEAST_1 = "jclouds.s3.endpoint.ap_southeast_1";
} }

View File

@ -0,0 +1,36 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "ec2.EucalyptusComputeServiceLiveTest")
public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
@BeforeClass
@Override
public void setServiceDefaults() {
service = "eucalyptus";
}
}

View File

@ -49,102 +49,111 @@ import com.google.common.collect.Iterables;
public class ImageParserTest extends BaseEC2HandlerTest { public class ImageParserTest extends BaseEC2HandlerTest {
public void testParseAlesticCanonicalImage() { public void testParseAlesticCanonicalImage() {
InputStream is = getClass().getResourceAsStream("/ec2/alestic_canonical.xml"); InputStream is = getClass().getResourceAsStream(
"/ec2/alestic_canonical.xml");
Set<Image> result = parseImages(is); Set<Image> result = parseImages(is);
assertEquals(result.size(), 7); assertEquals(result.size(), 7);
ImageParser parser = new ImageParser( ImageParser parser = new ImageParser(
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableSet new EC2PopulateDefaultLoginCredentialsForImageStrategy(),
.<Location> of(defaultLocation), defaultLocation); ImmutableSet.<Location> of(defaultLocation), defaultLocation);
org.jclouds.compute.domain.Image ubuntuHardy = parser.apply(Iterables.get(result, 0)); org.jclouds.compute.domain.Image ubuntuHardy = parser.apply(Iterables
.get(result, 0));
assertEquals(ubuntuHardy.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32); assertEquals(ubuntuHardy.getArchitecture(),
org.jclouds.compute.domain.Architecture.X86_32);
assertEquals(ubuntuHardy.getDescription(), assertEquals(ubuntuHardy.getDescription(),
"ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml"); "ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml");
assertEquals(ubuntuHardy.getProviderId(), "ami-7e28ca17"); assertEquals(ubuntuHardy.getProviderId(), "ami-7e28ca17");
assertEquals(ubuntuHardy.getLocation(), defaultLocation); assertEquals(ubuntuHardy.getLocation(), defaultLocation);
assertEquals(ubuntuHardy.getName(), "8.04"); assertEquals(ubuntuHardy.getName(), "8.04");
assertEquals(ubuntuHardy.getOsDescription(), assertEquals(ubuntuHardy.getOsDescription(),
"ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml"); "ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml");
assertEquals(ubuntuHardy.getOsFamily(), OsFamily.UBUNTU); assertEquals(ubuntuHardy.getOsFamily(), OsFamily.UBUNTU);
assertEquals(ubuntuHardy.getUserMetadata(), ImmutableMap.<String, String> of("owner", assertEquals(ubuntuHardy.getUserMetadata(), ImmutableMap
"099720109477")); .<String, String> of("owner", "099720109477"));
assertEquals(ubuntuHardy.getVersion(), "20091130"); assertEquals(ubuntuHardy.getVersion(), "20091130");
org.jclouds.compute.domain.Image alesticKarmic = parser.apply(Iterables.get(result, 1)); org.jclouds.compute.domain.Image alesticKarmic = parser.apply(Iterables
.get(result, 1));
assertEquals(alesticKarmic.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32); assertEquals(alesticKarmic.getArchitecture(),
org.jclouds.compute.domain.Architecture.X86_32);
assertEquals(alesticKarmic.getDescription(), assertEquals(alesticKarmic.getDescription(),
"alestic/ubuntu-9.10-karmic-base-20090623.manifest.xml"); "alestic/ubuntu-9.10-karmic-base-20090623.manifest.xml");
assertEquals(alesticKarmic.getProviderId(), "ami-19a34270"); assertEquals(alesticKarmic.getProviderId(), "ami-19a34270");
assertEquals(alesticKarmic.getLocation(), defaultLocation); assertEquals(alesticKarmic.getLocation(), defaultLocation);
assertEquals(alesticKarmic.getName(), "9.10"); assertEquals(alesticKarmic.getName(), "9.10");
assertEquals(alesticKarmic.getOsDescription(), assertEquals(alesticKarmic.getOsDescription(),
"alestic/ubuntu-9.10-karmic-base-20090623.manifest.xml"); "alestic/ubuntu-9.10-karmic-base-20090623.manifest.xml");
assertEquals(alesticKarmic.getOsFamily(), OsFamily.UBUNTU); assertEquals(alesticKarmic.getOsFamily(), OsFamily.UBUNTU);
assertEquals(alesticKarmic.getUserMetadata(), ImmutableMap.<String, String> of("owner", assertEquals(alesticKarmic.getUserMetadata(), ImmutableMap
"063491364108")); .<String, String> of("owner", "063491364108"));
assertEquals(alesticKarmic.getVersion(), "20090623"); assertEquals(alesticKarmic.getVersion(), "20090623");
org.jclouds.compute.domain.Image ubuntuKarmic = parser.apply(Iterables
.get(result, 2));
assertEquals(ubuntuKarmic.getArchitecture(),
org.jclouds.compute.domain.Architecture.X86_32);
org.jclouds.compute.domain.Image ubuntuKarmic = parser.apply(Iterables.get(result, 2));
assertEquals(ubuntuKarmic.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32);
assertEquals(ubuntuKarmic.getDescription(), assertEquals(ubuntuKarmic.getDescription(),
"ubuntu-images-us/ubuntu-karmic-9.10-i386-server-20100121.manifest.xml"); "ubuntu-images-us/ubuntu-karmic-9.10-i386-server-20100121.manifest.xml");
assertEquals(ubuntuKarmic.getProviderId(), "ami-bb709dd2"); assertEquals(ubuntuKarmic.getProviderId(), "ami-bb709dd2");
assertEquals(ubuntuKarmic.getLocation(), defaultLocation); assertEquals(ubuntuKarmic.getLocation(), defaultLocation);
assertEquals(ubuntuKarmic.getName(), "9.10"); assertEquals(ubuntuKarmic.getName(), "9.10");
assertEquals(ubuntuKarmic.getOsDescription(), assertEquals(ubuntuKarmic.getOsDescription(),
"ubuntu-images-us/ubuntu-karmic-9.10-i386-server-20100121.manifest.xml"); "ubuntu-images-us/ubuntu-karmic-9.10-i386-server-20100121.manifest.xml");
assertEquals(ubuntuKarmic.getOsFamily(), OsFamily.UBUNTU); assertEquals(ubuntuKarmic.getOsFamily(), OsFamily.UBUNTU);
assertEquals(ubuntuKarmic.getUserMetadata(), ImmutableMap.<String, String> of("owner", assertEquals(ubuntuKarmic.getUserMetadata(), ImmutableMap
"099720109477")); .<String, String> of("owner", "099720109477"));
assertEquals(ubuntuKarmic.getVersion(), "20100121"); assertEquals(ubuntuKarmic.getVersion(), "20100121");
// should skip testing image // should skip testing image
assert parser.apply(Iterables.get(result, 3)) == null; assert parser.apply(Iterables.get(result, 3)) == null;
org.jclouds.compute.domain.Image alesticHardy = parser.apply(Iterables.get(result, 4)); org.jclouds.compute.domain.Image alesticHardy = parser.apply(Iterables
.get(result, 4));
assertEquals(alesticHardy.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32); assertEquals(alesticHardy.getArchitecture(),
org.jclouds.compute.domain.Architecture.X86_32);
assertEquals(alesticHardy.getDescription(), assertEquals(alesticHardy.getDescription(),
"alestic/ubuntu-8.04-hardy-base-20080905.manifest.xml"); "alestic/ubuntu-8.04-hardy-base-20080905.manifest.xml");
assertEquals(alesticHardy.getProviderId(), "ami-c0fa1ea9"); assertEquals(alesticHardy.getProviderId(), "ami-c0fa1ea9");
assertEquals(alesticHardy.getLocation(), defaultLocation); assertEquals(alesticHardy.getLocation(), defaultLocation);
assertEquals(alesticHardy.getName(), "8.04"); assertEquals(alesticHardy.getName(), "8.04");
assertEquals(alesticHardy.getOsDescription(), assertEquals(alesticHardy.getOsDescription(),
"alestic/ubuntu-8.04-hardy-base-20080905.manifest.xml"); "alestic/ubuntu-8.04-hardy-base-20080905.manifest.xml");
assertEquals(alesticHardy.getOsFamily(), OsFamily.UBUNTU); assertEquals(alesticHardy.getOsFamily(), OsFamily.UBUNTU);
assertEquals(alesticHardy.getUserMetadata(), ImmutableMap.<String, String> of("owner", assertEquals(alesticHardy.getUserMetadata(), ImmutableMap
"063491364108")); .<String, String> of("owner", "063491364108"));
assertEquals(alesticHardy.getVersion(), "20080905"); assertEquals(alesticHardy.getVersion(), "20080905");
org.jclouds.compute.domain.Image ubuntuLucid = parser.apply(Iterables.get(result, 5)); org.jclouds.compute.domain.Image ubuntuLucid = parser.apply(Iterables
.get(result, 5));
assertEquals(ubuntuLucid.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32); assertEquals(ubuntuLucid.getArchitecture(),
assertEquals(ubuntuLucid.getDescription(), org.jclouds.compute.domain.Architecture.X86_32);
"ubuntu-images-us-west-1/ubuntu-lucid-10.04-i386-server-20100427.1.manifest.xml"); assertEquals(
ubuntuLucid.getDescription(),
"ubuntu-images-us-west-1/ubuntu-lucid-10.04-i386-server-20100427.1.manifest.xml");
assertEquals(ubuntuLucid.getProviderId(), "ami-c597c680"); assertEquals(ubuntuLucid.getProviderId(), "ami-c597c680");
assertEquals(ubuntuLucid.getLocation(), defaultLocation); assertEquals(ubuntuLucid.getLocation(), defaultLocation);
assertEquals(ubuntuLucid.getName(), "10.04"); assertEquals(ubuntuLucid.getName(), "10.04");
assertEquals(ubuntuLucid.getOsDescription(), assertEquals(
"ubuntu-images-us-west-1/ubuntu-lucid-10.04-i386-server-20100427.1.manifest.xml"); ubuntuLucid.getOsDescription(),
"ubuntu-images-us-west-1/ubuntu-lucid-10.04-i386-server-20100427.1.manifest.xml");
assertEquals(ubuntuLucid.getOsFamily(), OsFamily.UBUNTU); assertEquals(ubuntuLucid.getOsFamily(), OsFamily.UBUNTU);
assertEquals(ubuntuLucid.getUserMetadata(), ImmutableMap.<String, String> of("owner", assertEquals(ubuntuLucid.getUserMetadata(), ImmutableMap
"099720109477")); .<String, String> of("owner", "099720109477"));
assertEquals(ubuntuLucid.getVersion(), "20100427.1"); assertEquals(ubuntuLucid.getVersion(), "20100427.1");
// should skip kernel // should skip kernel
assert parser.apply(Iterables.get(result, 6)) == null; assert parser.apply(Iterables.get(result, 6)) == null;
} }
private Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1", private Location defaultLocation = new LocationImpl(LocationScope.REGION,
"us-east-1", null); "us-east-1", "us-east-1", null);
public void testParseVostokImage() { public void testParseVostokImage() {
InputStream is = getClass().getResourceAsStream("/ec2/vostok.xml"); InputStream is = getClass().getResourceAsStream("/ec2/vostok.xml");
@ -152,68 +161,122 @@ public class ImageParserTest extends BaseEC2HandlerTest {
Set<Image> result = parseImages(is); Set<Image> result = parseImages(is);
ImageParser parser = new ImageParser( ImageParser parser = new ImageParser(
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableSet new EC2PopulateDefaultLoginCredentialsForImageStrategy(),
.<Location> of(defaultLocation), defaultLocation); ImmutableSet.<Location> of(defaultLocation), defaultLocation);
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0)); org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(
result, 0));
assertEquals(image.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32); assertEquals(image.getArchitecture(),
org.jclouds.compute.domain.Architecture.X86_32);
assertEquals(image.getDescription(), assertEquals(image.getDescription(),
"vostok-builds/vostok-0.95-5622/vostok-0.95-5622.manifest.xml"); "vostok-builds/vostok-0.95-5622/vostok-0.95-5622.manifest.xml");
assertEquals(image.getProviderId(), "ami-870de2ee"); assertEquals(image.getProviderId(), "ami-870de2ee");
assertEquals(image.getLocation(), defaultLocation); assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), ""); assertEquals(image.getName(), "");
assertEquals(image.getOsDescription(), assertEquals(image.getOsDescription(),
"vostok-builds/vostok-0.95-5622/vostok-0.95-5622.manifest.xml"); "vostok-builds/vostok-0.95-5622/vostok-0.95-5622.manifest.xml");
assertEquals(image.getOsFamily(), null); assertEquals(image.getOsFamily(), null);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of(
"133804938231")); "owner", "133804938231"));
assertEquals(image.getVersion(), ""); assertEquals(image.getVersion(), "");
} }
public void testParseRightScaleImage() { public void testParseRightScaleImage() {
InputStream is = getClass().getResourceAsStream("/ec2/rightscale_images.xml"); InputStream is = getClass().getResourceAsStream(
"/ec2/rightscale_images.xml");
Set<Image> result = parseImages(is); Set<Image> result = parseImages(is);
ImageParser parser = new ImageParser( ImageParser parser = new ImageParser(
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableSet new EC2PopulateDefaultLoginCredentialsForImageStrategy(),
.<Location> of(defaultLocation), defaultLocation); ImmutableSet.<Location> of(defaultLocation), defaultLocation);
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0)); org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(
result, 0));
assertEquals(image.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_64); assertEquals(image.getArchitecture(),
assertEquals(image.getDescription(), "rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml"); org.jclouds.compute.domain.Architecture.X86_64);
assertEquals(image.getDescription(),
"rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml");
assertEquals(image.getProviderId(), "ami-ccb35ea5"); assertEquals(image.getProviderId(), "ami-ccb35ea5");
assertEquals(image.getLocation(), defaultLocation); assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), "5.4"); assertEquals(image.getName(), "5.4");
assertEquals(image.getOsDescription(), assertEquals(image.getOsDescription(),
"rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml"); "rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml");
assertEquals(image.getOsFamily(), OsFamily.CENTOS); assertEquals(image.getOsFamily(), OsFamily.CENTOS);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of(
"411009282317")); "owner", "411009282317"));
assertEquals(image.getVersion(), "4.4.10"); assertEquals(image.getVersion(), "4.4.10");
image = parser.apply(Iterables.get(result, 1)); image = parser.apply(Iterables.get(result, 1));
assertEquals(image.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_64); assertEquals(image.getArchitecture(),
assertEquals(image.getDescription(), "RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha"); org.jclouds.compute.domain.Architecture.X86_64);
assertEquals(image.getDescription(),
"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha");
assertEquals(image.getProviderId(), "ami-c19db6b5"); assertEquals(image.getProviderId(), "ami-c19db6b5");
assertEquals(image.getLocation(), defaultLocation); assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), "9.10"); assertEquals(image.getName(), "9.10");
assertEquals(image.getOsDescription(), assertEquals(image.getOsDescription(),
"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha"); "411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha");
assertEquals(image.getOsFamily(), OsFamily.UBUNTU); assertEquals(image.getOsFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of("owner", assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of(
"411009282317")); "owner", "411009282317"));
assertEquals(image.getVersion(), "4.5.3_EBS_Alpha"); assertEquals(image.getVersion(), "4.5.3_EBS_Alpha");
} }
public void testParseEucalyptusImage() {
InputStream is = getClass().getResourceAsStream(
"/ec2/eucalyptus_images.xml");
Set<Image> result = parseImages(is);
assertEquals(result.size(), 11);
ImageParser parser = new ImageParser(
new EC2PopulateDefaultLoginCredentialsForImageStrategy(),
ImmutableSet.<Location> of(defaultLocation), defaultLocation);
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(
result, 0));
assertEquals(image.getArchitecture(),
org.jclouds.compute.domain.Architecture.X86_64);
assertEquals(image.getDescription(),
"centos-5.3-x86_64/centos.5-3.x86-64.img.manifest.xml");
assertEquals(image.getProviderId(), "emi-9ACB1363");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), "5.3");
assertEquals(image.getOsDescription(),
"centos-5.3-x86_64/centos.5-3.x86-64.img.manifest.xml");
assertEquals(image.getOsFamily(), OsFamily.CENTOS);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of(
"owner", "admin"));
assertEquals(image.getVersion(), "");
image = parser.apply(Iterables.get(result, 6));
assertEquals(image.getDescription(),
"Lean/ubuntu.9-04.x86-64.img.manifest.xml");
assertEquals(image.getArchitecture(),
org.jclouds.compute.domain.Architecture.X86_64);
assertEquals(image.getDescription(),
"Lean/ubuntu.9-04.x86-64.img.manifest.xml");
assertEquals(image.getProviderId(), "emi-CBEA100C");
assertEquals(image.getLocation(), defaultLocation);
assertEquals(image.getName(), "9.04");
assertEquals(image.getOsDescription(),
"Lean/ubuntu.9-04.x86-64.img.manifest.xml");
assertEquals(image.getOsFamily(), OsFamily.UBUNTU);
assertEquals(image.getUserMetadata(), ImmutableMap.<String, String> of(
"owner", "mashaobing1"));
assertEquals(image.getVersion(), "");
}
private Set<Image> parseImages(InputStream is) { private Set<Image> parseImages(InputStream is) {
DescribeImagesResponseHandler handler = injector DescribeImagesResponseHandler handler = injector
.getInstance(DescribeImagesResponseHandler.class); .getInstance(DescribeImagesResponseHandler.class);
addDefaultRegionToHandler(handler); addDefaultRegionToHandler(handler);
Set<Image> result = factory.create(handler).parse(is); Set<Image> result = factory.create(handler).parse(is);
return result; return result;

View File

@ -29,6 +29,7 @@ import org.jclouds.aws.ec2.EC2;
import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.config.ParserModule; import org.jclouds.http.functions.config.ParserModule;
import org.jclouds.util.Utils;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -50,7 +51,8 @@ public class DescribeRegionsResponseHandlerTest extends BaseHandlerTest {
@Override @Override
protected void configure() { protected void configure() {
bind(URI.class).annotatedWith(EC2.class).toInstance(URI.create("https://booya")); bind(URI.class).annotatedWith(EC2.class).toInstance(
URI.create("https://booya"));
} }
}); });
@ -60,31 +62,57 @@ public class DescribeRegionsResponseHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() { public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/ec2/regionEndpoints.xml"); InputStream is = getClass().getResourceAsStream(
"/ec2/regionEndpoints.xml");
Map<String, URI> expected = ImmutableMap.<String, URI> of(Region.EU_WEST_1, URI Map<String, URI> expected = ImmutableMap
.create("https://ec2.eu-west-1.amazonaws.com"), Region.US_EAST_1, URI .<String, URI> of(Region.EU_WEST_1, URI
.create("https://ec2.us-east-1.amazonaws.com"), Region.US_WEST_1, URI .create("https://ec2.eu-west-1.amazonaws.com"),
.create("https://ec2.us-west-1.amazonaws.com")); Region.US_EAST_1, URI
.create("https://ec2.us-east-1.amazonaws.com"),
Region.US_WEST_1, URI
.create("https://ec2.us-west-1.amazonaws.com"));
Map<String, URI> result = factory.create( Map<String, URI> result = factory.create(
injector.getInstance(DescribeRegionsResponseHandler.class)).parse(is); injector.getInstance(DescribeRegionsResponseHandler.class)).parse(
is);
assertEquals(result, expected);
}
public void testEuc() {
InputStream is = Utils
.toInputStream("<DescribeRegionsResponse xmlns=\"http://ec2.amazonaws.com/doc/2009-11-30/\"><requestId>6a3b36f9-9ff4-47cf-87e3-285b08fbe5e5</requestId><regionInfo><item><regionName>Eucalyptus</regionName><regionEndpoint>http://173.205.188.130:8773/services/Eucalyptus</regionEndpoint></item><item><regionName>Walrus</regionName><regionEndpoint>http://173.205.188.130:8773/services/Walrus</regionEndpoint></item></regionInfo></DescribeRegionsResponse>");
Map<String, URI> expected = ImmutableMap.<String, URI> of("Eucalyptus",
URI.create("http://173.205.188.130:8773/services/Eucalyptus"));
Map<String, URI> result = factory.create(
injector.getInstance(DescribeRegionsResponseHandler.class)).parse(
is);
assertEquals(result, expected); assertEquals(result, expected);
} }
public void testUnsupportedAdditionalRegionDoesntBreak() { public void testUnsupportedAdditionalRegionDoesntBreak() {
InputStream is = getClass().getResourceAsStream("/ec2/regionEndpoints-additional.xml"); InputStream is = getClass().getResourceAsStream(
"/ec2/regionEndpoints-additional.xml");
Map<String, URI> expected = ImmutableMap.<String, URI> of("jp-west-1", URI Map<String, URI> expected = ImmutableMap
.create("https://ec2.jp-west-1.amazonaws.com"), Region.EU_WEST_1, URI .<String, URI> of("jp-west-1", URI
.create("https://ec2.eu-west-1.amazonaws.com"), Region.US_EAST_1, URI .create("https://ec2.jp-west-1.amazonaws.com"),
.create("https://ec2.us-east-1.amazonaws.com"), Region.US_WEST_1, URI Region.EU_WEST_1, URI
.create("https://ec2.us-west-1.amazonaws.com")); .create("https://ec2.eu-west-1.amazonaws.com"),
Region.US_EAST_1, URI
.create("https://ec2.us-east-1.amazonaws.com"),
Region.US_WEST_1, URI
.create("https://ec2.us-west-1.amazonaws.com"));
Map<String, URI> result = factory.create( Map<String, URI> result = factory.create(
injector.getInstance(DescribeRegionsResponseHandler.class)).parse(is); injector.getInstance(DescribeRegionsResponseHandler.class)).parse(
is);
assertEquals(result, expected); assertEquals(result, expected);
} }

View File

@ -0,0 +1,189 @@
<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
<requestId>7b893acf-7752-4e
2c-8c1a-3287a011b0df</requestId>
<imagesSet>
<item>
<imageId>emi-9ACB1363</imageId>
<imageLocation>centos-5.3-x86_64/centos.5-3.x86-64.img.manifest.xml
</imageLocation>
<imageState>available
</imageState>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>x86_64</architecture>
<imageType>
machine
</imageType>
<kernelId>eki-6CBD12F2</kernelId>
<ramdiskId>eri-A97113E4</ramdiskId>
<rootDeviceType>instance-store</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>emi-D2D610D1</imageId>
<imageLocation>martin_try1/martin_try1.manifest.xml</imageLocation>
<imageState>
available
</imageState>
<imageOwnerId>dominic</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>x86_64</architecture>
<imageType>machine</imageType>
<kernelId>eki-6CBD12F2</kernelId>
<ramdiskId>eri-A97113E4</ramdiskId>
<rootDeviceType>instance-store</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>eri-A97113E4</imageId>
<imageLocation>initrd-64/initrd.img-2.6.28-11-generic.manifest.xml
</imageLocation>
<imageState>available</imageState>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>x86_64</architecture>
<imageType>ramdisk</imageType>
<rootDeviceType>
instance-store
</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>emi-B9A40FF6</imageId>
<imageLocation>ulteo4/ubuntu804-32-test.manifest.xml</imageLocation>
<imageState>available</imageState>
<imageOwnerId>gaelduval</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>
i386
</architecture>
<imageType>machine</imageType>
<rootDeviceType>instance-store</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>
emi-D1991835
</imageId>
<imageLocation>jamestyj-test/Eucalyptus_Guest.x86_64-0.0.2.raw.manifest.xml
</imageLocation>
<imageState>available</imageState>
<imageOwnerId>jamestyj</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>x86_64</architecture>
<imageType>machine</imageType>
<rootDeviceType>
instance-store
</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>emi-D8AB1044</imageId>
<imageLocation>test/ubuntu.9-04.x86-64.img.manifest.xml
</imageLocation>
<imageState>available</imageState>
<imageOwnerId>mymq0206</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>
x86_64
</architecture>
<imageType>machine</imageType>
<rootDeviceType>instance-store</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>
emi-CBEA100C
</imageId>
<imageLocation>Lean/ubuntu.9-04.x86-64.img.manifest.xml
</imageLocation>
<imageState>available</imageState>
<imageOwnerId>
mashaobing1
</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>x86_64</architecture>
<imageType>machine</imageType>
<kernelId>eki-6CBD12F2</kernelId>
<ramdiskId>eri-A97113E4</ramdiskId>
<rootDeviceType>instance-store</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>emi-D176182B</imageId>
<imageLocation>jamestyj-test/Eucalyptus_Guest.x86_64-0.0.3.raw.manifest.xml
</imageLocation>
<imageState>available</imageState>
<imageOwnerId>
jamestyj
</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>x86_64</architecture>
<imageType>machine</imageType>
<rootDeviceType>instance-store</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>emi-D25E10CA</imageId>
<imageLocation>
biolinux/biolinux.qcow2.manifest.xml
</imageLocation>
<imageState>available</imageState>
<imageOwnerId>brainstorm</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>x86_64</architecture>
<imageType>machine</imageType>
<rootDeviceType>instance-store</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>
eki-6CBD12F2
</imageId>
<imageLocation>kernel-64/vmlinuz-2.6.28-11-generic.manifest.xml
</imageLocation>
<imageState>available</imageState>
<imageOwnerId>admin</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>x86_64</architecture>
<imageType>kernel</imageType>
<rootDeviceType>instance-store</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
<item>
<imageId>emi-2EDC1606</imageId>
<imageLocation>
ulteo2/Ulteo-SM-Scalability-Test-19feb2010.manifest.xml
</imageLocation>
<imageState>available</imageState>
<imageOwnerId>gaelduval</imageOwnerId>
<isPublic>true</isPublic>
<productCodes />
<architecture>i386</architecture>
<imageType>machine</imageType>
<rootDeviceType>instance-store</rootDeviceType>
<rootDeviceName>/dev/sda1</rootDeviceName>
<blockDeviceMapping />
</item>
</imagesSet>
</DescribeImagesResponse>

View File

@ -82,6 +82,7 @@
</layout> </layout>
</appender> </appender>
<!-- A time/date based rolling appender --> <!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender"> <appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" /> <param name="File" value="target/test-data/jclouds-compute.log" />
@ -145,6 +146,12 @@
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />
</category> </category>
<category name="jclouds.signature">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<!-- ======================= --> <!-- ======================= -->
<!-- Setup the Root category --> <!-- Setup the Root category -->
<!-- ======================= --> <!-- ======================= -->

View File

@ -27,5 +27,7 @@ cloudfiles.contextbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesContextBuil
cloudfiles.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder cloudfiles.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder
s3.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder s3.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder
walrus.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
walrus.propertiesbuilder=org.jclouds.aws.s3.WalrusPropertiesBuilder
transient.contextbuilder=org.jclouds.blobstore.TransientBlobStoreContextBuilder transient.contextbuilder=org.jclouds.blobstore.TransientBlobStoreContextBuilder
transient.propertiesbuilder=org.jclouds.blobstore.TransientBlobStorePropertiesBuilder transient.propertiesbuilder=org.jclouds.blobstore.TransientBlobStorePropertiesBuilder

View File

@ -29,6 +29,7 @@ import java.util.Formatter;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -42,12 +43,14 @@ import javax.annotation.Resource;
import javax.inject.Named; import javax.inject.Named;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.concurrent.ConcurrentUtils; import org.jclouds.concurrent.ConcurrentUtils;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
@ -85,21 +88,73 @@ public class ComputeUtils {
private final ExecutorService executor; private final ExecutorService executor;
protected final Predicate<NodeMetadata> nodeRunning; protected final Predicate<NodeMetadata> nodeRunning;
private final GetNodeMetadataStrategy getNode; private final GetNodeMetadataStrategy getNode;
private final Timeouts timeouts;
public static final Map<org.jclouds.compute.domain.OsFamily, Map<String, String>> NAME_VERSION_MAP = ImmutableMap
.<org.jclouds.compute.domain.OsFamily, Map<String, String>> of(
org.jclouds.compute.domain.OsFamily.CENTOS, ImmutableMap
.<String, String> builder().put("5.3", "5.3").put("5.4",
"5.4").put("5.5", "5.5").build(),
org.jclouds.compute.domain.OsFamily.RHEL, ImmutableMap
.<String, String> builder().put("5.3", "5.3").put("5.4",
"5.4").put("5.5", "5.5").build(),
org.jclouds.compute.domain.OsFamily.UBUNTU, ImmutableMap
.<String, String> builder().put("hardy", "8.04").put(
"intrepid", "8.10").put("jaunty", "9.04").put(
"karmic", "9.10").put("lucid", "10.04").put(
"maverick", "10.10").build());
@Inject @Inject
public ComputeUtils( public ComputeUtils(
Predicate<IPSocket> socketTester, Predicate<IPSocket> socketTester,
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning, @Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning,
GetNodeMetadataStrategy getNode, GetNodeMetadataStrategy getNode, Timeouts timeouts,
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning, @Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
this.nodeRunning = nodeRunning; this.nodeRunning = nodeRunning;
this.timeouts = timeouts;
this.getNode = getNode; this.getNode = getNode;
this.socketTester = socketTester; this.socketTester = socketTester;
this.runScriptNotRunning = runScriptNotRunning; this.runScriptNotRunning = runScriptNotRunning;
this.executor = executor; this.executor = executor;
} }
public static String parseVersionOrReturnEmptyString(
org.jclouds.compute.domain.OsFamily family, final String in) {
if (NAME_VERSION_MAP.containsKey(family)) {
CONTAINS_SUBSTRING contains = new CONTAINS_SUBSTRING(in.replace('-',
'.'));
try {
String key = Iterables.find(NAME_VERSION_MAP.get(family).keySet(),
contains);
return NAME_VERSION_MAP.get(family).get(key);
} catch (NoSuchElementException e) {
try {
return Iterables.find(NAME_VERSION_MAP.get(family).values(),
contains);
} catch (NoSuchElementException e1) {
}
}
}
return "";
}
public static org.jclouds.compute.domain.OsFamily parseOsFamilyOrNull(
String in) {
org.jclouds.compute.domain.OsFamily myOs = null;
for (org.jclouds.compute.domain.OsFamily os : org.jclouds.compute.domain.OsFamily
.values()) {
if (in.toLowerCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) {
myOs = os;
}
}
return myOs;
}
public static Architecture parseArchitectureOrNull(String in) {
return in.indexOf("64") == -1 ? Architecture.X86_32 : Architecture.X86_64;
}
public static String createExecutionErrorMessage( public static String createExecutionErrorMessage(
Map<?, Exception> executionExceptions) { Map<?, Exception> executionExceptions) {
Formatter fmt = new Formatter().format("Execution failures:%n%n"); Formatter fmt = new Formatter().format("Execution failures:%n%n");
@ -179,7 +234,11 @@ public class ComputeUtils {
.getCredentials()); .getCredentials());
else else
throw new IllegalStateException( throw new IllegalStateException(
"node didn't achieve the state running: " + node); String
.format(
"node didn't achieve the state running on node %s within %d seconds, final state: %s",
node.getId(), timeouts.nodeRunning / 1000, node
.getState()));
List<SshCallable<?>> callables = Lists.newArrayList(); List<SshCallable<?>> callables = Lists.newArrayList();
if (options.getRunScript() != null) { if (options.getRunScript() != null) {
@ -331,6 +390,19 @@ public class ComputeUtils {
return actualResponses; return actualResponses;
} }
private static final class CONTAINS_SUBSTRING implements Predicate<String> {
private final String in;
private CONTAINS_SUBSTRING(String in) {
this.in = in;
}
@Override
public boolean apply(String input) {
return in.indexOf(input) != -1;
}
}
public static interface SshCallable<T> extends Callable<T> { public static interface SshCallable<T> extends Callable<T> {
NodeMetadata getNode(); NodeMetadata getNode();

View File

@ -26,6 +26,8 @@ vcloud.contextbuilder=org.jclouds.vcloud.VCloudContextBuilder
vcloud.propertiesbuilder=org.jclouds.vcloud.VCloudPropertiesBuilder vcloud.propertiesbuilder=org.jclouds.vcloud.VCloudPropertiesBuilder
ec2.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder ec2.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
eucalyptus.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
eucalyptus.propertiesbuilder=org.jclouds.aws.ec2.EucalyptusPropertiesBuilder
cloudservers.contextbuilder=org.jclouds.rackspace.cloudservers.CloudServersContextBuilder cloudservers.contextbuilder=org.jclouds.rackspace.cloudservers.CloudServersContextBuilder
cloudservers.propertiesbuilder=org.jclouds.rackspace.RackspacePropertiesBuilder cloudservers.propertiesbuilder=org.jclouds.rackspace.RackspacePropertiesBuilder
bluelock.contextbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudContextBuilder bluelock.contextbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudContextBuilder

View File

@ -36,6 +36,7 @@ import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.internal.ImageImpl; import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.concurrent.ConcurrentUtils; import org.jclouds.concurrent.ConcurrentUtils;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
@ -66,10 +67,10 @@ public class VCloudImageProvider implements Provider<Set<? extends Image>> {
@Inject @Inject
protected VCloudImageProvider( protected VCloudImageProvider(
VCloudClient client, VCloudClient client,
FindLocationForResourceInVDC findLocationForResourceInVDC, FindLocationForResourceInVDC findLocationForResourceInVDC,
PopulateDefaultLoginCredentialsForImageStrategy populateDefaultLoginCredentialsForImageStrategy, PopulateDefaultLoginCredentialsForImageStrategy populateDefaultLoginCredentialsForImageStrategy,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
this.client = client; this.client = client;
this.findLocationForResourceInVDC = findLocationForResourceInVDC; this.findLocationForResourceInVDC = findLocationForResourceInVDC;
this.populateDefaultLoginCredentialsForImageStrategy = populateDefaultLoginCredentialsForImageStrategy; this.populateDefaultLoginCredentialsForImageStrategy = populateDefaultLoginCredentialsForImageStrategy;
@ -80,44 +81,44 @@ public class VCloudImageProvider implements Provider<Set<? extends Image>> {
public Set<? extends Image> get() { public Set<? extends Image> get() {
final Set<Image> images = Sets.newHashSet(); final Set<Image> images = Sets.newHashSet();
logger.debug(">> providing vAppTemplates"); logger.debug(">> providing vAppTemplates");
for (final NamedResource vDC : client.getDefaultOrganization().getVDCs().values()) { for (final NamedResource vDC : client.getDefaultOrganization().getVDCs()
Map<String, NamedResource> resources = client.getVDC(vDC.getId()).getResourceEntities(); .values()) {
Map<String, NamedResource> resources = client.getVDC(vDC.getId())
.getResourceEntities();
Map<String, ListenableFuture<Void>> responses = Maps.newHashMap(); Map<String, ListenableFuture<Void>> responses = Maps.newHashMap();
for (final NamedResource resource : resources.values()) { for (final NamedResource resource : resources.values()) {
if (resource.getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) { if (resource.getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) {
responses.put(resource.getName(), ConcurrentUtils.makeListenable(executor responses.put(resource.getName(), ConcurrentUtils
.submit(new Callable<Void>() { .makeListenable(executor.submit(new Callable<Void>() {
@Override @Override
public Void call() throws Exception { public Void call() throws Exception {
OsFamily myOs = null; OsFamily myOs = ComputeUtils
for (OsFamily os : OsFamily.values()) { .parseOsFamilyOrNull(resource.getName());
if (resource.getName().toLowerCase().replaceAll("\\s", "") Architecture arch = ComputeUtils
.indexOf(os.toString()) != -1) { .parseArchitectureOrNull(resource.getName());
myOs = os;
}
}
Architecture arch = resource.getName().indexOf("64") == -1 ? Architecture.X86_32
: Architecture.X86_64;
VAppTemplate template = client.getVAppTemplate(resource.getId());
Location location = findLocationForResourceInVDC.apply(resource, vDC VAppTemplate template = client
.getId()); .getVAppTemplate(resource.getId());
String name = getName(template.getName());
images.add(new ImageImpl(resource.getId(), name, resource.getId(), Location location = findLocationForResourceInVDC
location, template.getLocation(), ImmutableMap .apply(resource, vDC.getId());
.<String, String> of(), template.getDescription(), String name = getName(template.getName());
"", myOs, name, arch, images.add(new ImageImpl(resource.getId(), name,
populateDefaultLoginCredentialsForImageStrategy resource.getId(), location, template
.execute(template))); .getLocation(), ImmutableMap
return null; .<String, String> of(), template
} .getDescription(), "", myOs, name, arch,
}), executor)); populateDefaultLoginCredentialsForImageStrategy
.execute(template)));
return null;
}
}), executor));
} }
} }
ConcurrentUtils.awaitCompletion(responses, executor, null, logger, "vAppTemplates in " ConcurrentUtils.awaitCompletion(responses, executor, null, logger,
+ vDC); "vAppTemplates in " + vDC);
} }
return images; return images;
} }