public List<SpotInstanceOfferResult> createSpotInstanceOffer(SpotInstanceOffer request) { RequestSpotInstancesRequest spotRequest = new RequestSpotInstancesRequest(request.getOfferValue().toPlainString()) .withValidFrom(request.getValidFrom()) .withValidUntil(request.getValidUntil()) .withType(SpotInstanceType.fromValue(request.getType().getName())) .withInstanceCount(request.getNumberOfInstances()) .withLaunchSpecification(new LaunchSpecification() .withInstanceType(request.getInstanceType().getName()) .withImageId(request.getImageId()) .withKeyName(request.getKeyName())); RequestSpotInstancesResult requestedSpotInstances = ec2_.requestSpotInstances(spotRequest); request.setStatus(new InstanceTemplateStatus().setStatus(Status.SUCCESS)); return toSpotInstanceResults(request, requestedSpotInstances.getSpotInstanceRequests()); }
public void createInstances(int count, double priceLimitDollars) { AmazonEC2 ec2 = new AmazonEC2Client(getAwsCredentials()); ec2.setEndpoint(getOrCry("ec2endpoint")); log.info("Requesting " + count + " instances of type " + getOrCry("ec2instancetype") + " with price limit of " + priceLimitDollars + " US$"); log.debug(startupScript); try { // our bid RequestSpotInstancesRequest runInstancesRequest = new RequestSpotInstancesRequest() .withSpotPrice(Double.toString(priceLimitDollars)) .withInstanceCount(count).withType("persistent"); // increase volume size // BlockDeviceMapping mapping = new BlockDeviceMapping() // .withDeviceName("/dev/sda1").withEbs( // new EbsBlockDevice().withVolumeSize(Integer // .parseInt(getOrCry("ec2disksize")))); // what we want LaunchSpecification workerSpec = new LaunchSpecification() .withInstanceType(getOrCry("ec2instancetype")) .withImageId(getOrCry("ec2ami")) .withKeyName(getOrCry("ec2keypair")) // .withBlockDeviceMappings(mapping) .withUserData( new String(Base64.encodeBase64(startupScript .getBytes()))); runInstancesRequest.setLaunchSpecification(workerSpec); // place the request ec2.requestSpotInstances(runInstancesRequest); log.info("Request placed, now use 'monitor' to check how many instances are running. Use 'shutdown' to cancel the request and terminate the corresponding instances."); } catch (Exception e) { log.warn("Failed to start instances - ", e); } }
public List<String> launch(String workerAMI, String instanceType, int num, double price, List<String> securityGroups, String keyName, String userData, String charset) throws UnsupportedEncodingException { RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); requestRequest.setSpotPrice(Double.toString(price)); requestRequest.setInstanceCount(Integer.valueOf(num)); LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId(workerAMI); launchSpecification.setInstanceType(instanceType); launchSpecification.setSecurityGroups(securityGroups); launchSpecification.setUserData(new String(Base64.encode(userData.getBytes(charset)))); launchSpecification.setKeyName(keyName); //for test requestRequest.setLaunchSpecification(launchSpecification); RequestSpotInstancesResult requestResult = ec2 .requestSpotInstances(requestRequest); List<SpotInstanceRequest> requestResponses = requestResult .getSpotInstanceRequests(); List<String> spotInstanceRequestIds = new ArrayList<String>(); for (SpotInstanceRequest requestResponse : requestResponses) { System.out.println("Created Spot Request: " + requestResponse.getSpotInstanceRequestId()); spotInstanceRequestIds.add(requestResponse .getSpotInstanceRequestId()); } return spotInstanceRequestIds; }
public static void main(String[] args) { String region = "us-east-1"; AWSCredentials credentials = new BasicAWSCredentials(awsAccessKeyId, awsSecretAccessKey); AmazonEC2 api = AmazonEC2ClientBuilder.standard().withRegion(region) .withCredentials(new AWSStaticCredentialsProvider(credentials)).build(); // no particular availability zone String availabilityZone = null; String instanceType = "t1.micro"; String imageId = "ami-3cf8b154"; List<String> securityGroups = Arrays.asList("webserver"); String keyPair = "instancekey"; String bootScript = Joiner.on("\n") .join(Arrays.asList("#!/bin/bash", "sudo apt-get update -qy", "sudo apt-get install -qy apache2")); int instanceCount = 50; String bidPrice = "0.001"; SpotPlacement placement = new SpotPlacement().withAvailabilityZone(availabilityZone); LaunchSpecification launchSpec = new LaunchSpecification().withInstanceType(instanceType).withImageId(imageId) .withPlacement(placement).withSecurityGroups(securityGroups).withKeyName(keyPair) .withUserData(AmazonApiUtils.base64Encode(bootScript)); RequestSpotInstancesRequest request = new RequestSpotInstancesRequest().withInstanceCount(instanceCount) .withType(SpotInstanceType.Persistent).withSpotPrice(bidPrice).withLaunchSpecification(launchSpec); RequestSpotInstancesResult result = api.requestSpotInstances(request); for (SpotInstanceRequest spotRequest : result.getSpotInstanceRequests()) { LOG.info("placed request: {}", spotRequest.getSpotInstanceRequestId()); } }
@Override public List<SpotInstanceRequest> call() { LaunchSpecification spec = new LaunchSpecification(); spec.withInstanceType(this.instanceTemplate.getInstanceType()); spec.withImageId(this.instanceTemplate.getAmiId()); InstanceNetworkInterfaceSpecification nic = new InstanceNetworkInterfaceSpecification(); nic.withDeviceIndex(0); // select a subnet at random nic.withSubnetId(randomSubnet()); nic.withAssociatePublicIpAddress(this.instanceTemplate.isAssignPublicIp()); nic.withGroups(this.instanceTemplate.getSecurityGroupIds()); spec.withNetworkInterfaces(nic); spec.withKeyName(this.instanceTemplate.getKeyPair()); spec.withIamInstanceProfile( new IamInstanceProfileSpecification().withArn(this.instanceTemplate.getIamInstanceProfileARN())); spec.withUserData(this.instanceTemplate.getEncodedUserData()); spec.withEbsOptimized(this.instanceTemplate.isEbsOptimized()); RequestSpotInstancesRequest spotRequest = new RequestSpotInstancesRequest().withInstanceCount(this.count) .withType(SpotInstanceType.Persistent).withSpotPrice(this.bidPrice).withLaunchSpecification(spec); RequestSpotInstancesResult result = getClient().getApi().requestSpotInstances(spotRequest); List<String> spotRequestIds = result.getSpotInstanceRequests().stream() .map(SpotInstanceRequest::getSpotInstanceRequestId).collect(Collectors.toList()); if (!this.instanceTemplate.getTags().isEmpty()) { tagRequests(spotRequestIds); } return awaitSpotRequests(spotRequestIds); }
@Override public void execute(AmazonEC2 client, Pool pool, DelegateExecution execution) throws IOException { /* before sending a new request, we check to see if we already registered a launch group with the process ID, if yes, we don't re-send the request */ final String businessKey = execution.getProcessBusinessKey(); /* we timeout if requests have already been sent - the activity is being retried. */ Optional<Object> alreadySent = Optional.fromNullable( execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS)); if (alreadySent.isPresent()) { DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest() .withFilters(new Filter() .withName("launch-group").withValues(businessKey) .withName("state").withValues("open", "active")); Stopwatch stopwatch = new Stopwatch().start(); while (stopwatch.elapsedTime(TimeUnit.MINUTES) < 2) { DescribeSpotInstanceRequestsResult result = client.describeSpotInstanceRequests(describeRequest); List<SpotInstanceRequest> pending = result.getSpotInstanceRequests(); if (pending.size() > 0) { LOG.info("Not resending spot instance requests {} for businessKey: {}.", pending, businessKey); execution.setVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS, collectSpotInstanceRequestIds(pending)); return; } LOG.info("The describe call has not returned anything yet, waiting 20s and retrying."); Uninterruptibles.sleepUninterruptibly(20, TimeUnit.SECONDS); } } final RequestSpotInstancesRequest request = createSpotInstancesRequest(pool, execution); execution.setVariable(ProcessVariables.SPOT_REQUESTS_SENT, true); RequestSpotInstancesResult requestResult = client.requestSpotInstances(request); List<String> spotInstanceRequestIds = collectSpotInstanceRequestIds(requestResult.getSpotInstanceRequests()); execution.setVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS, spotInstanceRequestIds); }
@Override public RequestSpotInstancesResult requestSpotInstances(RequestSpotInstancesRequest requestSpotInstancesRequest) throws AmazonServiceException, AmazonClientException { throw new UnsupportedOperationException("Not supported in mock"); }
/** * Builds a {@code RequestSpotInstancesRequest}. * * @return the {@code RequestSpotInstancesRequest} */ @VisibleForTesting protected RequestSpotInstancesRequest newRequestSpotInstanceRequest(String virtualInstanceId) { String image = template.getImage(); String type = template.getType(); InstanceNetworkInterfaceSpecification network = getInstanceNetworkInterfaceSpecification(template); List<BlockDeviceMapping> deviceMappings = getBlockDeviceMappings(template); LaunchSpecification launchSpecification = new LaunchSpecification() .withImageId(image) .withInstanceType(type) .withNetworkInterfaces(network) .withBlockDeviceMappings(deviceMappings) .withEbsOptimized(template.isEbsOptimized()); if (template.getIamProfileName().isPresent()) { launchSpecification.withIamInstanceProfile(new IamInstanceProfileSpecification() .withName(template.getIamProfileName().get())); } if (template.getKeyName().isPresent()) { launchSpecification.withKeyName(template.getKeyName().get()); } SpotPlacement placement = null; if (template.getAvailabilityZone().isPresent()) { placement = new SpotPlacement().withAvailabilityZone(template.getAvailabilityZone().get()); } if (template.getPlacementGroup().isPresent()) { placement = (placement == null) ? new SpotPlacement().withGroupName(template.getPlacementGroup().get()) : placement.withGroupName(template.getPlacementGroup().get()); } launchSpecification.withPlacement(placement); Optional<String> userData = template.getUserData(); if (userData.isPresent()) { launchSpecification.withUserData(userData.get()); } LOG.info(">> Spot instance request type: {}, image: {}", type, image); RequestSpotInstancesRequest request = new RequestSpotInstancesRequest() .withSpotPrice(template.getSpotBidUSDPerHour().get().toString()) .withLaunchSpecification(launchSpecification) .withInstanceCount(1) .withClientToken(determineClientToken(virtualInstanceId, requestExpirationTime.getTime())) .withValidUntil(requestExpirationTime); Optional<Integer> blockDurationMinutes = template.getBlockDurationMinutes(); if (blockDurationMinutes.isPresent()) { request.withBlockDurationMinutes(blockDurationMinutes.get()); } return request; }
public void spotRequest() { if (instances <= instancesSet.size()) { logger.info("No more instances will be launched because there are already enough."); return; } com.amazonaws.services.ec2.AmazonEC2 client = AmazonEC2.connect(); RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); requestRequest.setSpotPrice(Double.valueOf(maxPrice).toString()); // requestRequest.setInstanceCount(instances); requestRequest.setInstanceCount(instances - instancesSet.size()); LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId(ami); launchSpecification.setInstanceType(size); if (userData != null) launchSpecification.setUserData(Base64.encodeAsString(userData .getBytes())); BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping(); blockDeviceMapping.setDeviceName("/dev/sda1"); EbsBlockDevice ebs = new EbsBlockDevice(); ebs.setDeleteOnTermination(Boolean.TRUE); ebs.setVolumeSize(diskSize); blockDeviceMapping.setEbs(ebs); ArrayList<BlockDeviceMapping> blockList = new ArrayList<BlockDeviceMapping>(); blockList.add(blockDeviceMapping); launchSpecification.setBlockDeviceMappings(blockList); ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add(Configuration.SECURITY_GROUP_NAME); launchSpecification.setSecurityGroups(securityGroups); launchSpecification.setKeyName(keyName); requestRequest.setLaunchSpecification(launchSpecification); RequestSpotInstancesResult requestResult = client .requestSpotInstances(requestRequest); List<SpotInstanceRequest> reqs = requestResult .getSpotInstanceRequests(); for (SpotInstanceRequest req : reqs) instancesSet.add(new Instance(this, req.getInstanceId(), req .getSpotInstanceRequestId())); }
protected RequestSpotInstancesRequest createSpotInstancesRequest(Pool pool, DelegateExecution execution) throws IOException { return (RequestSpotInstancesRequest) createRequest(pool, execution, true); }
private AmazonWebServiceRequest createRequest(Pool pool, DelegateExecution execution, boolean spot) throws IOException { final String businessKey = execution.getProcessBusinessKey(); final String securityGroupName = SecurityGroups.formatNameFromBusinessKey(businessKey); final String keyPairName = KeyPairs.formatNameFromBusinessKey(businessKey); final String instanceType = pool.getHardware().getType(); final String imageId = getImageIdFromPoolConfigurationOrQueryImageTable( pool, pool.getProvider(), instanceType); final String userData = Resources.toString(Resources.getResource(RunInstances.class, "/org/apache/provisionr/amazon/userdata.sh"), Charsets.UTF_8); List<BlockDevice> blockDevices = pool.getHardware().getBlockDevices(); List<BlockDeviceMapping> blockDeviceMappings = Lists.newArrayList(); if (blockDevices != null && blockDevices.size() > 0) { for (BlockDevice device : blockDevices) { blockDeviceMappings.add(new BlockDeviceMapping() .withDeviceName(device.getName()) .withEbs(new EbsBlockDevice() .withVolumeSize(device.getSize()) .withDeleteOnTermination(true) )); } } if (spot) { Calendar validUntil = Calendar.getInstance(); validUntil.add(Calendar.MINUTE, 10); final String spotPrice = checkNotNull(pool.getProvider().getOption(ProviderOptions.SPOT_BID), "The bid for spot instances was not specified"); LaunchSpecification ls = new LaunchSpecification() .withInstanceType(instanceType) .withKeyName(keyPairName) .withImageId(imageId) .withBlockDeviceMappings(blockDeviceMappings) .withSecurityGroups(Lists.newArrayList(securityGroupName)) .withUserData(Base64.encodeBytes(userData.getBytes(Charsets.UTF_8))); return new RequestSpotInstancesRequest() .withSpotPrice(spotPrice) .withLaunchSpecification(ls) .withLaunchGroup(businessKey) .withInstanceCount(pool.getExpectedSize()) .withType(SpotInstanceType.OneTime) .withValidUntil(validUntil.getTime()); } else { return new RunInstancesRequest() .withClientToken(businessKey) .withSecurityGroups(securityGroupName) .withKeyName(keyPairName) .withInstanceType(instanceType) .withImageId(imageId) .withBlockDeviceMappings(blockDeviceMappings) .withMinCount(pool.getMinSize()) .withMaxCount(pool.getExpectedSize()) .withUserData(Base64.encodeBytes(userData.getBytes(Charsets.UTF_8))); } }