Skip to content
Permalink
Browse files
JENKINS-17086 Add iamInstanceProfile option to slave configuration
  • Loading branch information
ww-mgr committed May 16, 2013
1 parent 7d8a169 commit b5f2eb7beec88bb7d008ffeb0b1768404aba3b8f
Showing 5 changed files with 40 additions and 20 deletions.
@@ -75,7 +75,7 @@ public class SlaveTemplate implements Describable<SlaveTemplate> {
public final String jvmopts;
public final String subnetId;
public final String idleTerminationMinutes;
public final String iamRole;
public final String iamInstanceProfile;
public int instanceCap;
public final boolean stopOnTerminate;
private final List<EC2Tag> tags;
@@ -87,7 +87,7 @@ public class SlaveTemplate implements Describable<SlaveTemplate> {
private transient /*almost final*/ Set<String> securityGroupSet;

@DataBoundConstructor
public SlaveTemplate(String ami, String zone, SpotConfiguration spotConfig, String securityGroups, String remoteFS, String sshPort, InstanceType type, String labelString, Node.Mode mode, String description, String initScript, String userData, String numExecutors, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String subnetId, List<EC2Tag> tags, String idleTerminationMinutes, boolean usePrivateDnsName, String instanceCapStr, String iamRole) {
public SlaveTemplate(String ami, String zone, SpotConfiguration spotConfig, String securityGroups, String remoteFS, String sshPort, InstanceType type, String labelString, Node.Mode mode, String description, String initScript, String userData, String numExecutors, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String subnetId, List<EC2Tag> tags, String idleTerminationMinutes, boolean usePrivateDnsName, String instanceCapStr, String iamInstanceProfile) {
this.ami = ami;
this.zone = zone;
this.spotConfig = spotConfig;
@@ -116,7 +116,7 @@ public SlaveTemplate(String ami, String zone, SpotConfiguration spotConfig, Stri
this.instanceCap = Integer.parseInt(instanceCapStr);
}

this.iamRole = iamRole;
this.iamInstanceProfile = iamInstanceProfile;

readResolve(); // initialize
}
@@ -222,8 +222,8 @@ public String getSpotMaxBidPrice(){
return SpotConfiguration.normalizeBid(spotConfig.spotMaxBidPrice);
}

public String getIamRole() {
return iamRole;
public String getIamInstanceProfile() {
return iamInstanceProfile;
}


@@ -299,7 +299,6 @@ private EC2AbstractSlave provisionOndemand(TaskListener listener) throws AmazonC
diFilters.add(new Filter("key-name").withValues(keyPair.getKeyName()));
riRequest.setInstanceType(type.toString());
diFilters.add(new Filter("instance-type").withValues(type.toString()));
riRequest.setIamInstanceProfile(new IamInstanceProfileSpecification().withName(getIamRole()));

HashSet<Tag> inst_tags = null;
if (tags != null && !tags.isEmpty()) {
@@ -317,7 +316,25 @@ private EC2AbstractSlave provisionOndemand(TaskListener listener) throws AmazonC
logger.println("Looking for existing instances: "+diRequest);

DescribeInstancesResult diResult = ec2.describeInstances(diRequest);
if (diResult.getReservations().size() == 0) {

Instance existingInstance = null;
if (StringUtils.isNotBlank(getIamInstanceProfile())) {
riRequest.setIamInstanceProfile(new IamInstanceProfileSpecification().withArn(getIamInstanceProfile()));
// cannot filter on IAM Instance Profile, so search in result
reservationLoop:
for (Reservation reservation : diResult.getReservations()) {
for (Instance instance : reservation.getInstances()) {
if (instance.getIamInstanceProfile() != null && instance.getIamInstanceProfile().getArn().equals(getIamInstanceProfile())) {
existingInstance = instance;
break reservationLoop;
}
}
}
} else if (diResult.getReservations().size() > 0) {
existingInstance = diResult.getReservations().get(0).getInstances().get(0);
}

if (existingInstance == null) {
// Have to create a new instance
Instance inst = ec2.runInstances(riRequest).getReservation().getInstances().get(0);

@@ -332,28 +349,27 @@ private EC2AbstractSlave provisionOndemand(TaskListener listener) throws AmazonC
return newOndemandSlave(inst);
}

Instance inst = diResult.getReservations().get(0).getInstances().get(0);
logger.println("Found existing stopped instance: "+inst);
logger.println("Found existing stopped instance: "+existingInstance);
List<String> instances = new ArrayList<String>();
instances.add(inst.getInstanceId());
instances.add(existingInstance.getInstanceId());
StartInstancesRequest siRequest = new StartInstancesRequest(instances);
StartInstancesResult siResult = ec2.startInstances(siRequest);
logger.println("Starting existing instance: "+inst+ " result:"+siResult);
logger.println("Starting existing instance: "+existingInstance+ " result:"+siResult);

List<Node> nodes = Hudson.getInstance().getNodes();
for (int i = 0, len = nodes.size(); i < len; i++) {
if (!(nodes.get(i) instanceof EC2AbstractSlave))
continue;
EC2AbstractSlave ec2Node = (EC2AbstractSlave) nodes.get(i);
if (ec2Node.getInstanceId().equals(inst.getInstanceId())) {
if (ec2Node.getInstanceId().equals(existingInstance.getInstanceId())) {
logger.println("Found existing corresponding: "+ec2Node);
return ec2Node;
}
}

// Existing slave not found
logger.println("Creating new slave for existing instance: "+inst);
return newOndemandSlave(inst);
logger.println("Creating new slave for existing instance: "+existingInstance);
return newOndemandSlave(existingInstance);

} catch (FormException e) {
throw new AssertionError(); // we should have discovered all configuration issues upfront
@@ -134,7 +134,7 @@ THE SOFTWARE.
<f:textbox />
</f:entry>

<f:entry title="${%IAM Role}" field="iamRole">
<f:entry title="${%IAM Instance Profile}" field="iamInstanceProfile">
<f:textbox />
</f:entry>
</f:advanced>
@@ -0,0 +1,7 @@
<div>
<p>IAM Instance Profile ARN e.g. arn:aws:iam::000000000000:instance-profile/SampleName.</p>
<p>An instance profile is a container for a role.
To associate a role to an Amazon EC2 instance, you must use the instance profile ARN.
Roles enable you to manage permissions for applications running on EC2.</p>
<p>The Instance Profile ARN can be found in the IAM Role's <b>Summary</b> tab in the AWS Management Console.</p>
</div>

This file was deleted.

@@ -139,7 +139,7 @@ public void testConfigRoundtripIamRole() throws Exception {
tags.add( tag1 );
tags.add( tag2 );

SlaveTemplate orig = new SlaveTemplate(ami, EC2AbstractSlave.TEST_ZONE, null, "default", "foo", "22", InstanceType.M1Large, "ttt", Node.Mode.NORMAL, description, "bar", "aaa", "10", "rrr", "fff", "-Xmx1g", false, "subnet 456", tags, null, false, null, "iamRole");
SlaveTemplate orig = new SlaveTemplate(ami, EC2AbstractSlave.TEST_ZONE, null, "default", "foo", "22", InstanceType.M1Large, "ttt", Node.Mode.NORMAL, description, "bar", "aaa", "10", "rrr", "fff", "-Xmx1g", false, "subnet 456", tags, null, false, null, "iamInstanceProfile");

List<SlaveTemplate> templates = new ArrayList<SlaveTemplate>();
templates.add(orig);
@@ -149,7 +149,7 @@ public void testConfigRoundtripIamRole() throws Exception {

submit(createWebClient().goTo("configure").getFormByName("config"));
SlaveTemplate received = ((EC2Cloud)hudson.clouds.iterator().next()).getTemplate(description);
assertEqualBeans(orig, received, "ami,zone,description,remoteFS,type,jvmopts,stopOnTerminate,securityGroups,subnetId,usePrivateDnsName,iamRole");
assertEqualBeans(orig, received, "ami,zone,description,remoteFS,type,jvmopts,stopOnTerminate,securityGroups,subnetId,usePrivateDnsName,iamInstanceProfile");
}

}

0 comments on commit b5f2eb7

Please sign in to comment.