Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 1 commit
  • 49 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jan 20, 2011
kohsuke moving to GitHub 364f6aa
Showing with 1 addition and 2,420 deletions.
  1. +1 −0 README.TXT
  2. +0 −2 TODO.txt
  3. +0 −58 pom.xml
  4. +0 −67 src/main/java/hudson/plugins/ec2/AmazonEC2Cloud.java
  5. +0 −50 src/main/java/hudson/plugins/ec2/AwsRegion.java
  6. +0 −485 src/main/java/hudson/plugins/ec2/EC2Cloud.java
  7. +0 −108 src/main/java/hudson/plugins/ec2/EC2Computer.java
  8. +0 −61 src/main/java/hudson/plugins/ec2/EC2ComputerLauncher.java
  9. +0 −115 src/main/java/hudson/plugins/ec2/EC2PrivateKey.java
  10. +0 −51 src/main/java/hudson/plugins/ec2/EC2RetentionStrategy.java
  11. +0 −128 src/main/java/hudson/plugins/ec2/EC2Slave.java
  12. +0 −187 src/main/java/hudson/plugins/ec2/Eucalyptus.java
  13. +0 −21 src/main/java/hudson/plugins/ec2/InstanceState.java
  14. +0 −47 src/main/java/hudson/plugins/ec2/PluginImpl.java
  15. +0 −204 src/main/java/hudson/plugins/ec2/SlaveTemplate.java
  16. +0 −26 src/main/java/hudson/plugins/ec2/ebs/ZPoolExpandNotice.java
  17. +0 −65 src/main/java/hudson/plugins/ec2/ebs/ZPoolMonitor.java
  18. +0 −9 src/main/java/hudson/plugins/ec2/ebs/package-info.java
  19. +0 −208 src/main/java/hudson/plugins/ec2/ssh/EC2UnixLauncher.java
  20. +0 −55 src/main/java/hudson/plugins/ec2/ssh/HostKeyVerifierImpl.java
  21. +0 −21 src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/config-entries.jelly
  22. +0 −6 src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/help-region.html
  23. +0 −26 src/main/resources/hudson/plugins/ec2/EC2Cloud/computerSet.jelly
  24. +0 −1 src/main/resources/hudson/plugins/ec2/EC2Cloud/computerSet.properties
  25. +0 −52 src/main/resources/hudson/plugins/ec2/EC2Cloud/config.jelly
  26. +0 −6 src/main/resources/hudson/plugins/ec2/EC2Cloud/help-accessId.html
  27. +0 −10 src/main/resources/hudson/plugins/ec2/EC2Cloud/help-ec2EndpointUrl.html
  28. +0 −15 src/main/resources/hudson/plugins/ec2/EC2Cloud/help-instanceCapStr.html
  29. +0 −1 src/main/resources/hudson/plugins/ec2/EC2Cloud/help-jvmopts.html
  30. +0 −12 src/main/resources/hudson/plugins/ec2/EC2Cloud/help-privateKey.html
  31. +0 −8 src/main/resources/hudson/plugins/ec2/EC2Cloud/help-remoteAdmin.html
  32. +0 −6 src/main/resources/hudson/plugins/ec2/EC2Cloud/help-rootCommandPrefix.html
  33. +0 −10 src/main/resources/hudson/plugins/ec2/EC2Cloud/help-s3EndpointUrl.html
  34. +0 −7 src/main/resources/hudson/plugins/ec2/EC2Cloud/help-userData.html
  35. +0 −78 src/main/resources/hudson/plugins/ec2/EC2Computer/configure.jelly
  36. +0 −4 src/main/resources/hudson/plugins/ec2/EC2Slave/help-initScript.html
  37. +0 −3 src/main/resources/hudson/plugins/ec2/EC2Slave/help-numExecutors.html
  38. +0 −8 src/main/resources/hudson/plugins/ec2/EC2Slave/help-remoteAdmin.html
  39. +0 −6 src/main/resources/hudson/plugins/ec2/EC2Slave/help-rootCommandPrefix.html
  40. +0 −21 src/main/resources/hudson/plugins/ec2/Eucalyptus/config-entries.jelly
  41. +0 −4 src/main/resources/hudson/plugins/ec2/Eucalyptus/help-url.html
  42. +0 −7 src/main/resources/hudson/plugins/ec2/Messages.properties
  43. +0 −40 src/main/resources/hudson/plugins/ec2/ebs/ZPoolExpandNotice/index.jelly
  44. +0 −33 src/main/resources/hudson/plugins/ec2/ebs/ZPoolExpandNotice/message.jelly
  45. +0 −5 src/main/resources/index.jelly
  46. +0 −3 src/main/webapp/help/instanceType.html
  47. +0 −18 src/test/java/hudson/plugins/ec2/AmazonEC2CloudTest.java
  48. +0 −37 src/test/java/hudson/plugins/ec2/EC2PrivateKeyTest.java
  49. +0 −25 src/test/java/hudson/plugins/ec2/SlaveTemplateTest.java
