use of com.thoughtworks.gocd.elasticagent.ecs.domain.Platform in project gocd-ecs-elastic-agent by gocd.
the class SpotInstanceService method create.
public Optional<ContainerInstance> create(PluginSettings pluginSettings, ElasticAgentProfileProperties elasticAgentProfileProperties, ConsoleLogAppender consoleLogAppender) throws LimitExceededException {
Platform platform = elasticAgentProfileProperties.platform();
synchronized (platform) {
consoleLogAppender.accept("The elastic agent profile is configured to run on a spot instance. Initiating steps to request for a spot instance.");
EC2Config ec2Config = ec2ConfigBuilder.withSettings(pluginSettings).withProfile(elasticAgentProfileProperties).build();
List<Instance> allRegisteredSpotInstancesForPlatform = spotInstanceHelper.allRegisteredSpotInstancesForPlatform(pluginSettings, platform);
synchronized (untaggedSpotRequests) {
refreshUnTaggedSpotRequests(pluginSettings);
List<SpotInstanceRequest> spotRequestsWithoutRegisteredInstances = spotRequestsWithoutRegisteredInstances(pluginSettings, platform, allRegisteredSpotInstancesForPlatform);
Collection<SpotInstanceRequest> allSpotRequestsWithoutRunningInstance = union(spotRequestsWithoutRegisteredInstances, untaggedSpotRequests);
LOG.info("[create-agent] For Platform: '{}',All-Registered-Spot-Instances count: '{}', Spot-Requests-Without-Registered-Instances count: '{}'," + "UnTagged-Spot-Requests count: '{}'", platform.name(), allRegisteredSpotInstancesForPlatform.size(), spotRequestsWithoutRegisteredInstances.size(), untaggedSpotRequests.size());
boolean openSpotRequestAvailable = isThereAOpenSpotRequestMatchingProfile(allSpotRequestsWithoutRunningInstance, ec2Config);
if (openSpotRequestAvailable) {
consoleLogAppender.accept("There is an open spot request matching the profile, not requesting for a new spot instance.");
LOG.debug("[create-agent] There is an open spot request matching the profile, not requesting for a new spot instance.");
return Optional.empty();
}
boolean clusterMaxedOut = (allRegisteredSpotInstancesForPlatform.size() + allSpotRequestsWithoutRunningInstance.size()) >= pluginSettings.getMaxLinuxSpotInstanceAllowed();
if (clusterMaxedOut) {
consoleLogAppender.accept(format("The number of %s EC2 (spot instances running + open spot requests) is currently at the maximum permissible limit(%s). Not requesting for a spot instance.", platform, pluginSettings.getMaxLinuxSpotInstanceAllowed()));
throw new LimitExceededException(format("The number of %s EC2 Spot Instances running is currently at the maximum permissible limit(%s). Not requesting for any more EC2 Spot Instances.", platform.name(), pluginSettings.getMaxLinuxSpotInstanceAllowed()));
}
}
LOG.debug("[create-agent] Initiating a new spot instance request.");
RequestSpotInstancesResult requestSpotInstancesResult = spotInstanceHelper.requestSpotInstanceRequest(pluginSettings, ec2Config, consoleLogAppender);
SpotInstanceRequest spotInstanceRequest = requestSpotInstancesResult.getSpotInstanceRequests().get(0);
/*
All valid spot SpotRequests are tagged after making a request for a spot instance.
There are times when tagging a spot request fails with 404 since aws does not find a spot request for the
given SpotInstanceRequestId. Ensuring that spot requests can be lookedup by id before tagging them.
*/
spotInstanceHelper.waitTillSpotRequestCanBeLookedUpById(pluginSettings, spotInstanceRequest.getSpotInstanceRequestId());
SpotInstanceStatus status = spotInstanceRequest.getStatus();
LOG.debug("[create-agent] Created spot instance request with request Id: {}, state: {}, status-code:{}, status-message:{}", spotInstanceRequest.getSpotInstanceRequestId(), spotInstanceRequest.getState(), status.getCode(), status.getMessage());
tagSpotRequest(pluginSettings, elasticAgentProfileProperties, spotInstanceRequest);
/*
A spot instance request is tagged post creation. AWS takes time to sync up the the tags on the spot request, hence
querying aws for the spot requests with tag filters does not yield results. Hence the SpotInstance service maintains
a list of new spot instance requests and removes from the list in future calls or as part of server ping.
*/
if (isSpotRequestValid(spotInstanceRequest)) {
untaggedSpotRequests.add(spotInstanceRequest);
}
return Optional.empty();
}
}
use of com.thoughtworks.gocd.elasticagent.ecs.domain.Platform in project gocd-ecs-elastic-agent by gocd.
the class ContainerInstanceHelperTest method shouldGroupByPlatform.
@Test
void shouldGroupByPlatform() {
final Instance linuxInstance1 = runningLinuxInstance("i-linux1");
final Instance linuxInstance2 = runningLinuxInstance("i-linux2");
final Instance windowsInstance1 = runningWindowsInstance("i-windows1");
final Instance windowsInstance2 = runningWindowsInstance("i-windows2");
final Map<Platform, List<Instance>> groupByPlatform = ContainerInstanceHelper.groupByPlatform(Arrays.asList(linuxInstance1, linuxInstance2, windowsInstance1, windowsInstance2));
assertThat(groupByPlatform).hasSize(2).containsEntry(LINUX, Arrays.asList(linuxInstance1, linuxInstance2)).containsEntry(WINDOWS, Arrays.asList(windowsInstance1, windowsInstance2));
}
use of com.thoughtworks.gocd.elasticagent.ecs.domain.Platform in project gocd-ecs-elastic-agent by gocd.
the class SpotRequestMatcher method matches.
public boolean matches(EC2Config ec2Config, SpotInstanceRequest spotInstanceRequest) {
if (spotInstanceRequest == null) {
return false;
}
LaunchSpecification launchSpecification = spotInstanceRequest.getLaunchSpecification();
final Platform platform = platformFor(spotInstanceRequest);
if (platform != ec2Config.getPlatform()) {
return false;
}
if (!StringUtils.equals(launchSpecification.getImageId(), ec2Config.getAmi())) {
return false;
}
if (!StringUtils.equals(ec2Config.getInstanceType(), launchSpecification.getInstanceType())) {
return false;
}
if (notMatching(ec2Config.getSubnetIds(), launchSpecification.getSubnetId())) {
return false;
}
if (notMatching(ec2Config.getSecurityGroups(), getInstanceSecurityGroups(launchSpecification))) {
return false;
}
return ec2Config.runAsSpotInstance();
}
use of com.thoughtworks.gocd.elasticagent.ecs.domain.Platform in project gocd-ecs-elastic-agent by gocd.
the class StopIdleInstanceSelectionStrategy method findInstancesToStop.
@Override
protected List<ContainerInstance> findInstancesToStop(PluginSettings pluginSettings, Platform platform, Map<String, ContainerInstance> instanceIdToContainerInstance, List<Instance> idleInstances) {
final Period timeInstanceCanStayIdle = platform == Platform.LINUX ? pluginSettings.stopLinuxInstanceAfter() : pluginSettings.stopWindowsInstanceAfter();
idleInstances.sort(new MostIdleInstanceComparator(clock.now()));
return idleInstances.stream().filter(isIdlePeriodIsMoreThan(timeInstanceCanStayIdle)).map(instance -> instanceIdToContainerInstance.get(instance.getInstanceId())).collect(Collectors.toList());
}
Aggregations