Search in sources :

Example 6 with EbsBlockDevice

use of com.amazonaws.services.ec2.model.EbsBlockDevice in project photon-model by vmware.

the class AWSInstanceService method customizeBootDiskProperties.

private void customizeBootDiskProperties(DiskState bootDisk, String rootDeviceType, BlockDeviceMapping rootDeviceMapping, boolean hasHardConstraint, AWSInstanceContext aws) {
    bootDisk.persistent = Boolean.FALSE;
    if (rootDeviceType.equals(AWSStorageType.EBS.name().toLowerCase())) {
        String requestedType = bootDisk.customProperties.get(DEVICE_TYPE);
        EbsBlockDevice ebs = rootDeviceMapping.getEbs();
        if (hasHardConstraint) {
            validateIfDeviceTypesAreMatching(rootDeviceType, requestedType);
        }
        bootDisk.capacityMBytes = ebs.getVolumeSize() * 1024;
        updateDeviceMapping(rootDeviceType, requestedType, rootDeviceMapping.getDeviceName(), ebs, bootDisk);
        bootDisk.customProperties.put(DEVICE_TYPE, AWSStorageType.EBS.getName());
        bootDisk.customProperties.put(VOLUME_TYPE, ebs.getVolumeType());
        if (ebs.getIops() != null) {
            bootDisk.customProperties.put(DISK_IOPS, String.valueOf(ebs.getIops()));
        }
    } else {
        if (aws.instanceTypeInfo.dataDiskSizeInMB != null) {
            this.logInfo(() -> "[AWSInstanceService] Instance-Store boot disk size is set to the " + "value supported by instance-type.");
            bootDisk.capacityMBytes = aws.instanceTypeInfo.dataDiskSizeInMB;
            bootDisk.customProperties.put(DEVICE_TYPE, AWSStorageType.INSTANCE_STORE.getName());
        }
    }
}
Also used : EbsBlockDevice(com.amazonaws.services.ec2.model.EbsBlockDevice)

Example 7 with EbsBlockDevice

use of com.amazonaws.services.ec2.model.EbsBlockDevice in project photon-model by vmware.

the class AWSInstanceService method createInstance.

