mirror of https://github.com/apache/jclouds.git
Issue 448: new EC2 EBS support
This commit is contained in:
parent
5a044b3c0e
commit
a1dbbd203c
|
@ -69,6 +69,8 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
|
|||
eTo.securityGroups(eFrom.getGroupIds());
|
||||
if (eFrom.getKeyPair() != null)
|
||||
eTo.keyPair(eFrom.getKeyPair());
|
||||
if (eFrom.getBlockDeviceMappings().size() > 0)
|
||||
eTo.blockDeviceMappings(eFrom.getBlockDeviceMappings());
|
||||
if (!eFrom.shouldAutomaticallyCreateKeyPair())
|
||||
eTo.noKeyPair();
|
||||
if (eFrom.getUserData() != null)
|
||||
|
|
|
@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -123,34 +122,34 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
* Specifies the block device mappings to be used to run the instance
|
||||
*/
|
||||
public EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId,
|
||||
@Nullable Integer sizeInGib, @Nullable Boolean deleteOnTermination) {
|
||||
@Nullable Integer sizeInGib, boolean deleteOnTermination) {
|
||||
checkNotNull(deviceName, "deviceName cannot be null");
|
||||
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
|
||||
checkNotNull(snapshotId, "snapshotId cannot be null");
|
||||
Preconditions2.checkNotEmpty(snapshotId, "snapshotId must be non-empty");
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
|
||||
.<BlockDeviceMapping> builder();
|
||||
mappings.addAll(blockDeviceMappings);
|
||||
MapEBSSnapshotToDevice mapping = new MapEBSSnapshotToDevice(deviceName, snapshotId, sizeInGib,
|
||||
deleteOnTermination);
|
||||
mappings.add(mapping);
|
||||
blockDeviceMappings = ImmutableSet.copyOf(mappings);
|
||||
blockDeviceMappings = mappings.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the block device mappings to be used to run the instance
|
||||
*/
|
||||
public EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, Integer sizeInGib,
|
||||
@Nullable Boolean deleteOnTermination) {
|
||||
public EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib, boolean deleteOnTermination) {
|
||||
checkNotNull(deviceName, "deviceName cannot be null");
|
||||
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
|
||||
checkNotNull(sizeInGib, "sizeInGib cannot be null");
|
||||
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
|
||||
.<BlockDeviceMapping> builder();
|
||||
mappings.addAll(blockDeviceMappings);
|
||||
MapNewVolumeToDevice mapping = new MapNewVolumeToDevice(deviceName, sizeInGib, deleteOnTermination);
|
||||
mappings.add(mapping);
|
||||
blockDeviceMappings = ImmutableSet.copyOf(mappings);
|
||||
blockDeviceMappings = mappings.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -163,11 +162,12 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
checkNotNull(virtualName, "virtualName cannot be null");
|
||||
Preconditions2.checkNotEmpty(virtualName, "virtualName must be non-empty");
|
||||
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
|
||||
.<BlockDeviceMapping> builder();
|
||||
mappings.addAll(blockDeviceMappings);
|
||||
MapEphemeralDeviceToDevice mapping = new MapEphemeralDeviceToDevice(deviceName, virtualName);
|
||||
mappings.add(mapping);
|
||||
blockDeviceMappings = ImmutableSet.copyOf(mappings);
|
||||
blockDeviceMappings = mappings.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -178,11 +178,12 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
checkNotNull(deviceName, "deviceName cannot be null");
|
||||
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
|
||||
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
com.google.common.collect.ImmutableSet.Builder<BlockDeviceMapping> mappings = ImmutableSet
|
||||
.<BlockDeviceMapping> builder();
|
||||
mappings.addAll(blockDeviceMappings);
|
||||
UnmapDeviceNamed mapping = new UnmapDeviceNamed(deviceName);
|
||||
mappings.add(mapping);
|
||||
blockDeviceMappings = ImmutableSet.copyOf(mappings);
|
||||
blockDeviceMappings = mappings.build();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -195,6 +196,47 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
}
|
||||
|
||||
public static class Builder {
|
||||
/**
|
||||
* @see EC2TemplateOptions#blockDeviceMappings
|
||||
*/
|
||||
public static EC2TemplateOptions blockDeviceMappings(Set<? extends BlockDeviceMapping> blockDeviceMappings) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.blockDeviceMappings(blockDeviceMappings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#mapEBSSnapshotToDeviceName
|
||||
*/
|
||||
public static EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId,
|
||||
@Nullable Integer sizeInGib, boolean deleteOnTermination) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.mapEBSSnapshotToDeviceName(deviceName, snapshotId, sizeInGib, deleteOnTermination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#mapNewVolumeToDeviceName
|
||||
*/
|
||||
public static EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib,
|
||||
boolean deleteOnTermination) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.mapNewVolumeToDeviceName(deviceName, sizeInGib, deleteOnTermination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#mapEphemeralDeviceToDeviceName
|
||||
*/
|
||||
public static EC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.mapEphemeralDeviceToDeviceName(deviceName, virtualName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#unmapDeviceNamed
|
||||
*/
|
||||
public static EC2TemplateOptions unmapDeviceNamed(String deviceName) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return options.unmapDeviceNamed(deviceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#securityGroups(Iterable<String>)
|
||||
|
@ -494,8 +536,7 @@ public class EC2TemplateOptions extends TemplateOptions {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "EC2TemplateOptions [groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair
|
||||
+ ", userData=" + Arrays.toString(userData) + ", blockDeviceMappings=" + blockDeviceMappings + "]";
|
||||
return "[groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", userData="
|
||||
+ Arrays.toString(userData) + ", blockDeviceMappings=" + blockDeviceMappings + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
|||
String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, template.getOptions());
|
||||
|
||||
addSecurityGroups(region, tag, template, instanceOptions);
|
||||
if (template.getOptions() instanceof EC2TemplateOptions) {
|
||||
|
||||
if (keyPairName != null)
|
||||
instanceOptions.withKeyName(keyPairName);
|
||||
|
@ -90,11 +91,12 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
|
|||
|
||||
Set<BlockDeviceMapping> blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions())
|
||||
.getBlockDeviceMappings();
|
||||
if (blockDeviceMappings != null && blockDeviceMappings.size() > 0) {
|
||||
if (blockDeviceMappings.size() > 0) {
|
||||
checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")),
|
||||
"BlockDeviceMapping only available on ebs boot");
|
||||
instanceOptions.withBlockDeviceMappings(blockDeviceMappings);
|
||||
}
|
||||
}
|
||||
return instanceOptions;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ public class BlockDevice {
|
|||
private final boolean deleteOnTermination;
|
||||
|
||||
public BlockDevice(String volumeId, Status attachmentStatus, Date attachTime, boolean deleteOnTermination) {
|
||||
super();
|
||||
this.volumeId = volumeId;
|
||||
this.attachmentStatus = attachmentStatus;
|
||||
this.attachTime = attachTime;
|
||||
|
|
|
@ -42,15 +42,15 @@ public class BlockDeviceMapping {
|
|||
private static final Integer VOLUME_SIZE_MIN_VALUE = 1;
|
||||
private static final Integer VOLUME_SIZE_MAX_VALUE = 1000;
|
||||
|
||||
public BlockDeviceMapping(String deviceName, @Nullable String virtualName, @Nullable String snapshotId,
|
||||
BlockDeviceMapping(String deviceName, @Nullable String virtualName, @Nullable String snapshotId,
|
||||
@Nullable Integer sizeInGib, @Nullable Boolean noDevice, @Nullable Boolean deleteOnTermination) {
|
||||
|
||||
checkNotNull(deviceName, "deviceName cannot be null");
|
||||
Preconditions2.checkNotEmpty(deviceName, "the deviceName must be non-empty");
|
||||
|
||||
if (sizeInGib != null) {
|
||||
checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE),
|
||||
String.format("Size in Gib must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE));
|
||||
checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE), String.format(
|
||||
"Size in Gib must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE));
|
||||
}
|
||||
this.deviceName = deviceName;
|
||||
this.virtualName = virtualName;
|
||||
|
@ -88,7 +88,12 @@ public class BlockDeviceMapping {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((deleteOnTermination == null) ? 0 : deleteOnTermination.hashCode());
|
||||
result = prime * result + ((deviceName == null) ? 0 : deviceName.hashCode());
|
||||
result = prime * result + ((noDevice == null) ? 0 : noDevice.hashCode());
|
||||
result = prime * result + ((sizeInGib == null) ? 0 : sizeInGib.hashCode());
|
||||
result = prime * result + ((snapshotId == null) ? 0 : snapshotId.hashCode());
|
||||
result = prime * result + ((virtualName == null) ? 0 : virtualName.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -101,19 +106,44 @@ public class BlockDeviceMapping {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BlockDeviceMapping other = (BlockDeviceMapping) obj;
|
||||
if (deleteOnTermination == null) {
|
||||
if (other.deleteOnTermination != null)
|
||||
return false;
|
||||
} else if (!deleteOnTermination.equals(other.deleteOnTermination))
|
||||
return false;
|
||||
if (deviceName == null) {
|
||||
if (other.deviceName != null)
|
||||
return false;
|
||||
} else if (!deviceName.equals(other.deviceName))
|
||||
return false;
|
||||
if (noDevice == null) {
|
||||
if (other.noDevice != null)
|
||||
return false;
|
||||
} else if (!noDevice.equals(other.noDevice))
|
||||
return false;
|
||||
if (sizeInGib == null) {
|
||||
if (other.sizeInGib != null)
|
||||
return false;
|
||||
} else if (!sizeInGib.equals(other.sizeInGib))
|
||||
return false;
|
||||
if (snapshotId == null) {
|
||||
if (other.snapshotId != null)
|
||||
return false;
|
||||
} else if (!snapshotId.equals(other.snapshotId))
|
||||
return false;
|
||||
if (virtualName == null) {
|
||||
if (other.virtualName != null)
|
||||
return false;
|
||||
} else if (!virtualName.equals(other.virtualName))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BlockDeviceMapping [deviceName=" + deviceName + ", virtualName=" + virtualName + ", snapshotId="
|
||||
+ snapshotId + ", sizeInGib=" + sizeInGib + ", noDevice=" + noDevice + ", deleteOnTermination="
|
||||
+ deleteOnTermination + "]";
|
||||
return "[deviceName=" + deviceName + ", virtualName=" + virtualName + ", snapshotId=" + snapshotId
|
||||
+ ", sizeInGib=" + sizeInGib + ", noDevice=" + noDevice + ", deleteOnTermination=" + deleteOnTermination
|
||||
+ "]";
|
||||
}
|
||||
|
||||
public static class MapEBSSnapshotToDevice extends BlockDeviceMapping {
|
||||
|
|
|
@ -153,7 +153,7 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
|
|||
|
||||
public RunInstancesOptions withBlockDeviceMappings(Set<? extends BlockDeviceMapping> mappings) {
|
||||
int i = 1;
|
||||
for (BlockDeviceMapping mapping : mappings) {
|
||||
for (BlockDeviceMapping mapping : checkNotNull(mappings, "mappings")) {
|
||||
checkNotNull(mapping.getDeviceName(), "deviceName");
|
||||
formParameters.put(String.format("BlockDeviceMapping.%d.DeviceName", i), mapping.getDeviceName());
|
||||
if (mapping.getVirtualName() != null)
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.jclouds.ec2.compute;
|
|||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -34,10 +33,12 @@ import org.jclouds.compute.domain.Template;
|
|||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.ec2.EC2Client;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.AvailabilityZone;
|
||||
import org.jclouds.ec2.domain.BlockDevice;
|
||||
import org.jclouds.ec2.domain.InstanceType;
|
||||
import org.jclouds.ec2.domain.IpProtocol;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
|
@ -51,6 +52,7 @@ import org.jclouds.ec2.services.SecurityGroupClient;
|
|||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
@ -136,8 +138,8 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
assertEquals(instance.getKeyName(), tag);
|
||||
|
||||
// make sure we made our dummy group and also let in the user's group
|
||||
assertEquals(Sets.newTreeSet(instance.getGroupIds()),
|
||||
ImmutableSortedSet.<String> of("jclouds#" + tag + "#" + instance.getRegion(), tag));
|
||||
assertEquals(Sets.newTreeSet(instance.getGroupIds()), ImmutableSortedSet.<String> of("jclouds#" + tag + "#"
|
||||
+ instance.getRegion(), tag));
|
||||
|
||||
// make sure our dummy group has no rules
|
||||
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null,
|
||||
|
@ -145,8 +147,8 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
assert group.getIpPermissions().size() == 0 : group;
|
||||
|
||||
// try to run a script with the original keyPair
|
||||
runScriptWithCreds(tag, first.getOperatingSystem(),
|
||||
new Credentials(first.getCredentials().identity, result.getKeyMaterial()));
|
||||
runScriptWithCreds(tag, first.getOperatingSystem(), new Credentials(first.getCredentials().identity, result
|
||||
.getKeyMaterial()));
|
||||
|
||||
} finally {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
|
@ -159,235 +161,78 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
|
||||
public void testExtendedOptionsNoKeyPair() throws Exception {
|
||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getSecurityGroupServices();
|
||||
|
||||
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getKeyPairServices();
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
String tag = this.tag + "k";
|
||||
|
||||
TemplateOptions options = client.templateOptions();
|
||||
|
||||
options.as(EC2TemplateOptions.class).securityGroups(tag);
|
||||
options.as(EC2TemplateOptions.class).noKeyPair();
|
||||
|
||||
String startedId = null;
|
||||
try {
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||
|
||||
// create the security group
|
||||
securityGroupClient.createSecurityGroupInRegion(null, tag, tag);
|
||||
|
||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
|
||||
Credentials creds = nodes.iterator().next().getCredentials();
|
||||
assert creds == null;
|
||||
|
||||
startedId = Iterables.getOnlyElement(nodes).getProviderId();
|
||||
|
||||
RunningInstance instance = getInstance(instanceClient, startedId);
|
||||
|
||||
assertEquals(instance.getKeyName(), null);
|
||||
|
||||
// make sure we made our dummy group and also let in the user's group
|
||||
assertEquals(Sets.newTreeSet(instance.getGroupIds()),
|
||||
ImmutableSortedSet.<String> of(tag, String.format("jclouds#%s#%s", tag, instance.getRegion())));
|
||||
|
||||
// make sure our dummy group has no rules
|
||||
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null,
|
||||
String.format("jclouds#%s#%s", tag, instance.getRegion())));
|
||||
assert group.getIpPermissions().size() == 0 : group;
|
||||
|
||||
} finally {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
if (startedId != null) {
|
||||
// ensure we didn't delete these resources!
|
||||
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1);
|
||||
}
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note we cannot use the micro size as it has no ephemeral space.
|
||||
*/
|
||||
@Test(enabled = true)
|
||||
public void testMapNewVolumeToDeviceName() throws Exception {
|
||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getSecurityGroupServices();
|
||||
|
||||
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getKeyPairServices();
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
String tag = this.tag + "BDM1";
|
||||
int volumeSize = 120;
|
||||
TemplateOptions options = client.templateOptions();
|
||||
|
||||
options.as(EC2TemplateOptions.class).securityGroups(tag);
|
||||
options.as(EC2TemplateOptions.class).noKeyPair();
|
||||
options.as(EC2TemplateOptions.class).mapNewVolumeToDeviceName("/dev/sda1", volumeSize, true);
|
||||
|
||||
String startedId = null;
|
||||
try {
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||
|
||||
// create the security group
|
||||
securityGroupClient.createSecurityGroupInRegion(null, tag, tag);
|
||||
|
||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
|
||||
Credentials creds = nodes.iterator().next().getCredentials();
|
||||
assert creds == null;
|
||||
|
||||
NodeMetadata node = nodes.iterator().next();
|
||||
startedId = node.getId();
|
||||
|
||||
Map<String, BlockDevice> devices = instanceClient
|
||||
.getBlockDeviceMappingForInstanceInRegion(node.getLocation()
|
||||
.getParent().getId(), node.getProviderId());
|
||||
|
||||
BlockDevice device = devices.get("/dev/sda1");
|
||||
//check delete on termination
|
||||
assertTrue(device.isDeleteOnTermination());
|
||||
ElasticBlockStoreClient ebsClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getElasticBlockStoreServices();
|
||||
|
||||
Set<Volume> volumes = ebsClient.describeVolumesInRegion(node
|
||||
.getLocation().getParent().getId(), device.getVolumeId());
|
||||
// check volume size
|
||||
assertEquals(volumeSize, volumes.iterator().next().getSize());
|
||||
|
||||
} finally {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
if (startedId != null) {
|
||||
// ensure we didn't delete these resources!
|
||||
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1);
|
||||
}
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testMapEBSSnapshotToDeviceName() throws Exception {
|
||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getSecurityGroupServices();
|
||||
|
||||
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getKeyPairServices();
|
||||
public void testMapEBS() throws Exception {
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
ElasticBlockStoreClient ebsClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getElasticBlockStoreServices();
|
||||
//create snapshot
|
||||
Volume volume = ebsClient.createVolumeInAvailabilityZone(AvailabilityZone.US_EAST_1A, 4);
|
||||
|
||||
String tag = this.tag + "e";
|
||||
int volumeSize = 8;
|
||||
|
||||
Location zone = Iterables.find(context.getComputeService().listAssignableLocations(), new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location arg0) {
|
||||
return arg0.getScope() == LocationScope.ZONE;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// create volume only to make a snapshot
|
||||
Volume volume = ebsClient.createVolumeInAvailabilityZone(zone.getId(), 4);
|
||||
Snapshot snapshot = ebsClient.createSnapshotInRegion(volume.getRegion(), volume.getId());
|
||||
ebsClient.deleteVolumeInRegion(volume.getRegion(), volume.getId());
|
||||
|
||||
String tag = this.tag + "BDM2";
|
||||
int volumeSize = 120;
|
||||
TemplateOptions options = client.templateOptions();
|
||||
Template template = context.getComputeService().templateBuilder().locationId(volume.getRegion()).hardwareId(
|
||||
InstanceType.M1_SMALL).imageDescriptionMatches(".*ebs.*").build();
|
||||
|
||||
options.as(EC2TemplateOptions.class).securityGroups(tag);
|
||||
options.as(EC2TemplateOptions.class).noKeyPair();
|
||||
options.as(EC2TemplateOptions.class).mapEBSSnapshotToDeviceName("/dev/sda1", snapshot.getId(), 120, true);
|
||||
template.getOptions().as(EC2TemplateOptions.class)//
|
||||
// .unmapDeviceNamed("/dev/foo)
|
||||
.mapEphemeralDeviceToDeviceName("/dev/sdm", "ephemeral0")//
|
||||
.mapNewVolumeToDeviceName("/dev/sdn", volumeSize, true)//
|
||||
.mapEBSSnapshotToDeviceName("/dev/sdo", snapshot.getId(), volumeSize, true);
|
||||
|
||||
String startedId = null;
|
||||
try {
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||
NodeMetadata node = Iterables.getOnlyElement(client.runNodesWithTag(tag, 1, template));
|
||||
|
||||
// create the security group
|
||||
securityGroupClient.createSecurityGroupInRegion(null, tag, tag);
|
||||
// TODO figure out how to validate the ephemeral drive. perhaps with df -k?
|
||||
|
||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
|
||||
Credentials creds = nodes.iterator().next().getCredentials();
|
||||
assert creds == null;
|
||||
|
||||
NodeMetadata node = nodes.iterator().next();
|
||||
|
||||
Map<String, BlockDevice> devices = instanceClient
|
||||
.getBlockDeviceMappingForInstanceInRegion(node.getLocation()
|
||||
Map<String, BlockDevice> devices = instanceClient.getBlockDeviceMappingForInstanceInRegion(node.getLocation()
|
||||
.getParent().getId(), node.getProviderId());
|
||||
|
||||
BlockDevice device = devices.get("/dev/sda1");
|
||||
//check delete on termination
|
||||
BlockDevice device = devices.get("/dev/sdn");
|
||||
// check delete on termination
|
||||
assertTrue(device.isDeleteOnTermination());
|
||||
|
||||
Set<Volume> volumes = ebsClient.describeVolumesInRegion(node
|
||||
.getLocation().getParent().getId(), device.getVolumeId());
|
||||
volume = Iterables.getOnlyElement(ebsClient.describeVolumesInRegion(node.getLocation().getParent().getId(),
|
||||
device.getVolumeId()));
|
||||
// check volume size
|
||||
assertEquals(volumeSize, volumes.iterator().next().getSize());
|
||||
//check volume's snapshot id
|
||||
assertEquals(snapshot.getId(), volumes.iterator().next().getSnapshotId());
|
||||
assertEquals(volumeSize, volume.getSize());
|
||||
|
||||
device = devices.get("/dev/sdo");
|
||||
// check delete on termination
|
||||
assertTrue(device.isDeleteOnTermination());
|
||||
|
||||
volume = Iterables.getOnlyElement(ebsClient.describeVolumesInRegion(node.getLocation().getParent().getId(),
|
||||
device.getVolumeId()));
|
||||
// check volume size
|
||||
assertEquals(volumeSize, volume.getSize());
|
||||
// check volume's snapshot id
|
||||
assertEquals(snapshot.getId(), volume.getSnapshotId());
|
||||
|
||||
} finally {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
ebsClient.deleteSnapshotInRegion(snapshot.getRegion(), snapshot.getId());
|
||||
ebsClient.deleteVolumeInRegion(volume.getRegion(), volume.getId());
|
||||
if (startedId != null) {
|
||||
// ensure we didn't delete these resources!
|
||||
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1);
|
||||
}
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testMapEphemeralDeviceToDeviceName() throws Exception {
|
||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getSecurityGroupServices();
|
||||
|
||||
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getKeyPairServices();
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
String tag = this.tag + "BDM3";
|
||||
|
||||
TemplateOptions options = client.templateOptions();
|
||||
|
||||
options.as(EC2TemplateOptions.class).securityGroups(tag);
|
||||
options.as(EC2TemplateOptions.class).noKeyPair();
|
||||
options.as(EC2TemplateOptions.class).mapEphemeralDeviceToDeviceName("/dev/sdh", "ephemeral0");
|
||||
|
||||
String startedId = null;
|
||||
try {
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||
|
||||
// create the security group
|
||||
securityGroupClient.createSecurityGroupInRegion(null, tag, tag);
|
||||
|
||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
|
||||
Credentials creds = nodes.iterator().next().getCredentials();
|
||||
assert creds == null;
|
||||
|
||||
NodeMetadata node = nodes.iterator().next();
|
||||
startedId = node.getId();
|
||||
|
||||
Map<String, BlockDevice> devices = instanceClient
|
||||
.getBlockDeviceMappingForInstanceInRegion(node.getLocation()
|
||||
.getParent().getId(), node.getProviderId());
|
||||
|
||||
BlockDevice device = devices.get("/dev/sdh");
|
||||
assertNotNull(device);
|
||||
|
||||
} finally {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
if (startedId != null) {
|
||||
// ensure we didn't delete these resources!
|
||||
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1);
|
||||
}
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected RunningInstance getInstance(InstanceClient instanceClient, String id) {
|
||||
RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(instanceClient
|
||||
.describeInstancesInRegion(null, id)));
|
||||
|
|
|
@ -29,14 +29,14 @@ import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withUserData;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.ec2.domain.InstanceType;
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Tests possible uses of RunInstancesOptions and RunInstancesOptions.Builder.*
|
||||
*
|
||||
|
@ -213,11 +213,9 @@ public class RunInstancesOptionsTest {
|
|||
|
||||
@Test
|
||||
public void testWithBlockDeviceMapping() {
|
||||
RunInstancesOptions options = new RunInstancesOptions();
|
||||
BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true);
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
mappings.add(mapping);
|
||||
options.withBlockDeviceMappings(mappings);
|
||||
BlockDeviceMapping mapping = new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sda1", 120, true);
|
||||
RunInstancesOptions options = new RunInstancesOptions().withBlockDeviceMappings(ImmutableSet
|
||||
.<BlockDeviceMapping> of(mapping));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections
|
||||
.singletonList("/dev/sda1"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections
|
||||
|
@ -234,10 +232,9 @@ public class RunInstancesOptionsTest {
|
|||
|
||||
@Test
|
||||
public void testWithBlockDeviceMappingStatic() {
|
||||
BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true);
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
mappings.add(mapping);
|
||||
RunInstancesOptions options = withBlockDeviceMappings(mappings);
|
||||
BlockDeviceMapping mapping = new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sda1", 120, true);
|
||||
RunInstancesOptions options = withBlockDeviceMappings(ImmutableSet
|
||||
.<BlockDeviceMapping> of(mapping));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections
|
||||
.singletonList("/dev/sda1"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections
|
||||
|
|
|
@ -41,18 +41,6 @@ public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest
|
|||
tag = "eu";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testExtendedOptionsAndLogin() throws Exception {
|
||||
// euc does not support monitoring
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testExtendedOptionsNoKeyPair() throws Exception {
|
||||
// euc does not support multiple security groups
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertDefaultWorks() {
|
||||
Template defaultTemplate = client.templateBuilder().build();
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
|
||||
package org.jclouds.location.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -35,6 +38,7 @@ import com.google.common.base.Function;
|
|||
*/
|
||||
@Singleton
|
||||
public class ZoneToEndpoint implements Function<Object, URI> {
|
||||
|
||||
private final Map<String, URI> zoneToEndpoint;
|
||||
|
||||
@Inject
|
||||
|
@ -42,8 +46,9 @@ public class ZoneToEndpoint implements Function<Object, URI> {
|
|||
this.zoneToEndpoint = zoneToEndpoint;
|
||||
}
|
||||
|
||||
public URI apply(Object from) {
|
||||
@Override
|
||||
public URI apply(@Nullable Object from) {
|
||||
checkArgument(from != null, "you must specify a zone");
|
||||
return zoneToEndpoint.get(from);
|
||||
}
|
||||
|
||||
}
|
|
@ -102,18 +102,22 @@ public class AWSEC2ComputeService extends EC2ComputeService {
|
|||
void deletePlacementGroup(String region, String tag) {
|
||||
Preconditions2.checkNotEmpty(tag, "tag");
|
||||
String group = String.format("jclouds#%s#%s", tag, region);
|
||||
try {
|
||||
if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, group).size() > 0) {
|
||||
logger.debug(">> deleting placementGroup(%s)", group);
|
||||
try {
|
||||
ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group);
|
||||
checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)), String
|
||||
.format("placementGroup region(%s) name(%s) failed to delete", region, group));
|
||||
checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)),
|
||||
String.format("placementGroup region(%s) name(%s) failed to delete", region, group));
|
||||
placementGroupMap.remove(new RegionAndName(region, group));
|
||||
logger.debug("<< deleted placementGroup(%s)", group);
|
||||
} catch (IllegalStateException e) {
|
||||
logger.debug("<< inUse placementGroup(%s)", group);
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedOperationException e) {
|
||||
logger.trace("<< placementGroups unsupported in region %s", region);
|
||||
}
|
||||
}
|
||||
|
||||
protected void cleanUpIncidentalResources(Entry<String, String> regionTag) {
|
||||
|
|
|
@ -23,10 +23,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.util.Preconditions2;
|
||||
|
@ -98,13 +102,54 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
}
|
||||
|
||||
public static class Builder {
|
||||
/**
|
||||
* @see EC2TemplateOptions#blockDeviceMappings
|
||||
*/
|
||||
public static AWSEC2TemplateOptions blockDeviceMappings(Set<? extends BlockDeviceMapping> blockDeviceMappings) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return options.blockDeviceMappings(blockDeviceMappings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#mapEBSSnapshotToDeviceName
|
||||
*/
|
||||
public static AWSEC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId,
|
||||
@Nullable Integer sizeInGib, boolean deleteOnTermination) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return options.mapEBSSnapshotToDeviceName(deviceName, snapshotId, sizeInGib, deleteOnTermination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#mapNewVolumeToDeviceName
|
||||
*/
|
||||
public static AWSEC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib,
|
||||
boolean deleteOnTermination) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return options.mapNewVolumeToDeviceName(deviceName, sizeInGib, deleteOnTermination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#mapEphemeralDeviceToDeviceName
|
||||
*/
|
||||
public static AWSEC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return options.mapEphemeralDeviceToDeviceName(deviceName, virtualName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EC2TemplateOptions#unmapDeviceNamed
|
||||
*/
|
||||
public static AWSEC2TemplateOptions unmapDeviceNamed(String deviceName) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return options.unmapDeviceNamed(deviceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AWSEC2TemplateOptions#securityGroups(Iterable<String>)
|
||||
*/
|
||||
public static AWSEC2TemplateOptions securityGroups(String... groupIds) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.securityGroups(groupIds));
|
||||
return options.securityGroups(groupIds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,7 +157,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions securityGroups(Iterable<String> groupIds) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.securityGroups(groupIds));
|
||||
return options.securityGroups(groupIds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,7 +165,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions keyPair(String keyPair) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.keyPair(keyPair));
|
||||
return options.keyPair(keyPair);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,7 +173,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions userData(byte[] unencodedData) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.userData(unencodedData));
|
||||
return options.userData(unencodedData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,7 +181,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions noKeyPair() {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.noKeyPair());
|
||||
return options.noKeyPair();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,7 +189,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions placementGroup(String placementGroup) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.placementGroup(placementGroup));
|
||||
return options.placementGroup(placementGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,7 +197,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions noPlacementGroup() {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.noPlacementGroup());
|
||||
return options.noPlacementGroup();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,7 +205,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions enableMonitoring() {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.enableMonitoring());
|
||||
return options.enableMonitoring();
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
|
@ -169,7 +214,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions inboundPorts(int... ports) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.inboundPorts(ports));
|
||||
return options.inboundPorts(ports);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,7 +222,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions blockOnPort(int port, int seconds) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.blockOnPort(port, seconds));
|
||||
return options.blockOnPort(port, seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,7 +230,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions runScript(byte[] script) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.runScript(script));
|
||||
return options.runScript(script);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,7 +238,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions installPrivateKey(String rsaKey) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.installPrivateKey(rsaKey));
|
||||
return options.installPrivateKey(rsaKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,7 +246,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions authorizePublicKey(String rsaKey) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.authorizePublicKey(rsaKey));
|
||||
return options.authorizePublicKey(rsaKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,7 +254,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions withDetails() {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.withMetadata());
|
||||
return options.withMetadata();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,12 +262,96 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
*/
|
||||
public static AWSEC2TemplateOptions subnetId(String subnetId) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.subnetId(subnetId));
|
||||
return options.subnetId(subnetId);
|
||||
}
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions blockDeviceMappings(Set<? extends BlockDeviceMapping> blockDeviceMappings) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.blockDeviceMappings(blockDeviceMappings));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions keyPair(String keyPair) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.keyPair(keyPair));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public AWSEC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId, Integer sizeInGib,
|
||||
boolean deleteOnTermination) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.mapEBSSnapshotToDeviceName(deviceName, snapshotId, sizeInGib,
|
||||
deleteOnTermination));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.mapEphemeralDeviceToDeviceName(deviceName, virtualName));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib, boolean deleteOnTermination) {
|
||||
return AWSEC2TemplateOptions.class.cast(super
|
||||
.mapNewVolumeToDeviceName(deviceName, sizeInGib, deleteOnTermination));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions noKeyPair() {
|
||||
return AWSEC2TemplateOptions.class.cast(super.noKeyPair());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions securityGroups(Iterable<String> groupIds) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.securityGroups(groupIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions securityGroups(String... groupIds) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.securityGroups(groupIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions unmapDeviceNamed(String deviceName) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.unmapDeviceNamed(deviceName));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions userData(byte[] unencodedData) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.userData(unencodedData));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -414,7 +543,7 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions {
|
|||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "AWSEC2TemplateOptions [groupIds=" + getGroupIds() + ", keyPair=" + getKeyPair() + ", noKeyPair="
|
||||
return "[groupIds=" + getGroupIds() + ", keyPair=" + getKeyPair() + ", noKeyPair="
|
||||
+ !shouldAutomaticallyCreateKeyPair() + ", monitoringEnabled=" + monitoringEnabled + ", placementGroup="
|
||||
+ placementGroup + ", noPlacementGroup=" + noPlacementGroup + ", subnetId=" + subnetId + ", userData="
|
||||
+ Arrays.toString(getUserData()) + ", blockDeviceMappings=" + getBlockDeviceMappings() + "]";
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.jclouds.aws.ec2.compute.config;
|
|||
import static org.jclouds.compute.domain.OsFamily.AMZN_LINUX;
|
||||
|
||||
import org.jclouds.aws.ec2.compute.AWSEC2TemplateBuilderImpl;
|
||||
import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
|
||||
import org.jclouds.aws.ec2.compute.strategy.AWSEC2ReviseParsedImage;
|
||||
import org.jclouds.aws.ec2.compute.strategy.CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions;
|
||||
import org.jclouds.aws.ec2.compute.suppliers.AWSEC2HardwareSupplier;
|
||||
|
@ -30,7 +29,6 @@ import org.jclouds.aws.ec2.compute.suppliers.AWSRegionAndNameToImageSupplier;
|
|||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.ec2.compute.config.EC2ComputeServiceContextModule;
|
||||
import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
||||
import org.jclouds.ec2.compute.strategy.ReviseParsedImage;
|
||||
import org.jclouds.ec2.compute.suppliers.EC2HardwareSupplier;
|
||||
|
@ -58,7 +56,6 @@ public class AWSEC2ComputeServiceContextModule extends EC2ComputeServiceContextM
|
|||
bind(EC2HardwareSupplier.class).to(AWSEC2HardwareSupplier.class);
|
||||
bind(RegionAndNameToImageSupplier.class).to(AWSRegionAndNameToImageSupplier.class);
|
||||
bind(EC2TemplateBuilderImpl.class).to(AWSEC2TemplateBuilderImpl.class);
|
||||
bind(EC2TemplateOptions.class).to(AWSEC2TemplateOptions.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,6 +32,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
|
||||
import org.jclouds.aws.ec2.AWSEC2Client;
|
||||
import org.jclouds.aws.ec2.compute.AWSEC2ComputeService;
|
||||
import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
|
||||
import org.jclouds.aws.ec2.domain.PlacementGroup;
|
||||
import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable;
|
||||
import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted;
|
||||
|
@ -48,7 +49,6 @@ import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded;
|
|||
import org.jclouds.ec2.compute.functions.CredentialsForInstance;
|
||||
import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata;
|
||||
import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
@ -69,7 +69,7 @@ public class AWSEC2ComputeServiceDependenciesModule extends EC2ComputeServiceDep
|
|||
@Override
|
||||
protected void configure() {
|
||||
bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class);
|
||||
bind(TemplateOptions.class).to(EC2TemplateOptions.class);
|
||||
bind(TemplateOptions.class).to(AWSEC2TemplateOptions.class);
|
||||
bind(ComputeService.class).to(AWSEC2ComputeService.class);
|
||||
bind(new TypeLiteral<Function<RunningInstance, NodeMetadata>>() {
|
||||
}).to(RunningInstanceToNodeMetadata.class);
|
||||
|
|
|
@ -31,14 +31,14 @@ import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withUse
|
|||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.ec2.domain.InstanceType;
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Tests possible uses of AWSRunInstancesOptions and AWSRunInstancesOptions.Builder.*
|
||||
*
|
||||
|
@ -258,14 +258,15 @@ public class AWSRunInstancesOptionsTest {
|
|||
|
||||
@Test
|
||||
public void testWithBlockDeviceMapping() {
|
||||
AWSRunInstancesOptions options = new AWSRunInstancesOptions();
|
||||
BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true);
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
mappings.add(mapping);
|
||||
options.withBlockDeviceMappings(mappings);
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true"));
|
||||
BlockDeviceMapping mapping = new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sda1", 120, true);
|
||||
AWSRunInstancesOptions options = new AWSRunInstancesOptions().withBlockDeviceMappings(ImmutableSet
|
||||
.<BlockDeviceMapping> of(mapping));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections
|
||||
.singletonList("/dev/sda1"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections
|
||||
.singletonList("120"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections
|
||||
.singletonList("true"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -276,13 +277,14 @@ public class AWSRunInstancesOptionsTest {
|
|||
|
||||
@Test
|
||||
public void testWithBlockDeviceMappingStatic() {
|
||||
BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true);
|
||||
Set<BlockDeviceMapping> mappings = new HashSet<BlockDeviceMapping>();
|
||||
mappings.add(mapping);
|
||||
AWSRunInstancesOptions options = withBlockDeviceMappings(mappings);
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true"));
|
||||
BlockDeviceMapping mapping = new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sda1", 120, true);
|
||||
AWSRunInstancesOptions options = withBlockDeviceMappings(ImmutableSet.<BlockDeviceMapping> of(mapping));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections
|
||||
.singletonList("/dev/sda1"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections
|
||||
.singletonList("120"));
|
||||
assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections
|
||||
.singletonList("true"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
|
|
Loading…
Reference in New Issue