From 8403b7d39ef46599247e74d6d61911cf03cce957 Mon Sep 17 00:00:00 2001 From: Alejandro Vallecilla Date: Mon, 10 Feb 2020 14:34:43 +0100 Subject: [PATCH 1/5] Adds configuration parameter to the cloud object so the codebuild agent can be kept alive the same amount of time as Agent Connection Timeout specifies. This will allow people to have warm agents --- .../jenkins/codebuilder/CodeBuilderCloud.java | 13 +++++++++++++ .../jenkins/codebuilder/CodeBuilderComputer.java | 8 ++++++-- .../codebuilder/CodeBuilderCloud/config.jelly | 4 ++++ .../CodeBuilderCloud/help-agentTimeout.html | 4 +++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java index e65ed56..c98e621 100644 --- a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java +++ b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java @@ -78,6 +78,7 @@ public class CodeBuilderCloud extends Cloud { private String jenkinsUrl; private String jnlpImage; private int agentTimeout; + private boolean terminateAgent; private transient AWSCodeBuild client; @@ -389,6 +390,14 @@ private static String getDefaultRegion() { } } + public boolean isTerminateAgent() { + return terminateAgent; + } + + public void setTerminateAgent(boolean terminateAgent) { + this.terminateAgent = terminateAgent; + } + @Extension public static class DescriptorImpl extends Descriptor { @Override @@ -408,6 +417,10 @@ public String getDefaultComputeType() { return DEFAULT_COMPUTE_TYPE; } + public boolean getDefaultTerminateAgent() { + return DEFAULT_TERMINATE_AGENT; + } + public ListBoxModel doFillCredentialsIdItems() { return AWSCredentialsHelper.doFillCredentialsIdItems(jenkins()); } diff --git a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderComputer.java b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderComputer.java index b28c0bd..3045e08 100644 --- a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderComputer.java +++ b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderComputer.java @@ -77,7 +77,9 @@ public void taskAccepted(Executor executor, Queue.Task task) { public void taskCompleted(Executor executor, Queue.Task task, long durationMS) { super.taskCompleted(executor, task, durationMS); LOGGER.info("[CodeBuilder]: [{}]: Task in job '{}' completed in {}ms", this, task.getFullDisplayName(), durationMS); - gracefulShutdown(); + if (cloud.isTerminateAgent()) { + gracefulShutdown(); + } } /** {@inheritDoc} */ @@ -86,7 +88,9 @@ public void taskCompletedWithProblems(Executor executor, Queue.Task task, long d super.taskCompletedWithProblems(executor, task, durationMS, problems); LOGGER.error("[CodeBuilder]: [{}]: Task in job '{}' completed with problems in {}ms", this, task.getFullDisplayName(), durationMS, problems); - gracefulShutdown(); + if (cloud.isTerminateAgent()) { + gracefulShutdown(); + } } /** {@inheritDoc} */ 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 d7625dd..cde60a5 100644 --- a/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/config.jelly +++ b/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/config.jelly @@ -37,5 +37,9 @@ + + + + diff --git a/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/help-agentTimeout.html b/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/help-agentTimeout.html index 8bd2483..17ccda0 100644 --- a/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/help-agentTimeout.html +++ b/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/help-agentTimeout.html @@ -1,4 +1,6 @@

The time in seconds to wait before giving up on an agent connection. Default - value is 120 seconds. + value is 120 seconds. If you are using a load balancer its idle connection timeout + should be the same. + Maximum value is the same as configured in the codebuild project.

\ No newline at end of file From 4b4347f819debe447018113e99b10cfebaa8c59a Mon Sep 17 00:00:00 2001 From: Alejandro Vallecilla Date: Mon, 10 Feb 2020 14:39:45 +0100 Subject: [PATCH 2/5] Adds html helper for new field --- .../dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java | 1 + .../codebuilder/CodeBuilderCloud/help-terminateAgent.html | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/help-terminateAgent.html diff --git a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java index c98e621..831a3b5 100644 --- a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java +++ b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java @@ -59,6 +59,7 @@ public class CodeBuilderCloud extends Cloud { private static final String DEFAULT_JNLP_IMAGE = "lsegal/jnlp-docker-agent:alpine"; private static final int DEFAULT_AGENT_TIMEOUT = 120; private static final String DEFAULT_COMPUTE_TYPE = "BUILD_GENERAL1_SMALL"; + private static final boolean DEFAULT_TERMINATE_AGENT = true; static { clearAllNodes(); diff --git a/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/help-terminateAgent.html b/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/help-terminateAgent.html new file mode 100644 index 0000000..d942778 --- /dev/null +++ b/src/main/resources/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud/help-terminateAgent.html @@ -0,0 +1,7 @@ +

Determines whether to terminate the codebuild Agent after the task is finished.

+

+ After a task is finished default behavior is to terminate the codebuild agent + right after the build is finished. By disabling this option the codebuild agent + will run for the amount of time specified by the Agent Connection Timeout. Each new build + will extend the Agent runtime for the Agent Connection Timeout value. +

From 449913d18f7946d45b34d8cd60161bf877e996b8 Mon Sep 17 00:00:00 2001 From: Alejandro Vallecilla Date: Mon, 10 Feb 2020 15:05:59 +0100 Subject: [PATCH 3/5] Adds region to unit test --- .../dev/lsegal/jenkins/codebuilder/CodeBuilderCloudTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloudTest.java b/src/test/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloudTest.java index 2717834..f366262 100644 --- a/src/test/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloudTest.java +++ b/src/test/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloudTest.java @@ -13,7 +13,7 @@ public class CodeBuilderCloudTest { @Test public void initializes_correctly() throws InterruptedException { - CodeBuilderCloud cloud = new CodeBuilderCloud(null, "project", null, null); + CodeBuilderCloud cloud = new CodeBuilderCloud(null, "project", null, "eu-west-1"); assertEquals("project", cloud.getProjectName()); assertEquals("codebuilder_0", cloud.getDisplayName()); assertNotNull(cloud.getClient()); From 7d172a58bd8a5566fcd434900222d2f74043b73b Mon Sep 17 00:00:00 2001 From: Alejandro Vallecilla Date: Fri, 14 Feb 2020 16:44:14 +0100 Subject: [PATCH 4/5] Adds timeout and logs to codebuild parallel execution --- .../dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java | 6 +++--- .../dev/lsegal/jenkins/codebuilder/CodeBuilderLauncher.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java index 831a3b5..b3c9399 100644 --- a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java +++ b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java @@ -329,7 +329,8 @@ public synchronized AWSCodeBuild getClient() { @Override public synchronized Collection provision(Label label, int excessWorkload) { List list = new ArrayList(); - + String labelName = label == null ? getLabel() : label.getDisplayName(); + LOGGER.info("[CodeBuilder]: Excess workload sent by Jenkins: {} for label: {}", excessWorkload, labelName); // guard against non-matching labels if (label != null && !label.matches(Arrays.asList(new LabelAtom(getLabel())))) { return list; @@ -343,7 +344,6 @@ public synchronized Collection provision(Label label, int excessWor return list; } - String labelName = label == null ? getLabel() : label.getDisplayName(); long stillProvisioning = numStillProvisioning(); long numToLaunch = Math.max(excessWorkload - stillProvisioning, 0); LOGGER.info("[CodeBuilder]: Provisioning {} nodes for label '{}' ({} already provisioning)", numToLaunch, labelName, @@ -372,7 +372,7 @@ public synchronized Collection provision(Label label, int excessWor */ private long numStillProvisioning() { return jenkins().getNodes().stream().filter(CodeBuilderAgent.class::isInstance).map(CodeBuilderAgent.class::cast) - .filter(a -> a.getLauncher().isLaunchSupported()).count(); + .filter(a -> !a.getLauncher().isLaunchSupported()).count(); } /** {@inheritDoc} */ diff --git a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderLauncher.java b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderLauncher.java index be856db..d87b006 100644 --- a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderLauncher.java +++ b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderLauncher.java @@ -66,7 +66,7 @@ public void launch(@Nonnull SlaveComputer computer, @Nonnull TaskListener listen CodeBuilderComputer cbcpu = (CodeBuilderComputer) computer; StartBuildRequest req = new StartBuildRequest().withProjectName(cloud.getProjectName()) .withSourceTypeOverride(SourceType.NO_SOURCE).withBuildspecOverride(buildspec(computer)) - .withImageOverride(cloud.getJnlpImage()).withPrivilegedModeOverride(true) + .withImageOverride(cloud.getJnlpImage()).withPrivilegedModeOverride(true).withTimeoutInMinutesOverride(480) .withComputeTypeOverride(cloud.getComputeType()); try { From a169eb91abdd5416c2797aaa80601cec8a067873 Mon Sep 17 00:00:00 2001 From: Alejandro Vallecilla Date: Fri, 14 Feb 2020 17:03:36 +0100 Subject: [PATCH 5/5] FixeS --- .../dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java index b3c9399..7668f4f 100644 --- a/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java +++ b/src/main/java/dev/lsegal/jenkins/codebuilder/CodeBuilderCloud.java @@ -378,8 +378,14 @@ private long numStillProvisioning() { /** {@inheritDoc} */ @Override public boolean canProvision(Label label) { + LOGGER.info("[CodeBuilder]: Check if can provision node for label '{}'", label); boolean canProvision = label == null ? true : label.matches(Arrays.asList(new LabelAtom(getLabel()))); - LOGGER.info("[CodeBuilder]: Check provisioning capabilities for label '{}': {}", label, canProvision); + if (canProvision) { + LOGGER.info("[CodeBuilder]: Label '{}' matches current label '{}'. Node will be provisioned...", label, getLabel()); + } + else { + LOGGER.info("[CodeBuilder]: Label '{}' DOESN'T MATCH current label '{}'. Node WON'T provisioned...", label, getLabel()); + } return canProvision; }