protected Volume getVolume(AmazonEC2AsyncClient client, Instance awsInstance, String deviceName) { InstanceBlockDeviceMapping bootDiskMapping = awsInstance.getBlockDeviceMappings().stream() .filter(blockDeviceMapping -> blockDeviceMapping.getDeviceName().equals(deviceName)) .findAny() .orElse(null); //The ami used in this test is an ebs-backed AMI assertNotNull("Device type should be ebs type", bootDiskMapping.getEbs()); String bootVolumeId = bootDiskMapping.getEbs().getVolumeId(); DescribeVolumesRequest describeVolumesRequest = new DescribeVolumesRequest() .withVolumeIds(bootVolumeId); DescribeVolumesResult describeVolumesResult = client .describeVolumes(describeVolumesRequest); return describeVolumesResult.getVolumes().get(0); }
/** * Get EBS volumes attached to the specified virtual instance id. * * @return list of ebs volumes */ @VisibleForTesting List<Volume> getVolumes(String virtualInstanceId) { String ec2InstanceId = getOnlyElement( getEC2InstanceIdsByVirtualInstanceId( Collections.singletonList(virtualInstanceId) ).values() ); InstanceAttribute instanceAttribute = describeInstanceAttribute(ec2InstanceId, InstanceAttributeName.BlockDeviceMapping); List<InstanceBlockDeviceMapping> blockDeviceMappings = instanceAttribute.getBlockDeviceMappings(); List<String> volumeIds = Lists.newArrayList(); for (InstanceBlockDeviceMapping mapping : blockDeviceMappings) { volumeIds.add(mapping.getEbs().getVolumeId()); } DescribeVolumesResult volumeResults = client.describeVolumes( new DescribeVolumesRequest().withVolumeIds(volumeIds) ); return volumeResults.getVolumes(); }
/** * updates status, Id and name of the disk. Also tags the corresponding AWS volume with its name. */ private void updateAndTagDisks(DiskState bootDisk, List<DiskState> imageDisks, List<DiskState> additionalDisks, List<InstanceBlockDeviceMapping> blockDeviceMappings) { List<DiskState> diskStateList = new ArrayList<>(); diskStateList.add(bootDisk); diskStateList.addAll(imageDisks); diskStateList.addAll(additionalDisks); for (DiskState diskState : diskStateList) { diskState.status = DiskService.DiskStatus.ATTACHED; String deviceType = diskState.customProperties.get(DEVICE_TYPE); if (deviceType.equals(AWSStorageType.EBS.getName())) { String deviceName = diskState.customProperties.get(DEVICE_NAME); for (InstanceBlockDeviceMapping blockDeviceMapping : blockDeviceMappings) { if (blockDeviceMapping.getDeviceName().equals(deviceName)) { diskState.id = blockDeviceMapping.getEbs().getVolumeId(); if (diskState.name == null) { diskState.name = diskState.id; } else { tagDisk(diskState.id, diskState.name); } break; } } } else { diskState.id = String.format("%s_%s", AWSStorageType.INSTANCE_STORE.getName(), UUID.randomUUID().toString()); diskState.name = diskState.id; } } }
private String getAvailableDeviceName(DiskContext context, String instanceId) { DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest() .withInstanceIds(instanceId); DescribeInstancesResult instancesResult = context.amazonEC2Client .describeInstances(describeInstancesRequest); List<InstanceBlockDeviceMapping> blockDeviceMappings = null; AWSSupportedOS platform = null; AWSSupportedVirtualizationTypes virtualizationTypes = null; String instanceType = null; for (Reservation reservation : instancesResult.getReservations()) { for (Instance instance : reservation.getInstances()) { if (instance.getInstanceId().equals(instanceId)) { blockDeviceMappings = instance.getBlockDeviceMappings(); platform = AWSSupportedOS.get(instance.getPlatform()); virtualizationTypes = AWSSupportedVirtualizationTypes.get(instance.getVirtualizationType()); instanceType = instance.getInstanceType(); break; } } } String deviceName = null; if (blockDeviceMappings != null) { List<String> usedDeviceNames = getUsedDeviceNames(blockDeviceMappings); List<String> availableDiskNames = AWSBlockDeviceNameMapper.getAvailableNames( platform, virtualizationTypes, AWSStorageType.EBS, instanceType, usedDeviceNames); deviceName = availableDiskNames.get(0); } return deviceName; }
private List<String> getUsedDeviceNames(List<InstanceBlockDeviceMapping> blockDeviceMappings) { List<String> usedDeviceNames = new ArrayList<>(); for (InstanceBlockDeviceMapping blockDeviceMapping : blockDeviceMappings) { usedDeviceNames.add(blockDeviceMapping.getDeviceName()); } return usedDeviceNames; }
/** * This method returns all EBS root volumes. * @return */ public List<Volume> getAllEBSRootVolumes() { List<Instance> allInstances = getAllInstances(); List<Volume> allEBSRootVolumes = new ArrayList<>(); for(Instance instance: allInstances) { //We need volumes of type only EBS. if ( instance.getRootDeviceType().equalsIgnoreCase(DeviceType.Ebs.toString())) { String rootDeviceName = instance.getRootDeviceName(); List<InstanceBlockDeviceMapping> instanceBlockDeviceMappings = instance.getBlockDeviceMappings(); for(InstanceBlockDeviceMapping instanceBlockDeviceMapping: instanceBlockDeviceMappings) { if(instanceBlockDeviceMapping.getDeviceName().equalsIgnoreCase(rootDeviceName)) { String volumeId = instanceBlockDeviceMapping.getEbs().getVolumeId(); Volume volume = new Volume().withVolumeId(volumeId); allEBSRootVolumes.add(volume); } } } } System.out.println("INFO: Number of EBS Root Volumes : " + allEBSRootVolumes.size()); List<String> volumeIds = allEBSRootVolumes.stream().map(e -> e.getVolumeId()).collect(Collectors.toList()); System.out.println("INFO: EBS Root Volumes : " + volumeIds); return allEBSRootVolumes; }
private void tagSpotEbsVolumes(String ec2InstanceId, String virtualInstanceId, List<Tag> tags) throws InterruptedException { DescribeInstancesResult result = client.describeInstances( new DescribeInstancesRequest().withInstanceIds(Collections.singletonList(ec2InstanceId)) ); List<InstanceBlockDeviceMapping> instanceBlockDeviceMappings = getOnlyElement(getOnlyElement(result.getReservations()).getInstances()).getBlockDeviceMappings(); for (InstanceBlockDeviceMapping instanceBlockDeviceMapping : instanceBlockDeviceMappings) { String volumeId = instanceBlockDeviceMapping.getEbs().getVolumeId(); tagSpotEbsVolume(template, tags, virtualInstanceId, volumeId); } }
/** * Adds a delete on termination flag to all volumes in an {@code InstanceEbsVolumes} list * that have the ATTACHED status. This makes sure that the volumes associated with the * instance will be automatically cleaned up upon instance termination. * * @param instanceEbsVolumesList list of instances along with their associated volumes */ public void addDeleteOnTerminationFlag(List<InstanceEbsVolumes> instanceEbsVolumesList) { Set<String> volumesToFlag = getAllVolumeIdsWithStatus(instanceEbsVolumesList, InstanceEbsVolumes.Status.ATTACHED); if (!volumesToFlag.isEmpty()) { for (InstanceEbsVolumes instanceEbsVolumes : instanceEbsVolumesList) { String ec2InstanceId = instanceEbsVolumes.getEc2InstanceId(); DescribeInstanceAttributeRequest instanceAttributeRequest = new DescribeInstanceAttributeRequest() .withAttribute(InstanceAttributeName.BlockDeviceMapping) .withInstanceId(ec2InstanceId); List<InstanceBlockDeviceMapping> blockDeviceMappings = client.describeInstanceAttribute(instanceAttributeRequest) .getInstanceAttribute() .getBlockDeviceMappings(); for (InstanceBlockDeviceMapping blockDeviceMapping : blockDeviceMappings) { String volumeId = blockDeviceMapping.getEbs().getVolumeId(); // The block device mapping may have volumes associated with it that were not // provisioned by us. We skip marking those volumes for deletion. if (!volumesToFlag.contains(volumeId)) { continue; } InstanceBlockDeviceMappingSpecification updatedSpec = new InstanceBlockDeviceMappingSpecification() .withEbs( new EbsInstanceBlockDeviceSpecification() .withDeleteOnTermination(true) .withVolumeId(volumeId) ) .withDeviceName(blockDeviceMapping.getDeviceName()); ModifyInstanceAttributeRequest modifyRequest = new ModifyInstanceAttributeRequest() .withBlockDeviceMappings(updatedSpec) .withInstanceId(ec2InstanceId); client.modifyInstanceAttribute(modifyRequest); } } } }
public void createTag(AwsProcessClient awsProcessClient, Long instanceNo) { // Eucalyptusの場合はタグを付けない PlatformAws platformAws = awsProcessClient.getPlatformAws(); if (BooleanUtils.isTrue(platformAws.getEuca())) { return; } Instance instance = instanceDao.read(instanceNo); AwsInstance awsInstance = awsInstanceDao.read(instanceNo); User user = userDao.read(awsProcessClient.getUserNo()); Farm farm = farmDao.read(instance.getFarmNo()); // インスタンスにタグを追加する List<Tag> tags = new ArrayList<Tag>(); tags.add(new Tag("Name", instance.getFqdn())); tags.add(new Tag("UserName", user.getUsername())); tags.add(new Tag("CloudName", farm.getDomainName())); tags.add(new Tag("ServerName", instance.getFqdn())); awsCommonProcess.createTag(awsProcessClient, awsInstance.getInstanceId(), tags); com.amazonaws.services.ec2.model.Instance instance2 = awsCommonProcess.describeInstance(awsProcessClient, awsInstance.getInstanceId()); // EBSにタグを追加する for (InstanceBlockDeviceMapping mapping : instance2.getBlockDeviceMappings()) { if (mapping.getEbs() == null) { continue; } String deviceName = mapping.getDeviceName(); if (deviceName.lastIndexOf("/") != -1) { deviceName = deviceName.substring(deviceName.lastIndexOf("/") + 1); } tags = new ArrayList<Tag>(); tags.add(new Tag("Name", instance.getFqdn() + "_" + deviceName)); tags.add(new Tag("UserName", user.getUsername())); tags.add(new Tag("CloudName", farm.getDomainName())); tags.add(new Tag("ServerName", instance.getFqdn())); awsCommonProcess.createTag(awsProcessClient, mapping.getEbs().getVolumeId(), tags); } }
@Override public List<InstanceBlockDeviceMapping> getBlockDeviceMappings() { return (List<InstanceBlockDeviceMapping>) resource.getAttribute("BlockDeviceMappings"); }
@Override public int compare(InstanceBlockDeviceMapping ibdm1, InstanceBlockDeviceMapping ibdm2) { return new CompareToBuilder().append(ibdm1.getDeviceName(), ibdm2.getDeviceName()).toComparison(); }
@Test public void testRunInstancesWithBlockDevices() throws Exception { // TODO: maybe we should also test for spot instances BlockDevice blockDevice = mock(BlockDevice.class); when(blockDevice.getSize()).thenReturn(8); // TODO: understand why it doesn't work for smaller volumes when(blockDevice.getName()).thenReturn("/dev/sda1"); BlockDevice blockDevice2 = mock(BlockDevice.class); when(blockDevice2.getSize()).thenReturn(16); when(blockDevice2.getName()).thenReturn("/dev/sda4"); when(hardware.getBlockDevices()).thenReturn(Lists.newArrayList(blockDevice, blockDevice2)); activity.execute(execution); Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS); @SuppressWarnings("unchecked") List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS); DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest() .withInstanceIds(instanceIds)); Instance instance = result.getReservations().get(0).getInstances().get(0); List<InstanceBlockDeviceMapping> bdm = instance.getBlockDeviceMappings(); assertThat(bdm).hasSize(2); List<String> volumeIds = Lists.newArrayList(); for (int i = 0; i < bdm.size(); i++) { assertThat(bdm.get(i).getDeviceName()).isEqualTo("/dev/sda" + ((i + 1) * (i + 1))); assertThat(bdm.get(i).getEbs().getDeleteOnTermination()).isTrue(); volumeIds.add(bdm.get(i).getEbs().getVolumeId()); } DescribeVolumesResult volumesResult = client.describeVolumes( new DescribeVolumesRequest().withVolumeIds(volumeIds)); for (Volume volume : volumesResult.getVolumes()) { assertThat(volume.getState()).isIn(Lists.newArrayList("creating", "available", "in-use")); } assertThat(volumesResult.getVolumes().get(0).getSize()) .isNotEqualTo(volumesResult.getVolumes().get(1).getSize()); }
/** * Gets the value of the BlockDeviceMappings attribute. If this resource is * not yet loaded, a call to {@code load()} is made to retrieve the value of * the attribute. */ List<InstanceBlockDeviceMapping> getBlockDeviceMappings();