private ECSTaskTemplate getTemplate(Label label) { for (ECSTaskTemplate t : templates) { if (label == null || label.matches(t.getLabelSet())) { return t; } } return null; }
@DataBoundConstructor public ECSCloud( String name, List<ECSTaskTemplate> templates, @Nonnull String credentialsId, String cluster, String regionName) { super(name); this.credentialsId = credentialsId; this.cluster = cluster; this.templates = templates; this.regionName = regionName; if (templates != null) { for (ECSTaskTemplate template : templates) { template.setOwer(this); } } }
@Override public Collection<NodeProvisioner.PlannedNode> provision(Label label, int excessWorkload) { try { List<NodeProvisioner.PlannedNode> r = new ArrayList<NodeProvisioner.PlannedNode>(); final ECSTaskTemplate template = getTemplate(label); for (int i = 1; i <= excessWorkload; i++) { r.add( new NodeProvisioner.PlannedNode( template.getDisplayName(), Computer.threadPoolForRemoting.submit(new ProvisioningCallback(template, label)), 1)); } return r; } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to provision ECS slave", e); return Collections.emptyList(); } }
public Node call() throws Exception { String uniq = Long.toHexString(System.nanoTime()); ECSSlave slave = new ECSSlave( ECSCloud.this, name + "-" + uniq, template.getRemoteFSRoot(), label == null ? null : label.toString(), new JNLPLauncher()); Jenkins.getInstance().addNode(slave); LOGGER.log(Level.INFO, "Created Slave: {0}", slave.getNodeName()); final AmazonECSClient client = getAmazonECSClient(); LOGGER.log(Level.INFO, "Selected Region: {0}", getRegionName()); client.setRegion(getRegion(getRegionName())); Collection<String> command = getDockerRunCommand(slave); String definitionArn = template.getTaskDefinitionArn(); slave.setTaskDefinitonArn(definitionArn); final RunTaskResult runTaskResult = client.runTask( new RunTaskRequest() .withTaskDefinition(definitionArn) .withOverrides( new TaskOverride() .withContainerOverrides( new ContainerOverride() .withName("jenkins-slave") .withCommand(command))) .withCluster(cluster)); if (!runTaskResult.getFailures().isEmpty()) { LOGGER.log( Level.WARNING, "Slave {0} - Failure to run task with definition {1} on ECS cluster {2}", new Object[] {slave.getNodeName(), definitionArn, cluster}); for (Failure failure : runTaskResult.getFailures()) { LOGGER.log( Level.WARNING, "Slave {0} - Failure reason={1}, arn={2}", new Object[] {slave.getNodeName(), failure.getReason(), failure.getArn()}); } throw new AbortException("Failed to run slave container " + slave.getNodeName()); } String taskArn = runTaskResult.getTasks().get(0).getTaskArn(); LOGGER.log( Level.INFO, "Slave {0} - Slave Task Started : {1}", new Object[] {slave.getNodeName(), taskArn}); slave.setTaskArn(taskArn); int i = 0; int j = 100; // wait 100 seconds // now wait for slave to be online for (; i < j; i++) { if (slave.getComputer() == null) { throw new IllegalStateException( "Slave " + slave.getNodeName() + " - Node was deleted, computer is null"); } if (slave.getComputer().isOnline()) { break; } LOGGER.log( Level.FINE, "Waiting for slave {0} (ecs task {1}) to connect ({2}/{3}).", new Object[] {slave.getNodeName(), taskArn, i, j}); Thread.sleep(1000); } if (!slave.getComputer().isOnline()) { throw new IllegalStateException( "ECS Slave " + slave.getNodeName() + " (ecs task " + taskArn + ") is not connected after " + j + " seconds"); } LOGGER.log( Level.INFO, "ECS Slave " + slave.getNodeName() + " (ecs task {0}) connected", taskArn); return slave; }