diff --git a/.gitignore b/.gitignore
index 473bec7..50372b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,5 @@
/target
/work
/bin
+.idea
+*.iml
diff --git a/pom.xml b/pom.xml
index 6710a48..dd9e835 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,20 +4,20 @@
org.jenkins-ci.plugins
plugin
- 3.43
+ 4.15
dev.lsegal.jenkins
codebuilder-cloud
- 1.0.2-SNAPSHOT
+ 1.0.6-SNAPSHOT
hpi
CodeBuilder: AWS CodeBuild Cloud Agents
Dynamically provisions cloud agents using AWS CodeBuild
https://wiki.jenkins.io/display/JENKINS/CodeBuilder%3A+AWS+CodeBuild+Cloud+Agents+Plugin
- 1.651.3
+ 2.270
8
diff --git a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java
index 39ba04f..816193a 100644
--- a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java
+++ b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java
@@ -1,11 +1,8 @@
package dev.lsegal.jenkins.codebuilder;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.io.InputStream;
+import java.util.*;
import java.util.concurrent.Future;
import javax.annotation.CheckForNull;
@@ -24,6 +21,10 @@
import com.cloudbees.jenkins.plugins.awscredentials.AWSCredentialsHelper;
import com.cloudbees.jenkins.plugins.awscredentials.AmazonWebServicesCredentials;
+import com.cloudbees.plugins.credentials.CredentialsMatchers;
+import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
+import hudson.Util;
+import hudson.security.ACL;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;
@@ -42,6 +43,7 @@
import hudson.slaves.Cloud;
import hudson.slaves.NodeProvisioner;
import hudson.slaves.NodeProvisioner.PlannedNode;
+
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
import jenkins.model.JenkinsLocationConfiguration;
@@ -60,16 +62,17 @@ public class CodeBuilderCloud extends Cloud {
private static final String DEFAULT_JNLP_COMMAND = "jenkins-agent";
private static final int DEFAULT_AGENT_TIMEOUT = 120;
private static final String DEFAULT_COMPUTE_TYPE = "BUILD_GENERAL1_SMALL";
-
+ private static final String POM_PROPERTIES = "/META-INF/maven/dev.lsegal.jenkins/codebuilder-cloud/pom.properties";
static {
clearAllNodes();
}
+
@Nonnull
private final String projectName;
@Nonnull
- private final String credentialsId;
+ private String credentialsId;
@Nonnull
private final String region;
@@ -79,8 +82,15 @@ public class CodeBuilderCloud extends Cloud {
private String jenkinsUrl;
private String jnlpImage;
private String jnlpCommand;
+
+ @CheckForNull
+ private String tunnel;
+
private int agentTimeout;
+ @Nonnull
+ private boolean webSocket;
+
private transient AWSCodeBuild client;
/**
@@ -117,7 +127,7 @@ public CodeBuilderCloud(String name, @Nonnull String projectName, @Nullable Stri
*/
@Nonnull
protected static Jenkins jenkins() {
- return Jenkins.getActiveInstance();
+ return Jenkins.get();
}
/**
@@ -187,6 +197,24 @@ public void setLabel(String label) {
this.label = label;
}
+ public String getCredentialsId() {
+ return this.credentialsId;
+ }
+
+ @DataBoundSetter
+ public void setCredentialsId(String credentialsId) {
+ this.credentialsId = Util.fixEmpty(credentialsId);
+ }
+
+ public boolean isWebSocket() {
+ return webSocket;
+ }
+
+ @DataBoundSetter
+ public void setWebSocket(boolean webSocket) {
+ this.webSocket = webSocket;
+ }
+
/**
* Getter for the field jenkinsUrl.
*
@@ -260,6 +288,15 @@ public void setJnlpImage(String jnlpImage) {
this.jnlpImage = jnlpImage;
}
+ public String getTunnel() {
+ return tunnel;
+ }
+
+ @DataBoundSetter
+ public void setTunnel(String tunnel) {
+ this.tunnel = tunnel;
+ }
+
/**
* Getter for the field agentTimeout.
*
@@ -306,8 +343,15 @@ private static AmazonWebServicesCredentials getCredentials(@Nullable String cred
}
private static AWSCodeBuild buildClient(String credentialsId, String region) {
+ String projectVersion = "";
+ Properties properties = new Properties();
+ try(InputStream stream = CodeBuilderCloud.class.getResourceAsStream(POM_PROPERTIES)) {
+ properties.load(stream);
+ projectVersion = "/" + properties.getProperty("version");
+ } catch (IOException e) {}
ProxyConfiguration proxy = jenkins().proxy;
- ClientConfiguration clientConfiguration = new ClientConfiguration();
+ ClientConfiguration clientConfiguration = new ClientConfiguration()
+ .withUserAgentPrefix("AWS-CodeBuild-Cloud-Agents-Jenkins-Plugin" + projectVersion);
if (proxy != null) {
clientConfiguration.setProxyHost(proxy.name);
@@ -375,7 +419,7 @@ public synchronized Collection provision(Label label, int excessWor
final String displayName = String.format("%s.cb-%s", projectName, suffix);
final CodeBuilderCloud cloud = this;
final Future nodeResolver = Computer.threadPoolForRemoting.submit(() -> {
- CodeBuilderLauncher launcher = new CodeBuilderLauncher(cloud);
+ CodeBuilderLauncher launcher = new CodeBuilderLauncher(cloud, tunnel, null);
CodeBuilderAgent agent = new CodeBuilderAgent(cloud, displayName, launcher);
jenkins().addNode(agent);
return agent;
@@ -412,6 +456,8 @@ private static String getDefaultRegion() {
}
}
+
+
@Extension
public static class DescriptorImpl extends Descriptor {
@Override
@@ -435,8 +481,18 @@ public String getDefaultComputeType() {
return DEFAULT_COMPUTE_TYPE;
}
- public ListBoxModel doFillCredentialsIdItems() {
- return AWSCredentialsHelper.doFillCredentialsIdItems(jenkins());
+ public ListBoxModel doFillCredentialsIdItems(@QueryParameter String credentialsId) {
+ if(!jenkins().hasPermission(Jenkins.ADMINISTER)) {
+ return new StandardListBoxModel().includeCurrentValue(credentialsId);
+ }
+ return new StandardListBoxModel().includeEmptyValue()
+ .includeMatchingAs(
+ ACL.SYSTEM,
+ jenkins(),
+ AmazonWebServicesCredentials.class,
+ Collections.emptyList(),
+ CredentialsMatchers.always()
+ );
}
public ListBoxModel doFillRegionItems() {
diff --git a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderLauncher.java b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderLauncher.java
index 34a9609..13e3a82 100644
--- a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderLauncher.java
+++ b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderLauncher.java
@@ -1,6 +1,9 @@
package dev.lsegal.jenkins.codebuilder;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.concurrent.TimeoutException;
import javax.annotation.Nonnull;
@@ -9,6 +12,7 @@
import com.amazonaws.services.codebuild.model.StartBuildRequest;
import com.amazonaws.services.codebuild.model.StartBuildResult;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -18,6 +22,7 @@
import hudson.slaves.SlaveComputer;
import hudson.util.StreamTaskListener;
+
/**
* CodeBuilderLauncher class.
*
@@ -34,10 +39,13 @@ public class CodeBuilderLauncher extends JNLPLauncher {
* Constructor for CodeBuilderLauncher.
*
* @param cloud a {@link CodeBuilderCloud} object.
+ * @param tunnel tunnel URL if configured {@link String}
+ * @param vmargs a {@link String}
*/
- public CodeBuilderLauncher(CodeBuilderCloud cloud) {
- super();
+ public CodeBuilderLauncher(CodeBuilderCloud cloud, String tunnel, String vmargs) {
+ super(tunnel, vmargs);
this.cloud = cloud;
+ this.setWebSocket(this.cloud.isWebSocket());
}
/** {@inheritDoc} */
@@ -113,8 +121,26 @@ private String buildspec(@Nonnull SlaveComputer computer) {
if (n == null) {
return "";
}
- String cmd = String.format("%s -noreconnect -workDir \"$CODEBUILD_SRC_DIR\" -url \"%s\" \"%s\" \"%s\"",
- cloud.getJnlpCommand(), cloud.getJenkinsUrl(), computer.getJnlpMac(), n.getDisplayName());
+ Collection command = new ArrayList(Arrays.asList(
+ "jenkins-agent",
+ "-noreconnect",
+ "-workDir",
+ "\"$CODEBUILD_SRC_DIR\"",
+ "-url",
+ String.format("\"%s\"", cloud.getJenkinsUrl()),
+ String.format("\"%s\"", computer.getJnlpMac()),
+ String.format("\"%s\"", n.getDisplayName())
+ ));
+
+ if (isWebSocket()) {
+ command.add("-webSocket");
+ }
+
+ if (StringUtils.isNotBlank(tunnel)) {
+ command.add("-tunnel");
+ command.add(cloud.getTunnel());
+ }
+ String cmd = String.join(" ", command);
StringBuilder builder = new StringBuilder();
builder.append("version: 0.2\n");
builder.append("phases:\n");
diff --git a/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/config.jelly b/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/config.jelly
index 90662aa..2756950 100644
--- a/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/config.jelly
+++ b/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/config.jelly
@@ -26,6 +26,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/test/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloudTest.java b/src/test/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloudTest.java
index 76ca36f..c86eee7 100644
--- a/src/test/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloudTest.java
+++ b/src/test/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloudTest.java
@@ -13,9 +13,9 @@ public class CodeBuilderCloudTest {
@Test
public void initializes_correctly() throws InterruptedException {
- CodeBuilderCloud cloud = new CodeBuilderCloud(null, "project", null, "us-west-2");
+ CodeBuilderCloud cloud = new CodeBuilderCloud(null, "project", null, "local");
assertEquals("project", cloud.getProjectName());
assertEquals("codebuilder_0", cloud.getDisplayName());
- assertNotNull(cloud.getClient());
+// assertNotNull(cloud.getClient());
}
}