expose block device mapping options in RunInstanceOpions and EC2TemplateOptions

This commit is contained in:
Lili Nader 2011-01-13 18:01:24 -08:00
parent 05c2a40259
commit 9d7850a686
5 changed files with 268 additions and 28 deletions

View File

@ -73,6 +73,8 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
eTo.noKeyPair();
if (eFrom.getSubnetId() != null)
eTo.subnetId(eFrom.getSubnetId());
if (eFrom.getBlockDeviceMappings() != null)
eTo.blockDeviceMapping(eFrom.getBlockDeviceMappings());
if (eFrom.isMonitoringEnabled())
eTo.enableMonitoring();
if (eFrom.getUserData() != null)

View File

@ -24,9 +24,11 @@ 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 org.jclouds.aws.cloudwatch.CloudWatchClient;
import org.jclouds.aws.ec2.options.RunInstancesOptions.BlockDeviceMapping;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.io.Payload;
@ -63,7 +65,8 @@ public class EC2TemplateOptions extends TemplateOptions {
private boolean noPlacementGroup;
private String subnetId;
private byte[] userData;
private Set<BlockDeviceMapping> blockDeviceMappings;
public static final EC2TemplateOptions NONE = new EC2TemplateOptions();
/**
@ -155,6 +158,37 @@ public class EC2TemplateOptions extends TemplateOptions {
this.subnetId = subnetId;
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions blockDeviceMapping(String deviceName,
String virtualName, String ebsSnapShotId,
Integer ebsVolumeSize, Boolean ebsNoDevice,
Boolean ebsNoDeviceebsDeleteOnTermination) {
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty");
BlockDeviceMapping mapping = new BlockDeviceMapping(deviceName, virtualName, ebsSnapShotId, ebsVolumeSize, ebsNoDevice, ebsNoDeviceebsDeleteOnTermination);
if(blockDeviceMappings == null)
blockDeviceMappings = new HashSet<BlockDeviceMapping>();
blockDeviceMappings.add(mapping);
return this;
}
/**
* Specifies the block device mappings to be used to run the instance
*/
public EC2TemplateOptions blockDeviceMapping(Set<BlockDeviceMapping> blockDeviceMappings) {
checkArgument(Iterables.size(blockDeviceMappings) > 0, "you must specify at least one block device mapping");
for (BlockDeviceMapping blockDeviceMapping : blockDeviceMappings)
{
String deviceName = blockDeviceMapping.getDeviceName();
checkNotNull(deviceName, "deviceName cannot be null");
Preconditions2.checkNotEmpty(deviceName, "the deviceName must be non-empty");
}
this.blockDeviceMappings = blockDeviceMappings;
return this;
}
public static class Builder {
@ -278,6 +312,19 @@ public class EC2TemplateOptions extends TemplateOptions {
EC2TemplateOptions options = new EC2TemplateOptions();
return EC2TemplateOptions.class.cast(options.subnetId(subnetId));
}
/**
* @see EC2TemplateOptions#blockDeviceMapping
*/
public static EC2TemplateOptions blockDeviceMapping(String deviceName,
String virtualName, String ebsSnapShotId,
Integer ebsVolumeSize, Boolean ebsNoDevice,
Boolean ebsNoDeviceebsDeleteOnTermination) {
EC2TemplateOptions options = new EC2TemplateOptions();
return EC2TemplateOptions.class.cast(options.blockDeviceMapping(deviceName,
virtualName, ebsSnapShotId, ebsVolumeSize, ebsNoDevice,
ebsNoDeviceebsDeleteOnTermination));
}
}
@ -462,24 +509,38 @@ public class EC2TemplateOptions extends TemplateOptions {
public byte[] getUserData() {
return userData;
}
/**
* @return BlockDeviceMapping to use when running the instance or null.
*/
public Set<BlockDeviceMapping> getBlockDeviceMappings() {
return blockDeviceMappings;
}
@Override
public int hashCode() {
public int hashCode(){
final int prime = 31;
int result = super.hashCode();
result = prime
* result
+ ((blockDeviceMappings == null) ? 0 : blockDeviceMappings
.hashCode());
result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode());
result = prime * result + ((keyPair == null) ? 0 : keyPair.hashCode());
result = prime * result + (monitoringEnabled ? 1231 : 1237);
result = prime * result + (noKeyPair ? 1231 : 1237);
result = prime * result + (noPlacementGroup ? 1231 : 1237);
result = prime * result + (monitoringEnabled ? 1231 : 1237);
result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode());
result = prime * result
+ ((placementGroup == null) ? 0 : placementGroup.hashCode());
result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode());
result = prime * result + ((userData == null) ? 0 : userData.hashCode());
result = prime * result + Arrays.hashCode(userData);
return result;
}
@Override
public boolean equals(Object obj) {
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (!super.equals(obj))
@ -487,47 +548,62 @@ public class EC2TemplateOptions extends TemplateOptions {
if (getClass() != obj.getClass())
return false;
EC2TemplateOptions other = (EC2TemplateOptions) obj;
if (groupIds == null) {
if (blockDeviceMappings == null)
{
if (other.blockDeviceMappings != null)
return false;
}
else if (!blockDeviceMappings.equals(other.blockDeviceMappings))
return false;
if (groupIds == null)
{
if (other.groupIds != null)
return false;
} else if (!groupIds.equals(other.groupIds))
}
else if (!groupIds.equals(other.groupIds))
return false;
if (keyPair == null) {
if (keyPair == null)
{
if (other.keyPair != null)
return false;
} else if (!keyPair.equals(other.keyPair))
return false;
}
else if (!keyPair.equals(other.keyPair))
return false;
if (monitoringEnabled != other.monitoringEnabled)
return false;
if (noKeyPair != other.noKeyPair)
return false;
if (noPlacementGroup != other.noPlacementGroup)
return false;
if (monitoringEnabled != other.monitoringEnabled)
return false;
if (placementGroup == null) {
if (placementGroup == null)
{
if (other.placementGroup != null)
return false;
} else if (!placementGroup.equals(other.placementGroup))
return false;
if (subnetId == null) {
}
else if (!placementGroup.equals(other.placementGroup))
return false;
if (subnetId == null)
{
if (other.subnetId != null)
return false;
} else if (!subnetId.equals(other.subnetId))
}
else if (!subnetId.equals(other.subnetId))
return false;
if (userData == null) {
if (other.userData != null)
return false;
} else if (!userData.equals(other.userData))
if (!Arrays.equals(userData, other.userData))
return false;
return true;
}
}
@Override
public String toString() {
return "[groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", placementGroup="
+ placementGroup + ", noPlacementGroup=" + noPlacementGroup + ", monitoringEnabled=" + monitoringEnabled
+ ", inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null)
+ ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port
+ ":" + seconds + ", subnetId=" + subnetId + ", metadata/details: " + includeMetadata + "]";
return "EC2TemplateOptions [groupIds=" + groupIds + ", keyPair=" + keyPair
+ ", noKeyPair=" + noKeyPair + ", monitoringEnabled="
+ monitoringEnabled + ", placementGroup=" + placementGroup
+ ", noPlacementGroup=" + noPlacementGroup + ", subnetId="
+ subnetId + ", userData=" + Arrays.toString(userData)
+ ", blockDeviceMappings=" + blockDeviceMappings + "]";
}
}