View
1 README.TXT
@@ -0,0 +1 @@
+sources are in git https://github.com/hudson/ec2-plugin
View
2 TODO.txt
@@ -1,2 +0,0 @@
-- the uptime should be displayed there
-- cloud configuration page should be moved elsewhere, like how we configure slaves
View
58 pom.xml
@@ -1,58 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.jvnet.hudson.plugins</groupId>
- <artifactId>plugin</artifactId>
- <version>1.346</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>ec2</artifactId>
- <version>1.11-SNAPSHOT</version>
- <packaging>hpi</packaging>
- <name>Hudson Amazon EC2 plugin</name>
- <url>http://wiki.hudson-ci.org/display/HUDSON/Amazon+EC2+Plugin</url>
-
- <dependencies>
- <dependency>
- <groupId>net.java.dev.jets3t</groupId>
- <artifactId>jets3t</artifactId>
- <version>0.7.2</version>
- <exclusions>
- <!-- they come from core -->
- <exclusion>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- </exclusion>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <!-- we only use this to handle key fingerprint. should be able to replace this with trilead -->
- <groupId>bouncycastle</groupId>
- <artifactId>bcprov-jdk15</artifactId>
- <version>135</version>
- </dependency>
- <dependency>
- <groupId>com.google.code.typica</groupId>
- <artifactId>typica</artifactId>
- <version>1.6</version>
- </dependency>
- </dependencies>
-
- <developers>
- <developer>
- <id>kohsuke</id>
- <name>Kohsuke Kawaguchi</name>
- <email>kohsuke@infradna.com</email>
- </developer>
- </developers>
-
-</project>
-
-
-
View
67 src/main/java/hudson/plugins/ec2/AmazonEC2Cloud.java
@@ -1,67 +0,0 @@
-package hudson.plugins.ec2;
-
-import hudson.Extension;
-import hudson.util.FormValidation;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.QueryParameter;
-import org.kohsuke.stapler.StaplerResponse;
-
-import javax.servlet.ServletException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-
-/**
- * The original implementation of {@link EC2Cloud}.
- *
- * @author Kohsuke Kawaguchi
- */
-public class AmazonEC2Cloud extends EC2Cloud {
- /**
- * Represents the region. Can be null for backward compatibility reasons.
- */
- private AwsRegion region;
-
- @DataBoundConstructor
- public AmazonEC2Cloud(AwsRegion region, String accessId, String secretKey, String privateKey, String instanceCapStr, List<SlaveTemplate> templates) {
- super("ec2-"+region.name(), accessId, secretKey, privateKey, instanceCapStr, templates);
- this.region = region;
- }
-
- public AwsRegion getRegion() {
- if (region==null)
- region = AwsRegion.US_EAST_1; // backward data compatibility with earlier versions
- return region;
- }
-
- @Override
- public URL getEc2EndpointUrl() {
- return getRegion().ec2Endpoint;
- }
-
- @Override
- public URL getS3EndpointUrl() {
- return getRegion().s3Endpoint;
- }
-
- @Extension
- public static class DescriptorImpl extends EC2Cloud.DescriptorImpl {
- public String getDisplayName() {
- return "Amazon EC2";
- }
-
- public FormValidation doTestConnection(
- @QueryParameter AwsRegion region,
- @QueryParameter String accessId,
- @QueryParameter String secretKey,
- @QueryParameter String privateKey) throws IOException, ServletException {
- return super.doTestConnection(region.ec2Endpoint,accessId,secretKey,privateKey);
- }
-
- public FormValidation doGenerateKey(
- StaplerResponse rsp, @QueryParameter AwsRegion region, @QueryParameter String accessId, @QueryParameter String secretKey) throws IOException, ServletException {
- return super.doGenerateKey(rsp,region.ec2Endpoint,accessId,secretKey);
- }
- }
-}
View
50 src/main/java/hudson/plugins/ec2/AwsRegion.java
@@ -1,50 +0,0 @@
-package hudson.plugins.ec2;
-
-import org.jvnet.localizer.Localizable;
-import org.kohsuke.stapler.Stapler;
-
-import hudson.model.Node.Mode;
-import hudson.util.EnumConverter;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Locale;
-
-/**
- * Represents Amazon EC2 regions.
- *
- * @author Kohsuke Kawaguchi
- */
-public enum AwsRegion {
- US_EAST_1(Messages._AwsRegion_UsEast()),
- US_WEST_1(Messages._AwsRegion_UsWest()),
- EU_WEST_1(Messages._AwsRegion_EuWest()),
- AP_SOUTHEAST_1(Messages._AwsRegion_ApSouthEast());
-
- public final URL ec2Endpoint,s3Endpoint;
-
- /**
- * Localized human readable description of this region in a few words.
- */
- public final Localizable displayName;
-
- AwsRegion(Localizable displayName) {
- try {
- String host = name().toLowerCase(Locale.ENGLISH).replace('_','-');
- ec2Endpoint = new URL("https://"+host+".ec2.amazonaws.com/");
- s3Endpoint = new URL("https://"+host+".s3.amazonaws.com/");
- this.displayName = displayName;
- } catch (MalformedURLException e) {
- throw new Error(e); // impossible
- }
- }
-
- @Override
- public String toString() {
- return displayName.toString();
- }
-
- static {
- Stapler.CONVERT_UTILS.register(new EnumConverter(), AwsRegion.class);
- }
-}
View
485 src/main/java/hudson/plugins/ec2/EC2Cloud.java
@@ -1,485 +0,0 @@
-package hudson.plugins.ec2;
-
-import com.xerox.amazonws.ec2.EC2Exception;
-import com.xerox.amazonws.ec2.InstanceType;
-import com.xerox.amazonws.ec2.Jec2;
-import com.xerox.amazonws.ec2.KeyPairInfo;
-import com.xerox.amazonws.ec2.ReservationDescription;
-import com.xerox.amazonws.ec2.ReservationDescription.Instance;
-import hudson.model.Computer;
-import hudson.model.Descriptor;
-import hudson.model.Hudson;
-import hudson.model.Label;
-import hudson.model.Node;
-import hudson.slaves.Cloud;
-import hudson.slaves.NodeProvisioner.PlannedNode;
-import hudson.util.FormValidation;
-import hudson.util.Secret;
-import hudson.util.StreamTaskListener;
-import java.net.MalformedURLException;
-
-import org.jets3t.service.Constants;
-import org.jets3t.service.S3Service;
-import org.jets3t.service.S3ServiceException;
-import org.jets3t.service.impl.rest.httpclient.RestS3Service;
-import org.jets3t.service.security.AWSCredentials;
-import org.jets3t.service.utils.ServiceUtils;
-import org.kohsuke.stapler.QueryParameter;
-import org.kohsuke.stapler.StaplerRequest;
-import org.kohsuke.stapler.StaplerResponse;
-
-import javax.servlet.ServletException;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.logging.Logger;
-
-import org.jets3t.service.Jets3tProperties;
-import static java.util.logging.Level.WARNING;
-
-/**
- * Hudson's view of EC2.
- *
- * @author Kohsuke Kawaguchi
- */
-public abstract class EC2Cloud extends Cloud {
-
- private final String accessId;
- private final Secret secretKey;
- private final EC2PrivateKey privateKey;
-
- /**
- * Upper bound on how many instances we may provision.
- */
- public final int instanceCap;
- private final List<SlaveTemplate> templates;
- private transient KeyPairInfo usableKeyPair;
-
- protected EC2Cloud(String id, String accessId, String secretKey, String privateKey, String instanceCapStr, List<SlaveTemplate> templates) {
- super(id);
- this.accessId = accessId.trim();
- this.secretKey = Secret.fromString(secretKey.trim());
- this.privateKey = new EC2PrivateKey(privateKey);
- if(instanceCapStr.equals(""))
- this.instanceCap = Integer.MAX_VALUE;
- else
- this.instanceCap = Integer.parseInt(instanceCapStr);
- if(templates==null) templates=Collections.emptyList();
- this.templates = templates;
- readResolve(); // set parents
- }
-
- public abstract URL getEc2EndpointUrl() throws IOException;
- public abstract URL getS3EndpointUrl() throws IOException;
-
- protected Object readResolve() {
- for (SlaveTemplate t : templates)
- t.parent = this;
- return this;
- }
-
- public String getAccessId() {
- return accessId;
- }
-
- public String getSecretKey() {
- return secretKey.getEncryptedValue();
- }
-
- public EC2PrivateKey getPrivateKey() {
- return privateKey;
- }
-
- public String getInstanceCapStr() {
- if(instanceCap==Integer.MAX_VALUE)
- return "";
- else
- return String.valueOf(instanceCap);
- }
-
- public List<SlaveTemplate> getTemplates() {
- return Collections.unmodifiableList(templates);
- }
-
- public SlaveTemplate getTemplate(String ami) {
- for (SlaveTemplate t : templates)
- if(t.ami.equals(ami))
- return t;
- return null;
- }
-
- /**
- * Gets {@link SlaveTemplate} that has the matching {@link Label}.
- */
- public SlaveTemplate getTemplate(Label label) {
- for (SlaveTemplate t : templates)
- if(t.containsLabel(label))
- return t;
- return null;
- }
-
- /**
- * Gets the {@link KeyPairInfo} used for the launch.
- */
- public synchronized KeyPairInfo getKeyPair() throws EC2Exception, IOException {
- if(usableKeyPair==null)
- usableKeyPair = privateKey.find(connect());
- return usableKeyPair;
- }
-
- /**
- * Counts the number of instances in EC2 currently running.
- *
- * <p>
- * This includes those instances that may be started outside Hudson.
- */
- public int countCurrentEC2Slaves() throws EC2Exception {
- int n=0;
- for (ReservationDescription r : connect().describeInstances(Collections.<String>emptyList())) {
- for (Instance i : r.getInstances()) {
- if(!i.isTerminated())
- n++;
- }
- }
- return n;
- }
-
- /**
- * Debug command to attach to a running instance.
- */
- public void doAttach(StaplerRequest req, StaplerResponse rsp, @QueryParameter String id) throws ServletException, IOException, EC2Exception {
- checkPermission(PROVISION);
- SlaveTemplate t = getTemplates().get(0);
-
- StringWriter sw = new StringWriter();
- StreamTaskListener listener = new StreamTaskListener(sw);
- EC2Slave node = t.attach(id,listener);
- Hudson.getInstance().addNode(node);
-
- rsp.sendRedirect2(req.getContextPath()+"/computer/"+node.getNodeName());
- }
-
- public void doProvision(StaplerRequest req, StaplerResponse rsp, @QueryParameter String ami) throws ServletException, IOException {
- checkPermission(PROVISION);
- if(ami==null) {
- sendError("The 'ami' query parameter is missing",req,rsp);
- return;
- }
- SlaveTemplate t = getTemplate(ami);
- if(t==null) {
- sendError("No such AMI: "+ami,req,rsp);
- return;
- }
-
- StringWriter sw = new StringWriter();
- StreamTaskListener listener = new StreamTaskListener(sw);
- try {
- EC2Slave node = t.provision(listener);
- Hudson.getInstance().addNode(node);
-
- rsp.sendRedirect2(req.getContextPath()+"/computer/"+node.getNodeName());
- } catch (EC2Exception e) {
- e.printStackTrace(listener.error(e.getMessage()));
- sendError(sw.toString(),req,rsp);
- }
- }
-
- public Collection<PlannedNode> provision(Label label, int excessWorkload) {
- try {
-
- final SlaveTemplate t = getTemplate(label);
-
- List<PlannedNode> r = new ArrayList<PlannedNode>();
- for( ; excessWorkload>0; excessWorkload-- ) {
- if(countCurrentEC2Slaves()>=instanceCap)
- break; // maxed out
-
- r.add(new PlannedNode(t.getDisplayName(),
- Computer.threadPoolForRemoting.submit(new Callable<Node>() {
- public Node call() throws Exception {
- // TODO: record the output somewhere
- EC2Slave s = t.provision(new StreamTaskListener(System.out));
- Hudson.getInstance().addNode(s);
- // EC2 instances may have a long init script. If we declare
- // the provisioning complete by returning without the connect
- // operation, NodeProvisioner may decide that it still wants
- // one more instance, because it sees that (1) all the slaves
- // are offline (because it's still being launched) and
- // (2) there's no capacity provisioned yet.
- //
- // deferring the completion of provisioning until the launch
- // goes successful prevents this problem.
- s.toComputer().connect(false).get();
- return s;
- }
- })
- ,t.getNumExecutors()));
- }
- return r;
- } catch (EC2Exception e) {
- LOGGER.log(WARNING,"Failed to count the # of live instances on EC2",e);
- return Collections.emptyList();
- }
- }
-
- public boolean canProvision(Label label) {
- return getTemplate(label)!=null;
- }
-
- /**
- * Gets the first {@link EC2Cloud} instance configured in the current Hudson, or null if no such thing exists.
- */
- public static EC2Cloud get() {
- return Hudson.getInstance().clouds.get(EC2Cloud.class);
- }
-
- /**
- * Connects to EC2 and returns {@link Jec2}, which can then be used to communicate with EC2.
- */
- public Jec2 connect() throws EC2Exception {
- try {
- return connect(accessId, secretKey, getEc2EndpointUrl());
- } catch (IOException e) {
- throw new EC2Exception("Failed to retrieve the endpoint",e);
- }
- }
-
- /***
- * Connect to an EC2 instance.
- * @return Jec2
- */
- public static Jec2 connect(String accessId, String secretKey, URL endpoint) {
- return connect(accessId, Secret.fromString(secretKey), endpoint);
- }
-
- /***
- * Connect to an EC2 instance.
- * @return Jec2
- */
- public static Jec2 connect(String accessId, Secret secretKey, URL endpoint) {
- int ec2Port = portFromURL(endpoint);
- boolean SSL = isSSL(endpoint);
- Jec2 result = new Jec2(accessId, secretKey.toString(), SSL, endpoint.getHost(), ec2Port);
- String path = endpoint.getPath();
- if (path.length() != 0) /* '/' is the default, not '' */
- result.setResourcePrefix(path);
- return result;
- }
-
- /***
- * Convert a configured hostname like 'us-east-1' to a FQDN or ip address
- */
- public static String convertHostName(String ec2HostName) {
- if (ec2HostName == null || ec2HostName.length()==0)
- ec2HostName = "us-east-1";
- if (!ec2HostName.contains("."))
- ec2HostName = ec2HostName + ".ec2.amazonaws.com";
- return ec2HostName;
- }
-
- /***
- * Convert a configured s3 endpoint to a FQDN or ip address
- */
- public static String convertS3HostName(String s3HostName) {
- if (s3HostName == null || s3HostName.length()==0)
- s3HostName = "s3";
- if (!s3HostName.contains("."))
- s3HostName = s3HostName + ".amazonaws.com";
- return s3HostName;
- }
-
- /***
- * Convert a user entered string into a port number
- * "" -> -1 to indicate default based on SSL setting
- */
- public static Integer convertPort(String ec2Port) {
- if (ec2Port == null || ec2Port.length() == 0)
- return -1;
- else
- return Integer.parseInt(ec2Port);
- }
-
- /**
- * Connects to S3 and returns {@link S3Service}.
- */
- public S3Service connectS3() throws S3ServiceException, IOException {
- URL s3 = getS3EndpointUrl();
-
- return new RestS3Service(new AWSCredentials(accessId,secretKey.toString()),
- null, null, buildJets3tProperties(s3));
- }
-
- /**
- * Builds the connection parameters for S3.
- */
- protected Jets3tProperties buildJets3tProperties(URL s3) {
- Jets3tProperties props = Jets3tProperties.getInstance(Constants.JETS3T_PROPERTIES_FILENAME);
- final String s3Host = s3.getHost();
- if (!s3Host.equals("s3.amazonaws.com"))
- props.setProperty("s3service.s3-endpoint", s3Host);
- int s3Port = portFromURL(s3);
- if (s3Port != -1)
- props.setProperty("s3service.s3-endpoint-http-port", String.valueOf(s3Port));
- if (s3.getPath().length() > 1)
- props.setProperty("s3service.s3-endpoint-virtual-path", s3.getPath());
- props.setProperty("s3service.https-only", String.valueOf(isSSL(s3)));
- return props;
- }
-
- /**
- * Computes the presigned URL for the given S3 resource.
- *
- * @param path
- * String like "/bucketName/folder/folder/abc.txt" that represents the resource to request.
- */
- public URL buildPresignedURL(String path) throws IOException, S3ServiceException {
- long expires = System.currentTimeMillis()/1000+60*60;
- String token = "GET\n\n\n" + expires + "\n" + path;
-
- String url = "http://s3.amazonaws.com"+path+"?AWSAccessKeyId="+accessId+"&Expires="+expires+"&Signature="+
- URLEncoder.encode(
- ServiceUtils.signWithHmacSha1(secretKey.toString(),token),"UTF-8");
- return new URL(url);
- }
-
- /* Parse a url or return a sensible error */
- public static URL checkEndPoint(String url) throws FormValidation {
- try {
- return new URL(url);
- } catch (MalformedURLException ex) {
- throw FormValidation.error("Endpoint URL is not a valid URL");
- }
- }
-
-
- public static abstract class DescriptorImpl extends Descriptor<Cloud> {
- public InstanceType[] getInstanceTypes() {
- return InstanceType.values();
- }
-
- /**
- * TODO: once 1.304 is released, revert to FormValidation.validateBase64
- */
- private FormValidation validateBase64(String value, boolean allowWhitespace, boolean allowEmpty, String errorMessage) {
- try {
- String v = value;
- if(!allowWhitespace) {
- if(v.indexOf(' ')>=0 || v.indexOf('\n')>=0)
- return FormValidation.error(errorMessage);
- }
- v=v.trim();
- if(!allowEmpty && v.length()==0)
- return FormValidation.error(errorMessage);
-
- com.trilead.ssh2.crypto.Base64.decode(v.toCharArray());
- return FormValidation.ok();
- } catch (IOException e) {
- return FormValidation.error(errorMessage);
- }
- }
-
- public FormValidation doCheckAccessId(@QueryParameter String value) throws IOException, ServletException {
- return validateBase64(value,false,false,Messages.EC2Cloud_InvalidAccessId());
- }
-
- public FormValidation doCheckSecretKey(@QueryParameter String value) throws IOException, ServletException {
- return validateBase64(value,false,false,Messages.EC2Cloud_InvalidSecretKey());
- }
-
- public FormValidation doCheckPrivateKey(@QueryParameter String value) throws IOException, ServletException {
- boolean hasStart=false,hasEnd=false;
- BufferedReader br = new BufferedReader(new StringReader(value));
- String line;
- while ((line = br.readLine()) != null) {
- if (line.equals("-----BEGIN RSA PRIVATE KEY-----"))
- hasStart=true;
- if (line.equals("-----END RSA PRIVATE KEY-----"))
- hasEnd=true;
- }
- if(!hasStart)
- return FormValidation.error("This doesn't look like a private key at all");
- if(!hasEnd)
- return FormValidation.error("The private key is missing the trailing 'END RSA PRIVATE KEY' marker. Copy&paste error?");
- return FormValidation.ok();
- }
-
- protected FormValidation doTestConnection( URL ec2endpoint,
- String accessId, String secretKey, String privateKey) throws IOException, ServletException {
- try {
- Jec2 jec2 = connect(accessId, secretKey, ec2endpoint);
- jec2.describeInstances(Collections.<String>emptyList());
-
- if(accessId==null)
- return FormValidation.error("Access ID is not specified");
- if(secretKey==null)
- return FormValidation.error("Secret key is not specified");
- if(privateKey==null)
- return FormValidation.error("Private key is not specified. Click 'Generate Key' to generate one.");
-
- if(privateKey.trim().length()>0) {
- // check if this key exists
- EC2PrivateKey pk = new EC2PrivateKey(privateKey);
- if(pk.find(jec2)==null)
- return FormValidation.error("The private key entered below isn't registered to EC2 (fingerprint is "+pk.getFingerprint()+")");
- }
-
- return FormValidation.ok(Messages.EC2Cloud_Success());
- } catch (EC2Exception e) {
- LOGGER.log(WARNING, "Failed to check EC2 credential",e);
- return FormValidation.error(e.getMessage());
- }
- }
-
- public FormValidation doGenerateKey(StaplerResponse rsp, URL ec2EndpointUrl, String accessId, String secretKey
- ) throws IOException, ServletException {
- try {
- Jec2 jec2 = connect(accessId, secretKey, ec2EndpointUrl);
- List<KeyPairInfo> existingKeys = jec2.describeKeyPairs(Collections.<String>emptyList());
-
- int n = 0;
- while(true) {
- boolean found = false;
- for (KeyPairInfo k : existingKeys) {
- if(k.getKeyName().equals("hudson-"+n))
- found=true;
- }
- if(!found)
- break;
- n++;
- }
-
- KeyPairInfo key = jec2.createKeyPair("hudson-" + n);
-
-
- rsp.addHeader("script","findPreviousFormItem(button,'privateKey').value='"+key.getKeyMaterial().replace("\n","\\n")+"'");
-
- return FormValidation.ok(Messages.EC2Cloud_Success());
- } catch (EC2Exception e) {
- LOGGER.log(WARNING, "Failed to check EC2 credential",e);
- return FormValidation.error(e.getMessage());
- }
- }
- }
-
- private static final Logger LOGGER = Logger.getLogger(EC2Cloud.class.getName());
-
- private static boolean isSSL(URL endpoint) {
- return endpoint.getProtocol().equals("https");
- }
-
- private static int portFromURL(URL endpoint) {
- int ec2Port = endpoint.getPort();
- if (ec2Port == -1) {
- ec2Port = endpoint.getDefaultPort();
- }
- return ec2Port;
- }
-}
View
108 src/main/java/hudson/plugins/ec2/EC2Computer.java
@@ -1,108 +0,0 @@
-package hudson.plugins.ec2;
-
-import com.xerox.amazonws.ec2.EC2Exception;
-import com.xerox.amazonws.ec2.Jec2;
-import com.xerox.amazonws.ec2.ReservationDescription;
-import com.xerox.amazonws.ec2.ReservationDescription.Instance;
-import hudson.Util;
-import hudson.slaves.SlaveComputer;
-import org.kohsuke.stapler.HttpRedirect;
-import org.kohsuke.stapler.HttpResponse;
-import org.kohsuke.stapler.StaplerResponse;
-
-import java.io.IOException;
-import java.util.Collections;
-
-/**
- * @author Kohsuke Kawaguchi
- */
-public class EC2Computer extends SlaveComputer {
- /**
- * Cached description of this EC2 instance. Lazily fetched.
- */
- private volatile Instance ec2InstanceDescription;
-
- public EC2Computer(EC2Slave slave) {
- super(slave);
- }
-
- @Override
- public EC2Slave getNode() {
- return (EC2Slave)super.getNode();
- }
-
- public String getInstanceId() {
- return getName();
- }
-
- /**
- * Gets the EC2 console output.
- */
- public String getConsoleOutput() throws EC2Exception {
- Jec2 ec2 = EC2Cloud.get().connect();
- return ec2.getConsoleOutput(getInstanceId()).getOutput();
- }
-
- /**
- * Obtains the instance state description in EC2.
- *
- * <p>
- * This method returns a cached state, so it's not suitable to check {@link Instance#getState()}
- * and {@link Instance#getStateCode()} from the returned instance (but all the other fields are valid as it won't change.)
- */
- public Instance describeInstance() throws EC2Exception {
- if(ec2InstanceDescription==null)
- ec2InstanceDescription = _describeInstance();
- return ec2InstanceDescription;
- }
-
- /**
- * Gets the current state of the instance.
- *
- * <p>
- * Unlike {@link #describeInstance()}, this method always return the current status by calling EC2.
- */
- public InstanceState getState() throws EC2Exception {
- ec2InstanceDescription=_describeInstance();
- return InstanceState.find(ec2InstanceDescription.getState());
- }
-
- /**
- * Number of milli-secs since the instance was started.
- */
- public long getUptime() throws EC2Exception {
- return System.currentTimeMillis()-describeInstance().getLaunchTime().getTimeInMillis();
- }
-
- /**
- * Returns uptime in the human readable form.
- */
- public String getUptimeString() throws EC2Exception {
- return Util.getTimeSpanString(getUptime());
- }
-
- private ReservationDescription.Instance _describeInstance() throws EC2Exception {
- return EC2Cloud.get().connect().describeInstances(Collections.<String>singletonList(getNode().getInstanceId())).get(0).getInstances().get(0);
- }
-
- /**
- * When the slave is deleted, terminate the instance.
- */
- @Override
- public HttpResponse doDoDelete() throws IOException {
- checkPermission(DELETE);
- getNode().terminate();
- return new HttpRedirect("..");
- }
-
- /** What username to use to run root-like commands
- *
- */
- public String getRemoteAdmin() {
- return getNode().getRemoteAdmin();
- }
-
- public String getRootCommandPrefix() {
- return getNode().getRootCommandPrefix();
- }
-}
View
61 src/main/java/hudson/plugins/ec2/EC2ComputerLauncher.java
@@ -1,61 +0,0 @@
-package hudson.plugins.ec2;
-
-import com.xerox.amazonws.ec2.EC2Exception;
-import com.xerox.amazonws.ec2.ReservationDescription.Instance;
-import hudson.model.TaskListener;
-import hudson.slaves.ComputerLauncher;
-import hudson.slaves.SlaveComputer;
-
-import java.io.IOException;
-import java.io.PrintStream;
-
-import org.jets3t.service.S3ServiceException;
-
-/**
- * {@link ComputerLauncher} for EC2 that waits for the instance to really come up before proceeding to
- * the real user-specified {@link ComputerLauncher}.
- *
- * @author Kohsuke Kawaguchi
- */
-public abstract class EC2ComputerLauncher extends ComputerLauncher {
- @Override
- public void launch(SlaveComputer _computer, TaskListener listener) {
- try {
- EC2Computer computer = (EC2Computer)_computer;
- PrintStream logger = listener.getLogger();
-
- OUTER:
- while(true) {
- switch (computer.getState()) {
- case PENDING:
- Thread.sleep(5000); // check every 5 secs
- continue OUTER;
- case RUNNING:
- break OUTER;
- case SHUTTING_DOWN:
- case TERMINATED:
- // abort
- logger.println("The instance "+computer.getInstanceId()+" appears to be shut down. Aborting launch.");
- return;
- }
- }
-
- launch(computer, logger, computer.describeInstance());
- } catch (EC2Exception e) {
- e.printStackTrace(listener.error(e.getMessage()));
- } catch (IOException e) {
- e.printStackTrace(listener.error(e.getMessage()));
- } catch (InterruptedException e) {
- e.printStackTrace(listener.error(e.getMessage()));
- } catch (S3ServiceException e) {
- e.printStackTrace(listener.error(e.getMessage()));
- }
-
- }
-
- /**
- * Stage 2 of the launch. Called after the EC2 instance comes up.
- */
- protected abstract void launch(EC2Computer computer, PrintStream logger, Instance inst)
- throws EC2Exception, IOException, InterruptedException, S3ServiceException;
-}
View
115 src/main/java/hudson/plugins/ec2/EC2PrivateKey.java
@@ -1,115 +0,0 @@
-package hudson.plugins.ec2;
-
-import hudson.util.Secret;
-import org.apache.commons.codec.binary.Hex;
-import org.bouncycastle.openssl.PEMReader;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.security.DigestInputStream;
-import java.security.KeyPair;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.Security;
-
-import com.xerox.amazonws.ec2.KeyPairInfo;
-import com.xerox.amazonws.ec2.Jec2;
-import com.xerox.amazonws.ec2.EC2Exception;
-
-/**
- * RSA private key (the one that you generate with ec2-add-keypair.)
- *
- * Starts with "----- BEGIN RSA PRIVATE KEY------\n".
- *
- * @author Kohsuke Kawaguchi
- */
-final class EC2PrivateKey {
- private final Secret privateKey;
-
- EC2PrivateKey(String privateKey) {
- this.privateKey = Secret.fromString(privateKey.trim());
- }
-
- /**
- * Obtains the fingerprint of the key in the "ab:cd:ef:...:12" format.
- */
- /**
- * Obtains the fingerprint of the key in the "ab:cd:ef:...:12" format.
- */
- public String getFingerprint() throws IOException {
- Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
- Reader r = new BufferedReader(new StringReader(privateKey.toString()));
- PEMReader pem = new PEMReader(r);
- KeyPair pair = (KeyPair) pem.readObject();
- if(pair==null) return null;
- PrivateKey key = pair.getPrivate();
- return digest(key);
- }
-
- /**
- * Is this file really a private key?
- */
- public boolean isPrivateKey() throws IOException {
- BufferedReader br = new BufferedReader(new StringReader(privateKey.toString()));
- String line;
- while ((line = br.readLine()) != null) {
- if (line.equals("-----BEGIN RSA PRIVATE KEY-----"))
- return true;
- }
- return false;
- }
-
- /**
- * Finds the {@link KeyPairInfo} that corresponds to this key in EC2.
- */
- public KeyPairInfo find(Jec2 ec2) throws IOException, EC2Exception {
- String fp = getFingerprint();
- for(KeyPairInfo kp : ec2.describeKeyPairs(new String[0])) {
- if(kp.getKeyFingerprint().equalsIgnoreCase(fp))
- return new KeyPairInfo(kp.getKeyName(),fp,privateKey.toString());
- }
- return null;
- }
-
- @Override
- public int hashCode() {
- return privateKey.hashCode();
- }
-
- @Override
- public boolean equals(Object that) {
- return that instanceof EC2PrivateKey && this.privateKey.equals(((EC2PrivateKey)that).privateKey);
- }
-
- @Override
- public String toString() {
- return privateKey.toString();
- }
-
- /*package*/ static String digest(PrivateKey k) throws IOException {
- try {
- MessageDigest md5 = MessageDigest.getInstance("SHA1");
-
- DigestInputStream in = new DigestInputStream(new ByteArrayInputStream(k.getEncoded()), md5);
- try {
- while (in.read(new byte[128]) > 0)
- ; // simply discard the input
- } finally {
- in.close();
- }
- StringBuilder buf = new StringBuilder();
- char[] hex = Hex.encodeHex(md5.digest());
- for( int i=0; i<hex.length; i+=2 ) {
- if(buf.length()>0) buf.append(':');
- buf.append(hex,i,2);
- }
- return buf.toString();
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- }
- }
-}
View
51 src/main/java/hudson/plugins/ec2/EC2RetentionStrategy.java
@@ -1,51 +0,0 @@
-package hudson.plugins.ec2;
-
-import hudson.model.Descriptor;
-import hudson.slaves.RetentionStrategy;
-import hudson.util.TimeUnit2;
-import org.kohsuke.stapler.DataBoundConstructor;
-
-import java.util.logging.Logger;
-
-/**
- * {@link RetentionStrategy} for EC2.
- *
- * @author Kohsuke Kawaguchi
- */
-public class EC2RetentionStrategy extends RetentionStrategy<EC2Computer> {
- @DataBoundConstructor
- public EC2RetentionStrategy() {
- }
-
- public synchronized long check(EC2Computer c) {
- if (c.isIdle() && !disabled) {
- // TODO: really think about the right strategy here
- final long idleMilliseconds = System.currentTimeMillis() - c.getIdleStartMilliseconds();
- if (idleMilliseconds > TimeUnit2.MINUTES.toMillis(30)) {
- LOGGER.info("Disconnecting "+c.getName());
- c.getNode().terminate();
- }
- }
- return 1;
- }
-
- /**
- * Try to connect to it ASAP.
- */
- @Override
- public void start(EC2Computer c) {
- c.connect(false);
- }
-
- // no registration since this retention strategy is used only for EC2 nodes that we provision automatically.
- // @Extension
- public static class DescriptorImpl extends Descriptor<RetentionStrategy<?>> {
- public String getDisplayName() {
- return "EC2";
- }
- }
-
- private static final Logger LOGGER = Logger.getLogger(EC2RetentionStrategy.class.getName());
-
- public static boolean disabled = Boolean.getBoolean(EC2RetentionStrategy.class.getName()+".disabled");
-}
View
128 src/main/java/hudson/plugins/ec2/EC2Slave.java
@@ -1,128 +0,0 @@
-package hudson.plugins.ec2;
-
-import com.xerox.amazonws.ec2.EC2Exception;
-import com.xerox.amazonws.ec2.InstanceType;
-import com.xerox.amazonws.ec2.Jec2;
-import hudson.model.Computer;
-import hudson.model.Descriptor.FormException;
-import hudson.model.Hudson;
-import hudson.model.Slave;
-import hudson.plugins.ec2.ssh.EC2UnixLauncher;
-import hudson.slaves.NodeProperty;
-import hudson.Extension;
-import hudson.Util;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.kohsuke.stapler.DataBoundConstructor;
-
-/**
- * Slave running on EC2.
- *
- * @author Kohsuke Kawaguchi
- */
-public final class EC2Slave extends Slave {
- /**
- * Comes from {@link SlaveTemplate#initScript}.
- */
- public final String initScript;
- public final String remoteAdmin; // e.g. 'ubuntu'
- public final String rootCommandPrefix; // e.g. 'sudo'
- public final String jvmopts; //e.g. -Xmx1g
-
- public EC2Slave(String instanceId, String description, String remoteFS, int numExecutors, String labelString, String initScript, String remoteAdmin, String rootCommandPrefix, String jvmopts) throws FormException, IOException {
- this(instanceId, description, remoteFS, numExecutors, Mode.NORMAL, labelString, initScript, Collections.<NodeProperty<?>>emptyList(), remoteAdmin, rootCommandPrefix, jvmopts);
- }
-
- @DataBoundConstructor
- public EC2Slave(String instanceId, String description, String remoteFS, int numExecutors, Mode mode, String labelString, String initScript, List<? extends NodeProperty<?>> nodeProperties, String remoteAdmin, String rootCommandPrefix, String jvmopts) throws FormException, IOException {
- super(instanceId, description, remoteFS, numExecutors, mode, labelString, new EC2UnixLauncher(), new EC2RetentionStrategy(), nodeProperties);
- this.initScript = initScript;
- this.remoteAdmin = remoteAdmin;
- this.rootCommandPrefix = rootCommandPrefix;
- this.jvmopts = jvmopts;
- }
-
- /**
- * Constructor for debugging.
- */
- public EC2Slave(String instanceId) throws FormException, IOException {
- this(instanceId,"debug","/tmp/hudson",1, Mode.NORMAL, "debug", "", Collections.<NodeProperty<?>>emptyList(), null, null, null);
- }
-
- /**
- * See http://aws.amazon.com/ec2/instance-types/
- */
- /*package*/ static int toNumExecutors(InstanceType it) {
- switch (it) {
- case DEFAULT: return 1;
- case MEDIUM_HCPU: return 5;
- case LARGE: return 4;
- case XLARGE: return 8;
- case XLARGE_HCPU: return 20;
- default: throw new AssertionError();
- }
- }
-
- /**
- * EC2 instance ID.
- */
- public String getInstanceId() {
- return getNodeName();
- }
-
- @Override
- public Computer createComputer() {
- return new EC2Computer(this);
- }
-
- /**
- * Terminates the instance in EC2.
- */
- public void terminate() {
- try {
- Jec2 ec2 = EC2Cloud.get().connect();
- ec2.terminateInstances(Collections.singletonList(getInstanceId()));
- LOGGER.info("Terminated EC2 instance: "+getInstanceId());
- Hudson.getInstance().removeNode(this);
- } catch (EC2Exception e) {
- LOGGER.log(Level.WARNING,"Failed to terminate EC2 instance: "+getInstanceId(),e);
- } catch (IOException e) {
- LOGGER.log(Level.WARNING,"Failed to terminate EC2 instance: "+getInstanceId(),e);
- }
- }
-
- String getRemoteAdmin() {
- if (remoteAdmin == null || remoteAdmin.length() == 0)
- return "root";
- return remoteAdmin;
- }
-
- String getRootCommandPrefix() {
- if (rootCommandPrefix == null || rootCommandPrefix.length() == 0)
- return "";
- return rootCommandPrefix + " ";
- }
-
- String getJvmopts() {
- return Util.fixNull(jvmopts);
- }
-
- @Extension
- public static final class DescriptorImpl extends SlaveDescriptor {
- public String getDisplayName() {
- return "Amazon EC2";
- }
-
- @Override
- public boolean isInstantiable() {
- return false;
- }
- }
-
- private static final Logger LOGGER = Logger.getLogger(EC2Slave.class.getName());
-}
View
187 src/main/java/hudson/plugins/ec2/Eucalyptus.java
@@ -1,187 +0,0 @@
-package hudson.plugins.ec2;
-
-import hudson.Extension;
-import hudson.util.FormValidation;
-import hudson.util.IOException2;
-import org.dom4j.Document;
-import org.dom4j.DocumentException;
-import org.dom4j.Element;
-import org.dom4j.io.SAXReader;
-import org.jets3t.service.Jets3tProperties;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.QueryParameter;
-import org.kohsuke.stapler.StaplerResponse;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-import javax.servlet.ServletException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.GeneralSecurityException;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.X509Certificate;
-import java.util.List;
-
-/**
- * Eucalyptus.
- *
- * @author Kohsuke Kawaguchi
- */
-public class Eucalyptus extends EC2Cloud {
- private transient Metadata metadata;
-
- public final URL url;
-
- @DataBoundConstructor
- public Eucalyptus(URL url, String accessId, String secretKey, String privateKey, String instanceCapStr, List<SlaveTemplate> templates) throws IOException {
- super("eucalyptus", accessId, secretKey, privateKey, instanceCapStr, templates);
- this.url = url;
- }
-
- private Metadata getMetadata() throws IOException {
- if (metadata==null)
- metadata = new Metadata(url);
- return metadata;
- }
-
- @Override
- public URL getEc2EndpointUrl() throws IOException {
- return getMetadata().ec2endpoint;
- }
-
- @Override
- public URL getS3EndpointUrl() throws IOException {
- return getMetadata().s3endpoint;
- }
-
- @Override
- protected Jets3tProperties buildJets3tProperties(URL s3) {
- Jets3tProperties props = super.buildJets3tProperties(s3);
-
- /* For eucalyptus as of 1.6.0 */
- props.setProperty("s3service.disable-dns-buckets", "true");
-
- return props;
- }
-
- @Extension
- public static class DescriptorImpl extends EC2Cloud.DescriptorImpl {
- public String getDisplayName() {
- return "Eucalyptus";
- }
-
- public FormValidation doTestConnection(
- @QueryParameter URL url,
- @QueryParameter String accessId,
- @QueryParameter String secretKey,
- @QueryParameter String privateKey) throws IOException, ServletException {
- return super.doTestConnection(new Metadata(url).ec2endpoint,accessId,secretKey,privateKey);
- }
-
- public FormValidation doGenerateKey(
- StaplerResponse rsp, @QueryParameter URL url, @QueryParameter String accessId, @QueryParameter String secretKey) throws IOException, ServletException {
- return super.doGenerateKey(rsp, new Metadata(url).ec2endpoint, accessId,secretKey);
- }
- }
-
- /**
- * Eucalyptus service endpoint metadata.
- */
- static class Metadata {
- final URL ec2endpoint,s3endpoint;
-
- Metadata(URL eucalyptus) throws IOException {
- if (!eucalyptus.getProtocol().equals("https"))
- throw new IOException("Expecting an HTTPS URL but got "+eucalyptus);
- URL metadataUrl = new URL(eucalyptus, "/register");
- try {
- HttpsURLConnection con = (HttpsURLConnection)metadataUrl.openConnection();
- makeIgnoreCertificate(con);
- Document metadata = new SAXReader().read(con.getInputStream());
- /*
- Metadata, as of Eucalyptus 1.5.2, looks like this:
-
- <Signature>
- <SignedInfo>
- <SignatureMethod>http://www.w3.org/2001/04/xmldsig-more#hmac-sha256</SignatureMethod>
- </SignedInfo>
- <SignatureValue>62595777525d7dbba4b5f361b3e9041d3d37e92611684557e67e85a9222a3ffb </SignatureValue>
- <Object>
- <CloudSchema>
- <Services type="array">
- <Service>
- <Name>ec2</Name>
- <EndpointUrl>http://eucalyptus.hudson-slaves.sfbay.sun.com:8773/services/Eucalyptus</EndpointUrl>
- <Resources type="array">
- ...
- </Resources>
- </Service>
- <Service>
- <Name>s3</Name>
- <EndpointUrl>http://eucalyptus.hudson-slaves.sfbay.sun.com:8773/services/Walrus</EndpointUrl>
- <Resources type="array">
- ...
- </Resources>
- </Service>
- </Services>
- <id>a002c56e-b994-4ed8-956b-b30eda9b6153</id> <CloudType>eucalyptus</CloudType>
- <CloudVersion>1.5.2</CloudVersion>
- <SchemaVersion>1.0</SchemaVersion>
- <Description>Public cloud in the new cluster</Description>
- </CloudSchema>
-
- */
-
- this.ec2endpoint = readURLFromMetadata(metadata, "ec2");
- this.s3endpoint = readURLFromMetadata(metadata, "s3");
- } catch (DocumentException e) {
- throw new IOException2("Failed to parse Eucalyptus metadata at "+metadataUrl,e);
- } catch (IOException e) {
- throw new IOException2("Failed to parse Eucalyptus metadata at "+metadataUrl,e);
- } catch (GeneralSecurityException e) {
- throw new IOException2("Failed to parse Eucalyptus metadata at "+metadataUrl,e);
- }
- }
-
- /**
- * Configures the given {@link HttpsURLConnection} so that it'll ignore all the HTTPS certificate checks,
- * as typical Eucalyptus implementation doesn't come with a valid certificate.
- */
- private void makeIgnoreCertificate(HttpsURLConnection con) throws NoSuchAlgorithmException, KeyManagementException {
- SSLContext sc = SSLContext.getInstance("SSL");
- TrustManager[] tma = {new X509TrustManager() {
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
-
- public void checkClientTrusted(X509Certificate[] certs, String authType) {
- }
-
- public void checkServerTrusted(X509Certificate[] certs, String authType) {
- }
- }};
- sc.init(null, tma, null);
-
- con.setSSLSocketFactory(sc.getSocketFactory());
- con.setHostnameVerifier(new HostnameVerifier() {
- public boolean verify(String s, SSLSession sslSession) {
- return true; // everything goes
- }
- });
- }
-
- private URL readURLFromMetadata(Document metadata, String serviceName) throws MalformedURLException {
- Element e = (Element)metadata.selectSingleNode("//Service[Name/text()='" + serviceName + "']/EndpointUrl");
- if (e==null)
- throw new IllegalStateException("Service metadata didn't contain "+serviceName);
- return new URL(e.getTextTrim());
- }
- }
-}
View
21 src/main/java/hudson/plugins/ec2/InstanceState.java
@@ -1,21 +0,0 @@
-package hudson.plugins.ec2;
-
-/**
- * Constants that represent the running state of EC2.
- *
- * @author Kohsuke Kawaguchi
- */
-public enum InstanceState {
- PENDING,
- RUNNING,
- SHUTTING_DOWN,
- TERMINATED;
-
- public String getCode() {
- return name().toLowerCase().replace('_','-');
- }
-
- public static InstanceState find(String name) {
- return Enum.valueOf(InstanceState.class,name.toUpperCase().replace('-','_'));
- }
-}
View
47 src/main/java/hudson/plugins/ec2/PluginImpl.java
@@ -1,47 +0,0 @@
-package hudson.plugins.ec2;
-
-import hudson.Extension;
-import hudson.Plugin;
-import hudson.model.Describable;
-import hudson.model.Descriptor;
-import hudson.model.Descriptor.FormException;
-import hudson.model.Hudson;
-import hudson.model.Items;
-import hudson.util.FormValidation;
-import hudson.util.Secret;
-import net.sf.json.JSONObject;
-import org.kohsuke.stapler.QueryParameter;
-import org.kohsuke.stapler.StaplerRequest;
-
-import javax.servlet.ServletException;
-import java.io.IOException;
-
-/**
- * Added to handle backwards compatibility of xstream class name mapping.
- */
-@Extension
-public class PluginImpl extends Plugin implements Describable<PluginImpl> {
- @Override
- public void start() throws Exception {
- // backward compatibility with the legacy class name
- Hudson.XSTREAM.alias("hudson.plugins.ec2.EC2Cloud",AmazonEC2Cloud.class);
-
- load();
- }
-
- public DescriptorImpl getDescriptor() {
- return (DescriptorImpl)Hudson.getInstance().getDescriptorOrDie(getClass());
- }
-
- public static PluginImpl get() {
- return Hudson.getInstance().getPlugin(PluginImpl.class);
- }
-
- @Extension
- public static final class DescriptorImpl extends Descriptor<PluginImpl> {
- @Override
- public String getDisplayName() {
- return "EC2 PluginImpl";
- }
- }
-}
View
204 src/main/java/hudson/plugins/ec2/SlaveTemplate.java
@@ -1,204 +0,0 @@
-package hudson.plugins.ec2;
-
-import com.xerox.amazonws.ec2.EC2Exception;
-import com.xerox.amazonws.ec2.ImageDescription;
-import com.xerox.amazonws.ec2.InstanceType;
-import com.xerox.amazonws.ec2.Jec2;
-import com.xerox.amazonws.ec2.KeyPairInfo;
-import com.xerox.amazonws.ec2.ReservationDescription.Instance;
-import hudson.model.Describable;
-import hudson.model.Descriptor;
-import hudson.model.Descriptor.FormException;
-import hudson.model.Hudson;
-import hudson.model.TaskListener;
-import hudson.model.Label;
-import hudson.model.Node;
-import hudson.Extension;
-import hudson.Util;
-import hudson.util.FormValidation;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.QueryParameter;
-
-import javax.servlet.ServletException;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Template of {@link EC2Slave} to launch.
- *
- * @author Kohsuke Kawaguchi
- */
-public class SlaveTemplate implements Describable<SlaveTemplate> {
- public final String ami;
- public final String description;
- public final String remoteFS;
- public final InstanceType type;
- public final String labels;
- public final String initScript;
- public final String userData;
- public final String numExecutors;
- public final String remoteAdmin;
- public final String rootCommandPrefix;
- public final String jvmopts;
- protected transient EC2Cloud parent;
-
- private transient /*almost final*/ Set<Label> labelSet;
-
- @DataBoundConstructor
- public SlaveTemplate(String ami, String remoteFS, InstanceType type, String labelString, String description, String initScript, String userData, String numExecutors, String remoteAdmin, String rootCommandPrefix, String jvmopts) {
- this.ami = ami;
- this.remoteFS = remoteFS;
- this.type = type;
- this.labels = Util.fixNull(labelString);
- this.description = description;
- this.initScript = initScript;
- this.userData = userData;
- this.numExecutors = Util.fixNull(numExecutors).trim();
- this.remoteAdmin = remoteAdmin;
- this.rootCommandPrefix = rootCommandPrefix;
- this.jvmopts = jvmopts;
- readResolve(); // initialize
- }
-
- public EC2Cloud getParent() {
- return parent;
- }
-
- public String getLabelString() {
- return labels;
- }
-
- public String getDisplayName() {
- return description+" ("+ami+")";
- }
-
- public int getNumExecutors() {
- try {
- return Integer.parseInt(numExecutors);
- } catch (NumberFormatException e) {
- return EC2Slave.toNumExecutors(type);
- }
- }
-
- public String getRemoteAdmin() {
- return remoteAdmin;
- }
-
- public String getRootCommandPrefix() {
- return rootCommandPrefix;
- }
-
- /**
- * Does this contain the given label?
- *
- * @param l
- * can be null to indicate "don't care".
- */
- public boolean containsLabel(Label l) {
- return l==null || labelSet.contains(l);
- }
-
- /**
- * Provisions a new EC2 slave.
- *
- * @return always non-null. This needs to be then added to {@link Hudson#addNode(Node)}.
- */
- public EC2Slave provision(TaskListener listener) throws EC2Exception, IOException {
- PrintStream logger = listener.getLogger();
- Jec2 ec2 = getParent().connect();
-
- try {
- logger.println("Launching "+ami);
- KeyPairInfo keyPair = parent.getPrivateKey().find(ec2);
- if(keyPair==null)
- throw new EC2Exception("No matching keypair found on EC2. Is the EC2 private key a valid one?");
- Instance inst = ec2.runInstances(ami, 1, 1, Collections.<String>emptyList(), userData, keyPair.getKeyName(), type).getInstances().get(0);
- return newSlave(inst);
- } catch (FormException e) {
- throw new AssertionError(); // we should have discovered all configuration issues upfront
- }
- }
-
- private EC2Slave newSlave(Instance inst) throws FormException, IOException {
- return new EC2Slave(inst.getInstanceId(), description, remoteFS, getNumExecutors(), labels, initScript, remoteAdmin, rootCommandPrefix, jvmopts);
- }
-
- /**
- * Provisions a new EC2 slave based on the currently running instance on EC2,
- * instead of starting a new one.
- */
- public EC2Slave attach(String instanceId, TaskListener listener) throws EC2Exception, IOException {
- PrintStream logger = listener.getLogger();
- Jec2 ec2 = getParent().connect();
-
- try {
- logger.println("Attaching to "+instanceId);
- Instance inst = ec2.describeInstances(Collections.singletonList(instanceId)).get(0).getInstances().get(0);
- return newSlave(inst);
- } catch (FormException e) {
- throw new AssertionError(); // we should have discovered all configuration issues upfront
- }
- }
-
- /**
- * Initializes data structure that we don't persist.
- */
- protected Object readResolve() {
- labelSet = Label.parse(labels);
- return this;
- }
-
- public Descriptor<SlaveTemplate> getDescriptor() {
- return Hudson.getInstance().getDescriptor(getClass());
- }
-
- @Extension
- public static final class DescriptorImpl extends Descriptor<SlaveTemplate> {
- public String getDisplayName() {
- return null;
- }
-
- /**
- * Since this shares much of the configuration with {@link EC2Computer}, check its help page, too.
- */
- @Override
- public String getHelpFile(String fieldName) {
- String p = super.getHelpFile(fieldName);
- if (p==null) p = Hudson.getInstance().getDescriptor(EC2Slave.class).getHelpFile(fieldName);
- return p;
- }
-
- /***
- * Check that the AMI requested is available in the cloud and can be used.
- */
- public FormValidation doValidateAmi(
- @QueryParameter String accessId, @QueryParameter String secretKey,
- @QueryParameter String ec2EndpointUrl,
- final @QueryParameter String ami) throws IOException, ServletException {
- Jec2 jec2 = EC2Cloud.connect(accessId, secretKey, EC2Cloud.checkEndPoint(ec2EndpointUrl));
- if(jec2!=null) {
- try {
- List<String> images = new LinkedList<String>();
- images.add(ami);
- List<String> owners = new LinkedList<String>();
- List<String> users = new LinkedList<String>();
- users.add("self"); // if we can't run it its not useful.
- List<ImageDescription> img = jec2.describeImages(
- images, owners, users, null);
- if(img==null || img.isEmpty())
- // de-registered AMI causes an empty list to be returned. so be defensive
- // against other possibilities
- return FormValidation.error("No such AMI, or not usable with this accessId: "+ami);
- return FormValidation.ok(img.get(0).getImageLocation()+" by "+img.get(0).getImageOwnerId());
- } catch (EC2Exception e) {
- return FormValidation.error(e.getMessage());
- }
- } else
- return FormValidation.ok(); // can't test
- }
- }
-}
View
26 src/main/java/hudson/plugins/ec2/ebs/ZPoolExpandNotice.java
@@ -1,26 +0,0 @@
-package hudson.plugins.ec2.ebs;
-
-import hudson.model.AdministrativeMonitor;
-import hudson.Extension;
-
-/**
- * {@link AdministrativeMonitor} that tells the user that ZFS pool is filling up
- * and they need to add more storage.
- *
- * @author Kohsuke Kawaguchi
- */
-@Extension
-public class ZPoolExpandNotice extends AdministrativeMonitor {
- /**
- * Set by {@link ZPoolMonitor}.
- */
- /*package*/ boolean activated = false;
-
- public ZPoolExpandNotice() {
- super("zpool.ebs");
- }
-
- public boolean isActivated() {
- return activated;
- }
-}
View
65 src/main/java/hudson/plugins/ec2/ebs/ZPoolMonitor.java
@@ -1,65 +0,0 @@
-package hudson.plugins.ec2.ebs;
-
-import hudson.model.PeriodicWork;
-import hudson.model.Hudson;
-import hudson.model.AdministrativeMonitor;
-import hudson.triggers.Trigger;
-import hudson.util.TimeUnit2;
-import hudson.Extension;
-import org.jvnet.solaris.libzfs.LibZFS;
-import org.jvnet.solaris.libzfs.ZFSFileSystem;
-import org.jvnet.solaris.libzfs.ZFSPool;
-
-import java.net.URL;
-import java.io.IOException;
-
-/**
- * Once an hour, check if the main zpool is that hosts $HUDSON_HOME has still enough free space.
- *
- * @author Kohsuke Kawaguchi
- */
-@Extension
-public class ZPoolMonitor extends PeriodicWork {
- public long getRecurrencePeriod() {
- return TimeUnit2.HOURS.toMillis(1);
- }
-
- protected void doRun() {
- ZFSFileSystem fs=null;
- try {
- if(isInsideEC2())
- fs = new LibZFS().getFileSystemByMountPoint(Hudson.getInstance().getRootDir());
- } catch (LinkageError e) {
- // probably not running on OpenSolaris
- }
- if(fs==null) {
- cancel();
- return;
- }
- ZFSPool pool = fs.getPool();
- long a = pool.getAvailableSize();
- long t = pool.getSize();
-
- // if the disk is 90% filled up and the available space is less than 1GB,
- // notify the user
- ZPoolExpandNotice zen = AdministrativeMonitor.all().get(ZPoolExpandNotice.class);
- zen.activated = t/a>10 && a<1000L*1000*1000;
- }
-
- private static Boolean isInsideEC2;
-
- /**
- * Returns true if this JVM runs inside EC2.
- */
- public static synchronized boolean isInsideEC2() {
- if(isInsideEC2==null) {
- try {
- new URL("http://169.254.169.254/latest").openStream().close();
- isInsideEC2 = true;
- } catch (IOException e) {
- isInsideEC2 = false;
- }
- }
- return isInsideEC2;
- }
-}
View
9 src/main/java/hudson/plugins/ec2/ebs/package-info.java
@@ -1,9 +0,0 @@
-/**
- * Code that deals with HUDSON_HOME on EBS, which is used in
- * conjunction with our EC2 launch wizard.
- *
- * <p>
- * This should eventually move to its own plugin, but for
- * now I'm putting this here.
- */
-package hudson.plugins.ec2.ebs;
View
208 src/main/java/hudson/plugins/ec2/ssh/EC2UnixLauncher.java