private void createInstance(AWSInstanceContext aws) {
    if (aws.computeRequest.isMockRequest) {
        aws.taskManager.finishTask();
        return;
    }
    final DiskState bootDisk = aws.bootDisk;
    if (bootDisk == null) {
        aws.taskManager.patchTaskToFailure(new IllegalStateException("AWS bootDisk not specified"));
        return;
    }
    if (bootDisk.bootConfig != null && bootDisk.bootConfig.files.length > 1) {
        aws.taskManager.patchTaskToFailure(new IllegalStateException("Only 1 configuration file allowed"));
        return;
    }
    // This a single disk state with a bootConfig. There's no expectation
    // that it does exists, but if it does, we only support cloud configs at
    // this point.
    String cloudConfig = null;
    if (bootDisk.bootConfig != null && bootDisk.bootConfig.files.length > CLOUD_CONFIG_DEFAULT_FILE_INDEX) {
        cloudConfig = bootDisk.bootConfig.files[CLOUD_CONFIG_DEFAULT_FILE_INDEX].contents;
    }
    String instanceType = aws.child.description.instanceType;
    if (instanceType == null) {
        // fallback to legacy usage of name
        instanceType = aws.child.description.name;
    }
    if (instanceType == null) {
        aws.error = new IllegalStateException("AWS Instance type not specified");
        aws.stage = AWSInstanceStage.ERROR;
        handleAllocation(aws);
        return;
    }
    RunInstancesRequest runInstancesRequest = new RunInstancesRequest().withImageId(aws.bootDiskImageNativeId).withInstanceType(instanceType).withMinCount(1).withMaxCount(1).withMonitoring(true).withTagSpecifications(new TagSpecification().withResourceType(ResourceType.Instance).withTags(aws.getAWSTags()));
    if (aws.placement != null) {
        runInstancesRequest.withPlacement(new Placement(aws.placement));
    }
    if (aws.child.customProperties != null && aws.child.customProperties.containsKey(CUSTOM_PROP_SSH_KEY_NAME)) {
        runInstancesRequest = runInstancesRequest.withKeyName(aws.child.customProperties.get(CUSTOM_PROP_SSH_KEY_NAME));
    }
    if (!aws.dataDisks.isEmpty() || bootDisk.capacityMBytes > 0 || bootDisk.customProperties != null) {
        DescribeImagesRequest imagesDescriptionRequest = new DescribeImagesRequest();
        imagesDescriptionRequest.withImageIds(aws.bootDiskImageNativeId);
        DescribeImagesResult imagesDescriptionResult = aws.amazonEC2Client.describeImages(imagesDescriptionRequest);
        if (imagesDescriptionResult.getImages().size() != 1) {
            handleError(aws, new IllegalStateException("AWS ImageId is not available"));
            return;
        }
        Image image = imagesDescriptionResult.getImages().get(0);
        AssertUtil.assertNotNull(aws.instanceTypeInfo, "instanceType cannot be null");
        List<BlockDeviceMapping> blockDeviceMappings = image.getBlockDeviceMappings();
        String rootDeviceType = image.getRootDeviceType();
        String bootDiskType = bootDisk.customProperties.get(DEVICE_TYPE);
        boolean hasHardConstraint = containsHardConstraint(bootDisk);
        BlockDeviceMapping rootDeviceMapping = null;
        try {
            // The number of instance-store disks that will be provisioned is limited by the instance-type.
            suppressExcessInstanceStoreDevices(blockDeviceMappings, aws.instanceTypeInfo);
            for (BlockDeviceMapping blockDeviceMapping : blockDeviceMappings) {
                EbsBlockDevice ebs = blockDeviceMapping.getEbs();
                String diskType = getDeviceType(ebs);
                if (hasHardConstraint) {
                    validateIfDeviceTypesAreMatching(diskType, bootDiskType);
                }
                if (blockDeviceMapping.getNoDevice() != null) {
                    continue;
                }
                if (rootDeviceType.equals(AWSStorageType.EBS.getName()) && blockDeviceMapping.getDeviceName().equals(image.getRootDeviceName())) {
                    rootDeviceMapping = blockDeviceMapping;
                    continue;
                }
                DiskState diskState = new DiskState();
                copyCustomProperties(diskState, bootDisk);
                addMandatoryProperties(diskState, blockDeviceMapping, aws);
                updateDeviceMapping(diskType, bootDiskType, blockDeviceMapping.getDeviceName(), ebs, diskState);
                // update disk state with final volume-type and iops
                if (diskType.equals(AWSStorageType.EBS.getName())) {
                    diskState.customProperties.put(VOLUME_TYPE, ebs.getVolumeType());
                    diskState.customProperties.put(DISK_IOPS, String.valueOf(ebs.getIops()));
                }
                aws.imageDisks.add(diskState);
            }
            customizeBootDiskProperties(bootDisk, rootDeviceType, rootDeviceMapping, hasHardConstraint, aws);
            List<DiskState> ebsDisks = new ArrayList<>();
            List<DiskState> instanceStoreDisks = new ArrayList<>();
            if (!aws.dataDisks.isEmpty()) {
                if (!rootDeviceType.equals(AWSStorageType.EBS.name().toLowerCase())) {
                    instanceStoreDisks = aws.dataDisks;
                    assertAndResetPersistence(instanceStoreDisks);
                    validateSupportForAdditionalInstanceStoreDisks(instanceStoreDisks, blockDeviceMappings, aws.instanceTypeInfo, rootDeviceType);
                } else {
                    splitDataDisks(aws.dataDisks, instanceStoreDisks, ebsDisks);
                    setEbsDefaultsIfNotSpecified(ebsDisks, Boolean.FALSE);
                    if (!instanceStoreDisks.isEmpty()) {
                        assertAndResetPersistence(instanceStoreDisks);
                        validateSupportForAdditionalInstanceStoreDisks(instanceStoreDisks, blockDeviceMappings, aws.instanceTypeInfo, rootDeviceType);
                    }
                }
            }
            // get the available attach paths for new disks and external disks
            List<String> usedDeviceNames = null;
            if (!instanceStoreDisks.isEmpty() || !ebsDisks.isEmpty() || !aws.externalDisks.isEmpty()) {
                usedDeviceNames = getUsedDeviceNames(blockDeviceMappings);
            }
            if (!instanceStoreDisks.isEmpty()) {
                List<String> usedVirtualNames = getUsedVirtualNames(blockDeviceMappings);
                blockDeviceMappings.addAll(createInstanceStoreMappings(instanceStoreDisks, usedDeviceNames, usedVirtualNames, aws.instanceTypeInfo.id, aws.instanceTypeInfo.dataDiskSizeInMB, image.getPlatform(), image.getVirtualizationType()));
            }
            if (!ebsDisks.isEmpty() || !aws.externalDisks.isEmpty()) {
                aws.availableEbsDiskNames = AWSBlockDeviceNameMapper.getAvailableNames(AWSSupportedOS.get(image.getPlatform()), AWSSupportedVirtualizationTypes.get(image.getVirtualizationType()), AWSStorageType.EBS, instanceType, usedDeviceNames);
            }
            if (!ebsDisks.isEmpty()) {
                blockDeviceMappings.addAll(createEbsDeviceMappings(ebsDisks, aws.availableEbsDiskNames));
            }
            runInstancesRequest.withBlockDeviceMappings(blockDeviceMappings);
        } catch (Exception e) {
            aws.error = e;
            aws.stage = AWSInstanceStage.ERROR;
            handleAllocation(aws);
            return;
        }
    }
    AWSNicContext primaryNic = aws.getPrimaryNic();
    if (primaryNic != null && primaryNic.nicSpec != null) {
        runInstancesRequest.withNetworkInterfaces(primaryNic.nicSpec);
    } else {
        runInstancesRequest.withSecurityGroupIds(AWSUtils.getOrCreateSecurityGroups(aws, null));
    }
    if (cloudConfig != null) {
        try {
            runInstancesRequest.setUserData(Base64.getEncoder().encodeToString(cloudConfig.getBytes(Utils.CHARSET)));
        } catch (UnsupportedEncodingException e) {
            handleError(aws, new IllegalStateException("Error encoding user data"));
            return;
        }
    }
    String message = "[AWSInstanceService] Sending run instance request for instance id: " + aws.bootDiskImageNativeId + ", instance type: " + instanceType + ", parent task id: " + aws.computeRequest.taskReference;
    this.logInfo(() -> message);
    // handler invoked once the EC2 runInstancesAsync commands completes
    AsyncHandler<RunInstancesRequest, RunInstancesResult> creationHandler = new AWSCreationHandler(this, aws);
    aws.amazonEC2Client.runInstancesAsync(runInstancesRequest, creationHandler);
}
Also used : DescribeImagesRequest(com.amazonaws.services.ec2.model.DescribeImagesRequest) DiskState(com.vmware.photon.controller.model.resources.DiskService.DiskState) ArrayList(java.util.ArrayList) UnsupportedEncodingException(java.io.UnsupportedEncodingException) TagSpecification(com.amazonaws.services.ec2.model.TagSpecification) Image(com.amazonaws.services.ec2.model.Image) AmazonServiceException(com.amazonaws.AmazonServiceException) AmazonEC2Exception(com.amazonaws.services.ec2.model.AmazonEC2Exception) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Placement(com.amazonaws.services.ec2.model.Placement) DescribeImagesResult(com.amazonaws.services.ec2.model.DescribeImagesResult) RunInstancesResult(com.amazonaws.services.ec2.model.RunInstancesResult) EbsBlockDevice(com.amazonaws.services.ec2.model.EbsBlockDevice) BlockDeviceMapping(com.amazonaws.services.ec2.model.BlockDeviceMapping) InstanceBlockDeviceMapping(com.amazonaws.services.ec2.model.InstanceBlockDeviceMapping) RunInstancesRequest(com.amazonaws.services.ec2.model.RunInstancesRequest) AWSNicContext(com.vmware.photon.controller.model.adapters.awsadapter.AWSInstanceContext.AWSNicContext)