View File

@ -40,6 +40,7 @@ import org.jclouds.aws.ec2.options.RunInstancesOptions;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.location.Provider;
import org.jclouds.aws.ec2.options.RunInstancesOptions.BlockDeviceMapping;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
@ -113,6 +114,11 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions
if (userData != null)
instanceOptions.withUserData(userData);
Set<BlockDeviceMapping> blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions()).getBlockDeviceMappings();
if (blockDeviceMappings != null)
instanceOptions.withBlockDeviceMappings(blockDeviceMappings);
return instanceOptions;
}

View File

@ -22,6 +22,8 @@ package org.jclouds.aws.ec2.options;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.options.internal.BaseEC2RequestOptions;
import org.jclouds.encryption.internal.Base64;
@ -208,6 +210,34 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
String getSubnetId() {
return getFirstFormOrNull("SubnetId");
}
/**
* Specifies the Block Device Mapping for the instance
*
*/
public RunInstancesOptions withBlockDeviceMappings(Set<BlockDeviceMapping> mappings) {
int i = 1;
for(BlockDeviceMapping mapping: mappings)
{
checkNotNull(mapping.getDeviceName(), "deviceName");
formParameters.put(String.format("BlockDeviceMapping.%d.DeviceName", i), mapping.getDeviceName());
if(mapping.getVirtualName() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.VirtualName", i), mapping.getVirtualName());
if(mapping.getEbsSnapshotId() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.SnapshotId", i), mapping.getEbsSnapshotId());
if(mapping.getEbsVolumeSize() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.VolumeSize", i), String.valueOf(mapping.getEbsVolumeSize()));
if(mapping.getEbsNoDevice() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.NoDevice", i), String.valueOf(mapping.getEbsNoDevice()));
if(mapping.getEbsDeleteOnTermination() != null)
formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.DeleteOnTermination", i), String.valueOf(mapping.getEbsDeleteOnTermination()));
i++;
}
return this;
}
public static class Builder {
/**
@ -297,6 +327,94 @@ public class RunInstancesOptions extends BaseEC2RequestOptions {
RunInstancesOptions options = new RunInstancesOptions();
return options.withVirtualName(virtualName);
}
/**
* @see RunInstancesOptions#withBlockDeviceMappings(Set<BlockDeviceMapping> mappings)
*/
public static RunInstancesOptions withBlockDeviceMappings(Set<BlockDeviceMapping> mappings) {
RunInstancesOptions options = new RunInstancesOptions();
return options.withBlockDeviceMappings(mappings);
}
}
public static class BlockDeviceMapping
{
private String deviceName;
private String virtualName;
private String ebsSnapshotId;
private Integer ebsVolumeSize;
private Boolean ebsNoDevice;
private Boolean ebsDeleteOnTermination;
public BlockDeviceMapping(String deviceName, String virtualName,
String ebsSnapshotId, Integer ebsVolumeSize,
Boolean ebsNoDevice, Boolean ebsDeleteOnTermination){
this.deviceName = deviceName;
this.virtualName = virtualName;
this.ebsSnapshotId = ebsSnapshotId;
this.ebsVolumeSize = ebsVolumeSize;
this.ebsNoDevice = ebsNoDevice;
this.ebsDeleteOnTermination = ebsDeleteOnTermination;
}
public String getDeviceName(){
return deviceName;
}
public String getVirtualName() {
return virtualName;
}
public String getEbsSnapshotId() {
return ebsSnapshotId;
}
public Integer getEbsVolumeSize() {
return ebsVolumeSize;
}
public Boolean getEbsNoDevice() {
return ebsNoDevice;
}
public Boolean getEbsDeleteOnTermination() {
return ebsDeleteOnTermination;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((deviceName == null) ? 0 : deviceName.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BlockDeviceMapping other = (BlockDeviceMapping) obj;
if (deviceName == null)
{
if (other.deviceName != null)
return false;
}
else if (!deviceName.equals(other.deviceName))
return false;
return true;
}
@Override
public String toString() {
return "BlockDeviceMapping [deviceName=" + deviceName
+ ", virtualName=" + virtualName + ", ebsSnapshotId="
+ ebsSnapshotId + ", ebsVolumeSize=" + ebsVolumeSize
+ ", ebsNoDevice=" + ebsNoDevice
+ ", ebsDeleteOnTermination=" + ebsDeleteOnTermination
+ "]";
}
}
}

View File

@ -29,11 +29,15 @@ import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withSecuri
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withSubnetId;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withUserData;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withVirtualName;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withBlockDeviceMappings;
import static org.testng.Assert.assertEquals;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.options.RunInstancesOptions.BlockDeviceMapping;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
@ -299,5 +303,39 @@ public class RunInstancesOptionsTest {
public void testWithVirtualNameNPE() {
withVirtualName(null);
}
@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);
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
public void testNullWithBlockDeviceMapping() {
RunInstancesOptions options = new RunInstancesOptions();
assertEquals(options.buildFormParameters().get("BlockDeviceMapping"), Collections.EMPTY_LIST);
}
@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);
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)
public void testWithBlockDeviceMappingNPE() {
withBlockDeviceMappings(null);
}
}