Skip to content
Permalink
Browse files
Merge pull request #48 from rsennewald/jenkins-15081
Fix to allow multiple EC2Clouds (fix for JENKINS-15081)
  • Loading branch information
francisu committed Apr 30, 2013
2 parents 881b2b8 + bcc00db commit 5da8f6be66e839e33923cbf5e8b62b0f6c4b7bfc
Showing 7 changed files with 41 additions and 43 deletions.
@@ -75,6 +75,7 @@ public abstract class EC2AbstractSlave extends Slave {
public final String idleTerminationMinutes;
public final boolean usePrivateDnsName;
public List<EC2Tag> tags;
public EC2Cloud cloud;

// Temporary stuff that is obtained live from EC2
public String publicDNS;
@@ -99,7 +100,7 @@ public abstract class EC2AbstractSlave extends Slave {


@DataBoundConstructor
public EC2AbstractSlave(String name, String instanceId, String description, String remoteFS, int sshPort, int numExecutors, Mode mode, String labelString, ComputerLauncher launcher, RetentionStrategy<EC2Computer> retentionStrategy, String initScript, List<? extends NodeProperty<?>> nodeProperties, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String idleTerminationMinutes, List<EC2Tag> tags, boolean usePrivateDnsName) throws FormException, IOException {
public EC2AbstractSlave(String name, String instanceId, String description, String remoteFS, int sshPort, int numExecutors, Mode mode, String labelString, ComputerLauncher launcher, RetentionStrategy<EC2Computer> retentionStrategy, String initScript, List<? extends NodeProperty<?>> nodeProperties, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String idleTerminationMinutes, List<EC2Tag> tags, EC2Cloud cloud, boolean usePrivateDnsName) throws FormException, IOException {

super(name, "", remoteFS, numExecutors, mode, labelString, launcher, retentionStrategy, nodeProperties);

@@ -112,6 +113,7 @@ public EC2AbstractSlave(String name, String instanceId, String description, Stri
this.stopOnTerminate = stopOnTerminate;
this.idleTerminationMinutes = idleTerminationMinutes;
this.tags = tags;
this.cloud = cloud;
this.usePrivateDnsName = usePrivateDnsName;
}

@@ -164,13 +166,12 @@ public Computer createComputer() {
return new EC2Computer(this);
}

public static Instance getInstance(String instanceId) {
public static Instance getInstance(String instanceId, EC2Cloud cloud) {
DescribeInstancesRequest request = new DescribeInstancesRequest();
request.setInstanceIds(Collections.<String>singletonList(instanceId));
EC2Cloud cloudInstance = EC2Cloud.get();
if (cloudInstance == null)
if (cloud == null)
return null;
AmazonEC2 ec2 = cloudInstance.connect();
AmazonEC2 ec2 = cloud.connect();
List<Reservation> reservations = ec2.describeInstances(request).getReservations();
Instance i = null;
if (reservations.size() > 0) {
@@ -188,21 +189,21 @@ public static Instance getInstance(String instanceId) {

void stop() {
try {
AmazonEC2 ec2 = EC2Cloud.get().connect();
AmazonEC2 ec2 = cloud.connect();
StopInstancesRequest request = new StopInstancesRequest(
Collections.singletonList(getInstanceId()));
ec2.stopInstances(request);
LOGGER.info("EC2 instance stopped: " + getInstanceId());
toComputer().disconnect(null);
} catch (AmazonClientException e) {
Instance i = getInstance(getInstanceId());
Instance i = getInstance(getInstanceId(), cloud);
LOGGER.log(Level.WARNING, "Failed to terminate EC2 instance: "+getInstanceId() + " info: "+((i != null)?i:"") , e);
}
}

boolean terminateInstance() {
try {
AmazonEC2 ec2 = EC2Cloud.get().connect();
AmazonEC2 ec2 = cloud.connect();
TerminateInstancesRequest request = new TerminateInstancesRequest(Collections.singletonList(getInstanceId()));
ec2.terminateInstances(request);
LOGGER.info("Terminated EC2 instance (terminated): "+getInstanceId());
@@ -280,7 +281,7 @@ protected void fetchLiveInstanceData( boolean force ) throws AmazonClientExcepti
return;
}

Instance i = getInstance(getInstanceId());
Instance i = getInstance(getInstanceId(), cloud);

lastFetchTime = now;
lastFetchInstance = i;
@@ -298,7 +299,7 @@ protected void fetchLiveInstanceData( boolean force ) throws AmazonClientExcepti

/* Clears all existing tag data so that we can force the instance into a known state */
protected void clearLiveInstancedata() throws AmazonClientException {
Instance inst = getInstance(getInstanceId());
Instance inst = getInstance(getInstanceId(), cloud);

/* Now that we have our instance, we can clear the tags on it */
if (!tags.isEmpty()) {
@@ -310,14 +311,14 @@ protected void clearLiveInstancedata() throws AmazonClientException {

DeleteTagsRequest tag_request = new DeleteTagsRequest();
tag_request.withResources(inst.getInstanceId()).setTags(inst_tags);
EC2Cloud.get().connect().deleteTags(tag_request);
cloud.connect().deleteTags(tag_request);
}
}


/* Sets tags on an instance. This will not clear existing tag data, so call clearLiveInstancedata if needed */
protected void pushLiveInstancedata() throws AmazonClientException {
Instance inst = getInstance(getInstanceId());
Instance inst = getInstance(getInstanceId(), cloud);

/* Now that we have our instance, we can set tags on it */
if (tags != null && !tags.isEmpty()) {
@@ -329,7 +330,7 @@ protected void pushLiveInstancedata() throws AmazonClientException {

CreateTagsRequest tag_request = new CreateTagsRequest();
tag_request.withResources(inst.getInstanceId()).setTags(inst_tags);
EC2Cloud.get().connect().createTags(tag_request);
cloud.connect().createTags(tag_request);
}
}

@@ -70,12 +70,17 @@ public String getSpotInstanceRequestId(){
}
return "";
}

public EC2Cloud getCloud() {
EC2AbstractSlave node = (EC2AbstractSlave) super.getNode();
return node.cloud;
}

/**
* Gets the EC2 console output.
*/
public String getConsoleOutput() throws AmazonClientException {
AmazonEC2 ec2 = EC2Cloud.get().connect();
AmazonEC2 ec2 = getCloud().connect();
GetConsoleOutputRequest request = new GetConsoleOutputRequest(getInstanceId());
return ec2.getConsoleOutput(request).getOutput();
}
@@ -150,7 +155,7 @@ private Instance _describeInstance() throws AmazonClientException, InterruptedEx
private Instance _describeInstanceOnce() throws AmazonClientException {
DescribeInstancesRequest request = new DescribeInstancesRequest();
request.setInstanceIds(Collections.<String>singletonList(getNode().getInstanceId()));
return EC2Cloud.get().connect().describeInstances(request).getReservations().get(0).getInstances().get(0);
return getCloud().connect().describeInstances(request).getReservations().get(0).getInstances().get(0);
}

/**
@@ -61,7 +61,7 @@ public void launch(SlaveComputer _computer, TaskListener listener) {
case RUNNING:
break OUTER;
case STOPPED:
AmazonEC2 ec2 = EC2Cloud.get().connect();
AmazonEC2 ec2 = computer.getCloud().connect();
List<String> instances = new ArrayList<String>();
instances.add(computer.getInstanceId());

@@ -33,18 +33,18 @@
*/
public final class EC2OndemandSlave extends EC2AbstractSlave {

public EC2OndemandSlave(String instanceId, String description, String remoteFS, int sshPort, int numExecutors, String labelString, Mode mode, String initScript, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String idleTerminationMinutes, String publicDNS, String privateDNS, List<EC2Tag> tags) throws FormException, IOException {
this(instanceId, description, remoteFS, sshPort, numExecutors, labelString, Mode.NORMAL, initScript, Collections.<NodeProperty<?>>emptyList(), remoteAdmin, rootCommandPrefix, jvmopts, stopOnTerminate, idleTerminationMinutes, publicDNS, privateDNS, tags, false);
public EC2OndemandSlave(String instanceId, String description, String remoteFS, int sshPort, int numExecutors, String labelString, Mode mode, String initScript, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String idleTerminationMinutes, String publicDNS, String privateDNS, List<EC2Tag> tags, EC2Cloud cloud) throws FormException, IOException {
this(instanceId, description, remoteFS, sshPort, numExecutors, labelString, Mode.NORMAL, initScript, Collections.<NodeProperty<?>>emptyList(), remoteAdmin, rootCommandPrefix, jvmopts, stopOnTerminate, idleTerminationMinutes, publicDNS, privateDNS, tags, cloud, false);
}

public EC2OndemandSlave(String instanceId, String description, String remoteFS, int sshPort, int numExecutors, String labelString, Mode mode, String initScript, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String idleTerminationMinutes, String publicDNS, String privateDNS, List<EC2Tag> tags, boolean usePrivateDnsName) throws FormException, IOException {
this(instanceId, description, remoteFS, sshPort, numExecutors, labelString, Mode.NORMAL, initScript, Collections.<NodeProperty<?>>emptyList(), remoteAdmin, rootCommandPrefix, jvmopts, stopOnTerminate, idleTerminationMinutes, publicDNS, privateDNS, tags, usePrivateDnsName);
public EC2OndemandSlave(String instanceId, String description, String remoteFS, int sshPort, int numExecutors, String labelString, Mode mode, String initScript, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String idleTerminationMinutes, String publicDNS, String privateDNS, List<EC2Tag> tags, EC2Cloud cloud, boolean usePrivateDnsName) throws FormException, IOException {
this(instanceId, description, remoteFS, sshPort, numExecutors, labelString, Mode.NORMAL, initScript, Collections.<NodeProperty<?>>emptyList(), remoteAdmin, rootCommandPrefix, jvmopts, stopOnTerminate, idleTerminationMinutes, publicDNS, privateDNS, tags, cloud, usePrivateDnsName);
}

@DataBoundConstructor
public EC2OndemandSlave(String instanceId, String description, String remoteFS, int sshPort, int numExecutors, String labelString, Mode mode, String initScript, List<? extends NodeProperty<?>> nodeProperties, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String idleTerminationMinutes, String publicDNS, String privateDNS, List<EC2Tag> tags, boolean usePrivateDnsName) throws FormException, IOException {
public EC2OndemandSlave(String instanceId, String description, String remoteFS, int sshPort, int numExecutors, String labelString, Mode mode, String initScript, List<? extends NodeProperty<?>> nodeProperties, String remoteAdmin, String rootCommandPrefix, String jvmopts, boolean stopOnTerminate, String idleTerminationMinutes, String publicDNS, String privateDNS, List<EC2Tag> tags, EC2Cloud cloud, boolean usePrivateDnsName) throws FormException, IOException {

super(description + " (" + instanceId + ")", instanceId, description, remoteFS, sshPort, numExecutors, mode, labelString, new EC2UnixLauncher(), new EC2RetentionStrategy(idleTerminationMinutes), initScript, nodeProperties, remoteAdmin, rootCommandPrefix, jvmopts, false, idleTerminationMinutes, tags, usePrivateDnsName);
super(description + " (" + instanceId + ")", instanceId, description, remoteFS, sshPort, numExecutors, mode, labelString, new EC2UnixLauncher(), new EC2RetentionStrategy(idleTerminationMinutes), initScript, nodeProperties, remoteAdmin, rootCommandPrefix, jvmopts, false, idleTerminationMinutes, tags, cloud, usePrivateDnsName);

this.publicDNS = publicDNS;
this.privateDNS = privateDNS;
@@ -54,7 +54,7 @@ public EC2OndemandSlave(String instanceId, String description, String remoteFS,
* Constructor for debugging.
*/
public EC2OndemandSlave(String instanceId) throws FormException, IOException {
this(instanceId,"debug", "/tmp/hudson", 22, 1, "debug", Mode.NORMAL, "", Collections.<NodeProperty<?>>emptyList(), null, null, null, false, null, "Fake public", "Fake private", null, false);
this(instanceId,"debug", "/tmp/hudson", 22, 1, "debug", Mode.NORMAL, "", Collections.<NodeProperty<?>>emptyList(), null, null, null, false, null, "Fake public", "Fake private", null, null, false);
}


@@ -67,7 +67,7 @@ public void terminate() {
/* The node has been killed externally, so we've nothing to do here */
LOGGER.info("EC2 instance already terminated: "+getInstanceId());
} else {
AmazonEC2 ec2 = EC2Cloud.get().connect();
AmazonEC2 ec2 = cloud.connect();
TerminateInstancesRequest request = new TerminateInstancesRequest(Collections.singletonList(getInstanceId()));
ec2.terminateInstances(request);
LOGGER.info("Terminated EC2 instance (terminated): "+getInstanceId());
@@ -30,14 +30,14 @@ public final class EC2SpotSlave extends EC2AbstractSlave {

private final String spotInstanceRequestId;

public EC2SpotSlave(String name, String spotInstanceRequestId, String description, String remoteFS, int sshPort, int numExecutors, Mode mode, String initScript, String labelString, String remoteAdmin, String rootCommandPrefix, String jvmopts, String idleTerminationMinutes, List<EC2Tag> tags, boolean usePrivateDnsName) throws FormException, IOException {
this(name, spotInstanceRequestId, description, remoteFS, sshPort, numExecutors, mode, initScript, labelString, Collections.<NodeProperty<?>>emptyList(), remoteAdmin, rootCommandPrefix, jvmopts, idleTerminationMinutes, tags, usePrivateDnsName);
public EC2SpotSlave(String name, String spotInstanceRequestId, String description, String remoteFS, int sshPort, int numExecutors, Mode mode, String initScript, String labelString, String remoteAdmin, String rootCommandPrefix, String jvmopts, String idleTerminationMinutes, List<EC2Tag> tags, EC2Cloud cloud, boolean usePrivateDnsName) throws FormException, IOException {
this(name, spotInstanceRequestId, description, remoteFS, sshPort, numExecutors, mode, initScript, labelString, Collections.<NodeProperty<?>>emptyList(), remoteAdmin, rootCommandPrefix, jvmopts, idleTerminationMinutes, tags, cloud, usePrivateDnsName);
}

@DataBoundConstructor
public EC2SpotSlave(String name, String spotInstanceRequestId, String description, String remoteFS, int sshPort, int numExecutors, Mode mode, String initScript, String labelString, List<? extends NodeProperty<?>> nodeProperties, String remoteAdmin, String rootCommandPrefix, String jvmopts, String idleTerminationMinutes, List<EC2Tag> tags, boolean usePrivateDnsName) throws FormException, IOException {
public EC2SpotSlave(String name, String spotInstanceRequestId, String description, String remoteFS, int sshPort, int numExecutors, Mode mode, String initScript, String labelString, List<? extends NodeProperty<?>> nodeProperties, String remoteAdmin, String rootCommandPrefix, String jvmopts, String idleTerminationMinutes, List<EC2Tag> tags, EC2Cloud cloud, boolean usePrivateDnsName) throws FormException, IOException {

super(name, "", description, remoteFS, sshPort, numExecutors, mode, labelString, new EC2SpotComputerLauncher(), new EC2SpotRetentionStrategy(idleTerminationMinutes), initScript, nodeProperties, remoteAdmin, rootCommandPrefix, jvmopts, false, idleTerminationMinutes, tags, usePrivateDnsName);
super(name, "", description, remoteFS, sshPort, numExecutors, mode, labelString, new EC2SpotComputerLauncher(), new EC2SpotRetentionStrategy(idleTerminationMinutes), initScript, nodeProperties, remoteAdmin, rootCommandPrefix, jvmopts, false, idleTerminationMinutes, tags, cloud, usePrivateDnsName);

this.name = name;
this.spotInstanceRequestId = spotInstanceRequestId;
@@ -52,8 +52,7 @@ public EC2SpotSlave(String name, String spotInstanceRequestId, String descriptio
@Override
public void terminate() {
// Cancel the spot request
AmazonEC2 ec2 = getEc2Cloud();
if (ec2 == null) return;
AmazonEC2 ec2 = cloud.connect();

String instanceId = getInstanceId();
List<String> requestIds = Collections.singletonList(spotInstanceRequestId);
@@ -88,20 +87,13 @@ public void terminate() {

}

private AmazonEC2 getEc2Cloud(){
EC2Cloud cloudInstance = EC2Cloud.get();
if (cloudInstance == null) return null;
return cloudInstance.connect();
}

/**
* Retrieve the SpotRequest for a requestId
* @param requestId
* @return SpotInstanceRequest object for the requestId, or null
*/
private SpotInstanceRequest getSpotRequest(String spotRequestId){
AmazonEC2 ec2 = getEc2Cloud();
if(ec2 == null) return null;
AmazonEC2 ec2 = cloud.connect();

DescribeSpotInstanceRequestsRequest dsirRequest = new DescribeSpotInstanceRequestsRequest().withSpotInstanceRequestIds(spotRequestId);
DescribeSpotInstanceRequestsResult dsirResult = ec2.describeSpotInstanceRequests(dsirRequest);
@@ -455,11 +455,11 @@ private EC2AbstractSlave provisionSpot(TaskListener listener) throws AmazonClien
}

private EC2OndemandSlave newOndemandSlave(Instance inst) throws FormException, IOException {
return new EC2OndemandSlave(inst.getInstanceId(), description, remoteFS, getSshPort(), getNumExecutors(), labels, mode, initScript, remoteAdmin, rootCommandPrefix, jvmopts, stopOnTerminate, idleTerminationMinutes, inst.getPublicDnsName(), inst.getPrivateDnsName(), EC2Tag.fromAmazonTags(inst.getTags()), usePrivateDnsName);
return new EC2OndemandSlave(inst.getInstanceId(), description, remoteFS, getSshPort(), getNumExecutors(), labels, mode, initScript, remoteAdmin, rootCommandPrefix, jvmopts, stopOnTerminate, idleTerminationMinutes, inst.getPublicDnsName(), inst.getPrivateDnsName(), EC2Tag.fromAmazonTags(inst.getTags()), parent, usePrivateDnsName);
}

private EC2SpotSlave newSpotSlave(SpotInstanceRequest sir, String name) throws FormException, IOException {
return new EC2SpotSlave(name, sir.getSpotInstanceRequestId(), description, remoteFS, getSshPort(), getNumExecutors(), mode, initScript, labels, remoteAdmin, rootCommandPrefix, jvmopts, idleTerminationMinutes, EC2Tag.fromAmazonTags(sir.getTags()), usePrivateDnsName);
return new EC2SpotSlave(name, sir.getSpotInstanceRequestId(), description, remoteFS, getSshPort(), getNumExecutors(), mode, initScript, labels, remoteAdmin, rootCommandPrefix, jvmopts, idleTerminationMinutes, EC2Tag.fromAmazonTags(sir.getTags()), parent, usePrivateDnsName);
}

/**

0 comments on commit 5da8f6b

Please sign in to comment.