Aggregations

EbsBlockDevice (com.amazonaws.services.ec2.model.EbsBlockDevice)7 BlockDeviceMapping (com.amazonaws.services.ec2.model.BlockDeviceMapping)5 Image (com.amazonaws.services.ec2.model.Image)3 DiskState (com.vmware.photon.controller.model.resources.DiskService.DiskState)3 ArrayList (java.util.ArrayList)3 DescribeImagesRequest (com.amazonaws.services.ec2.model.DescribeImagesRequest)2 DescribeImagesResult (com.amazonaws.services.ec2.model.DescribeImagesResult)2 InstanceBlockDeviceMapping (com.amazonaws.services.ec2.model.InstanceBlockDeviceMapping)2 AmazonServiceException (com.amazonaws.AmazonServiceException)1 AmazonEC2Exception (com.amazonaws.services.ec2.model.AmazonEC2Exception)1 Filter (com.amazonaws.services.ec2.model.Filter)1 Placement (com.amazonaws.services.ec2.model.Placement)1 RunInstancesRequest (com.amazonaws.services.ec2.model.RunInstancesRequest)1 RunInstancesResult (com.amazonaws.services.ec2.model.RunInstancesResult)1 Tag (com.amazonaws.services.ec2.model.Tag)1 TagSpecification (com.amazonaws.services.ec2.model.TagSpecification)1 AWSNicContext (com.vmware.photon.controller.model.adapters.awsadapter.AWSInstanceContext.AWSNicContext)1 TestAWSSetupUtils.deleteVMsOnThisEndpoint (com.vmware.photon.controller.model.adapters.awsadapter.TestAWSSetupUtils.deleteVMsOnThisEndpoint)1 TagsUtil.newTagState (com.vmware.photon.controller.model.adapters.util.TagsUtil.newTagState)1 ComputeState (com.vmware.photon.controller.model.resources.ComputeService.ComputeState)1