Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
/target
/work
/bin
.idea
*.iml
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>3.43</version>
<version>4.15</version>
<relativePath />
</parent>

<groupId>dev.lsegal.jenkins</groupId>
<artifactId>codebuilder-cloud</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.0.6-SNAPSHOT</version>
<packaging>hpi</packaging>
<name>CodeBuilder: AWS CodeBuild Cloud Agents</name>
<description>Dynamically provisions cloud agents using AWS CodeBuild</description>
<url>https://wiki.jenkins.io/display/JENKINS/CodeBuilder%3A+AWS+CodeBuild+Cloud+Agents+Plugin</url>

<properties>
<jenkins.version>1.651.3</jenkins.version>
<jenkins.version>2.270</jenkins.version>
<java.level>8</java.level>
</properties>

Expand Down
80 changes: 68 additions & 12 deletions src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;

/**
Expand Down Expand Up @@ -117,7 +127,7 @@ public CodeBuilderCloud(String name, @Nonnull String projectName, @Nullable Stri
*/
@Nonnull
protected static Jenkins jenkins() {
return Jenkins.getActiveInstance();
return Jenkins.get();
}

/**
Expand Down Expand Up @@ -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 <code>jenkinsUrl</code>.
*
Expand Down Expand Up @@ -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 <code>agentTimeout</code>.
*
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -375,7 +419,7 @@ public synchronized Collection<PlannedNode> provision(Label label, int excessWor
final String displayName = String.format("%s.cb-%s", projectName, suffix);
final CodeBuilderCloud cloud = this;
final Future<Node> 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;
Expand Down Expand Up @@ -412,6 +456,8 @@ private static String getDefaultRegion() {
}
}



@Extension
public static class DescriptorImpl extends Descriptor<Cloud> {
@Override
Expand All @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;

Expand All @@ -18,6 +22,7 @@
import hudson.slaves.SlaveComputer;
import hudson.util.StreamTaskListener;


/**
* CodeBuilderLauncher class.
*
Expand All @@ -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} */
Expand Down Expand Up @@ -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<String> command = new ArrayList<String>(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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@
</f:entry>

<f:advanced>

<f:entry field="webSocket" title="${%Use WebSocket}">
<f:checkbox/>
</f:entry>

<f:entry field="tunnel" title="${%Tunnel URL}">
<f:textbox />
</f:entry>

<f:entry field="jenkinsUrl" title="${%Alternative Jenkins URL}">
<f:textbox />
</f:entry>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}