/** * Counts the number of instances in EC2 currently running that are using the specified image and * a template. * * @param ami If AMI is left null, then all instances are counted and template description is * ignored. * <p>This includes those instances that may be started outside Jenkins. * @param templateDesc */ public int countCurrentEC2Slaves(String ami, String templateDesc) throws AmazonClientException { int n = 0; for (Reservation r : connect().describeInstances().getReservations()) { for (Instance i : r.getInstances()) { if (isEc2ProvisionedAmiSlave(i, ami, templateDesc)) { InstanceStateName stateName = InstanceStateName.fromValue(i.getState().getName()); if (stateName == InstanceStateName.Pending || stateName == InstanceStateName.Running) { EC2AbstractSlave foundSlave = null; for (EC2AbstractSlave ec2Node : NodeIterator.nodes(EC2AbstractSlave.class)) { if (ec2Node.getInstanceId().equals(i.getInstanceId())) { foundSlave = ec2Node; break; } } // Don't count disconnected slaves as being used, we will connected them later is // required if (foundSlave != null && foundSlave.toComputer().isOffline()) continue; n++; } } } } // Count pending spot requests too for (SpotInstanceRequest sir : connect().describeSpotInstanceRequests().getSpotInstanceRequests()) { // Count Spot requests that are open and still have a // chance to be active. if (sir.getState().equals("open")) { n++; } } return n; }
/** Debug command to attach to a running instance. */ public void doAttach(StaplerRequest req, StaplerResponse rsp, @QueryParameter String id) throws ServletException, IOException, AmazonClientException { checkPermission(PROVISION); SlaveTemplate t = getTemplates().get(0); StringWriter sw = new StringWriter(); StreamTaskListener listener = new StreamTaskListener(sw); EC2AbstractSlave node = t.attach(id, listener); Hudson.getInstance().addNode(node); rsp.sendRedirect2(req.getContextPath() + "/computer/" + node.getNodeName()); }
@Override public Node reconfigure(final StaplerRequest req, JSONObject form) throws FormException { if (form == null) { return null; } EC2AbstractSlave result = (EC2AbstractSlave) super.reconfigure(req, form); /* Get rid of the old tags, as represented by ourselves. */ clearLiveInstancedata(); /* Set the new tags, as represented by our successor */ result.pushLiveInstancedata(); return result; }
public int getNumExecutors() { try { return Integer.parseInt(numExecutors); } catch (NumberFormatException e) { return EC2AbstractSlave.toNumExecutors(type); } }
public ListBoxModel doFillZoneItems( @QueryParameter boolean useInstanceProfileForCredentials, @QueryParameter String credentialsId, @QueryParameter String region) throws IOException, ServletException { AWSCredentialsProvider credentialsProvider = EC2Cloud.createCredentialsProvider(useInstanceProfileForCredentials, credentialsId); return EC2AbstractSlave.fillZoneItems(credentialsProvider, region); }
public HttpResponse doProvision(@QueryParameter String template) throws ServletException, IOException { checkPermission(PROVISION); if (template == null) { throw HttpResponses.error(SC_BAD_REQUEST, "The 'template' query parameter is missing"); } SlaveTemplate t = getTemplate(template); if (t == null) { throw HttpResponses.error(SC_BAD_REQUEST, "No such template: " + template); } StringWriter sw = new StringWriter(); StreamTaskListener listener = new StreamTaskListener(sw); try { EC2AbstractSlave node = t.provision(listener); Hudson.getInstance().addNode(node); return HttpResponses.redirectViaContextPath("/computer/" + node.getNodeName()); } catch (AmazonClientException e) { throw HttpResponses.error(SC_INTERNAL_SERVER_ERROR, e); } }
/** * Determines whether the AMI of the given instance matches the AMI of template and has the * required label (if requiredLabel is non-null) */ private boolean checkInstance( PrintStream logger, Instance existingInstance, Label requiredLabel, EC2AbstractSlave[] returnNode) { logProvision(logger, "checkInstance: " + existingInstance); if (StringUtils.isNotBlank(getIamInstanceProfile())) { if (existingInstance.getIamInstanceProfile() != null) { if (!existingInstance.getIamInstanceProfile().getArn().equals(getIamInstanceProfile())) { logProvision(logger, " false - IAM Instance profile does not match"); return false; } // Match, fall through } else { logProvision(logger, " false - Null IAM Instance profile"); return false; } } if (existingInstance .getState() .getName() .equalsIgnoreCase(InstanceStateName.Terminated.toString()) || existingInstance .getState() .getName() .equalsIgnoreCase(InstanceStateName.ShuttingDown.toString())) { logProvision(logger, " false - Instance is terminated or shutting down"); return false; } // See if we know about this and it has capacity for (EC2AbstractSlave node : NodeIterator.nodes(EC2AbstractSlave.class)) { if (node.getInstanceId().equals(existingInstance.getInstanceId())) { logProvision(logger, "Found existing corresponding Jenkins slave: " + node.getInstanceId()); if (!node.toComputer().isPartiallyIdle()) { logProvision(logger, " false - Node is not partially idle"); return false; } // REMOVEME - this was added to force provision to work, but might not allow // stopped instances to be found - need to investigate further else if (false && node.toComputer().isOffline()) { logProvision(logger, " false - Node is offline"); return false; } else if (requiredLabel != null && !requiredLabel.matches(node.getAssignedLabels())) { logProvision(logger, " false - we need a Node having label " + requiredLabel); return false; } else { logProvision(logger, " true - Node has capacity - can use it"); returnNode[0] = node; return true; } } } logProvision(logger, " true - Instance has no node, but can be used"); return true; }