Skip to content

Commit 9a9d310

Browse files
authored
Merge branch 'master' into JENKINS-73460
2 parents 38b0d69 + 78bd4a1 commit 9a9d310

21 files changed

+75
-498
lines changed

Jenkinsfile

+1-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ stage('Tests') {
2727
writeFile file: (split.includes ? "$WORKSPACE_TMP/includes.txt" : "$WORKSPACE_TMP/excludes.txt"), text: split.list.join("\n")
2828
writeFile file: (split.includes ? "$WORKSPACE_TMP/excludes.txt" : "$WORKSPACE_TMP/includes.txt"), text: ''
2929
sh './kind.sh -Dsurefire.includesFile="$WORKSPACE_TMP/includes.txt" -Dsurefire.excludesFile="$WORKSPACE_TMP/excludes.txt"'
30-
dir(env.WORKSPACE_TMP) {
31-
junit 'surefire-reports/*.xml'
32-
}
30+
junit 'target/surefire-reports/*.xml'
3331
} finally {
3432
dir(env.WORKSPACE_TMP) {
3533
if (fileExists('kindlogs/docker-info.txt')) {

Jenkinsfile-release

-25
This file was deleted.

README.md

+11-52
Original file line numberDiff line numberDiff line change
@@ -1006,72 +1006,31 @@ Run `mvn clean install` and copy `target/kubernetes.hpi` to Jenkins plugins fold
10061006
10071007
## Running Kubernetes Integration Tests
10081008
1009-
### Integration tests with Kind (recommended)
1009+
Set up your `$KUBECONFIG` however you like, for example
10101010
10111011
```bash
1012-
export MOUNT_M2=true
1013-
./kind-mount-m2.sh
1014-
./kind-preload.sh
1015-
./test-in-k8s.sh -Dtest=KubernetesPipelineTest#runInPod
1016-
kind delete cluster
1012+
kind create cluster
10171013
```
10181014

1019-
### Integration tests in a remote cluster
1020-
1021-
Set up your `$KUBECONFIG` as usual, then
1015+
then
10221016

10231017
```bash
1024-
./test-in-k8s.sh -Dtest=KubernetesPipelineTest#runInPod
1018+
kubectl krew install tunnel # as needed; install Krew first
1019+
kubectl tunnel expose jenkins 8000:8000 8001:8001 &
1020+
mvn test -Djenkins.host.address=jenkins.default -Dport=8000 -DslaveAgentPort=8001 -Dtest=KubernetesPipelineTest#runInPod
10251021
```
10261022

1027-
### Integration tests with Minikube
1028-
1029-
The system you run `mvn` on needs to be reachable from the cluster.
1030-
If you see the agents happen to connect to the wrong host, see you can use
1031-
`jenkins.host.address` as mentioned above.
1032-
1033-
For integration tests install and start [minikube](https://github.com/kubernetes/minikube).
1034-
Tests will detect it and run a set of integration tests in a new namespace.
1035-
1036-
Some integration tests run a local jenkins, so the host that runs them needs
1037-
to be accessible from the kubernetes cluster.
1038-
By default Jenkins will listen on `192.168.64.1` interface only, for security reasons.
1039-
If your minikube is not running in that network, pass `connectorHost` to maven, ie.
1040-
1041-
mvn clean install -DconnectorHost=$(minikube ip | sed -e 's/\([0-9]*\.[0-9]*\.[0-9]*\).*/\1.1/')
1042-
1043-
If you don't mind others in your network being able to use your test jenkins you could just use this:
1044-
1045-
mvn clean install -DconnectorHost=0.0.0.0
1046-
1047-
Then your test jenkins will listen on all ip addresses so that the build pods will be able to connect from the pods in your minikube VM to your host.
1048-
1049-
If your minikube is running in a VM (e.g. on virtualbox) and the host running `mvn`
1050-
does not have a public hostname for the VM to access, you can set the `jenkins.host.address`
1051-
system property to the (host-only or NAT) IP of your host:
1052-
1053-
mvn clean install -Djenkins.host.address=192.168.99.1
1054-
1055-
### Integration tests with Microk8s
1056-
1057-
If [Microk8s](https://microk8s.io/) is running and is the default context in your `~/.kube/config`,
1058-
just run as
1059-
1060-
mvn clean install -Pmicrok8s
1061-
1062-
This assumes that from a pod, the host system is accessible as IP address `10.1.1.1`.
1063-
It might be some variant such as `10.1.37.1`,
1064-
in which case you would need to set `-DconnectorHost=… -Djenkins.host.address=…` instead.
1065-
To see the actual address, try:
1023+
Alternately, you can run everything like in CI:
10661024

10671025
```bash
1068-
ifdata -pa cni0
1026+
export KIND_PRELOAD=true # optionally
1027+
./kind.sh -Dtest=KubernetesPipelineTest#runInPod
10691028
```
10701029

1071-
Or to verify the networking inside a pod:
1030+
You can also run interactively after setting up the tunnel:
10721031

10731032
```bash
1074-
kubectl run --rm --image=praqma/network-multitool --restart=Never --attach sh ip route | fgrep 'default via'
1033+
mvn hpi:run -Djenkins.host.address=jenkins.default -Dport=8000 -Djenkins.model.Jenkins.slaveAgentPort=8001
10751034
```
10761035

10771036
# Docker image

kind-mount-m2.sh

-23
This file was deleted.

kind-preload.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ set -euxo pipefail
33
cd $(dirname $0)
44

55
PRE_LOAD_IMAGES=()
6-
PRE_LOAD_IMAGES+=($(grep -e image: test-in-k8s.yaml | cut -d ':' -f 2- | xargs))
6+
PRE_LOAD_IMAGES+=(omrieival/ktunnel:v1.6.1)
77
PRE_LOAD_IMAGES+=($(grep -h --include="*.groovy" -e "^\s*image: .*$" -R src/test/resources | sed -e "s/^[[:space:]]*image: //" | sort | uniq | grep -v "windows" | grep -v "nonexistent" | grep -v "invalid" | xargs))
88
PRE_LOAD_IMAGES+=($(grep -e FROM src/main/resources/org/csanchez/jenkins/plugins/kubernetes/Dockerfile | cut -d ' ' -f 2-))
99
if [[ -v cluster ]]

kind.sh

+30-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
set -euxo pipefail
33
cd $(dirname $0)
44

5+
: ${WORKSPACE_TMP:=/tmp}
6+
57
export PATH=$WORKSPACE_TMP:$PATH
68
if [ \! -x "$WORKSPACE_TMP/kind" ]
79
then
@@ -13,25 +15,41 @@ then
1315
curl -sLo "$WORKSPACE_TMP/kubectl" https://storage.googleapis.com/kubernetes-release/release/v1.30.1/bin/$(uname | tr '[:upper:]' '[:lower:]')/amd64/kubectl
1416
chmod +x "$WORKSPACE_TMP/kubectl"
1517
fi
18+
if [ \! -x "$WORKSPACE_TMP/ktunnel" ]
19+
then
20+
(cd "$WORKSPACE_TMP"; curl -sL https://github.com/omrikiei/ktunnel/releases/download/v1.6.1/ktunnel_1.6.1_Linux_x86_64.tar.gz | tar xvfz - ktunnel)
21+
fi
1622

1723
export cluster=ci$RANDOM
1824
export KUBECONFIG="$WORKSPACE_TMP/kubeconfig-$cluster"
19-
if ${MOUNT_M2:-false}
20-
then
21-
./kind-mount-m2.sh
22-
else
23-
kind create cluster --name $cluster --wait 5m
24-
fi
25+
kind create cluster --name $cluster --wait 5m
2526
function cleanup() {
26-
kind export logs --name $cluster "$WORKSPACE_TMP/kindlogs" || :
27-
kind delete cluster --name $cluster || :
27+
set +e
28+
if [ -v ktunnel_pid ]
29+
then
30+
kill $ktunnel_pid
31+
fi
32+
kind export logs --name $cluster "$WORKSPACE_TMP/kindlogs"
33+
kind delete cluster --name $cluster
2834
rm "$KUBECONFIG"
2935
}
3036
trap cleanup EXIT
3137
kubectl cluster-info
3238

33-
./kind-preload.sh
39+
if ${KIND_PRELOAD:-false}
40+
then
41+
./kind-preload.sh
42+
fi
43+
44+
ktunnel expose jenkins 8000:8000 8001:8001 &
45+
ktunnel_pid=$!
3446

35-
./test-in-k8s.sh "$@"
36-
rm -rf "$WORKSPACE_TMP/surefire-reports"
37-
kubectl cp jenkins:/checkout/target/surefire-reports "$WORKSPACE_TMP/surefire-reports"
47+
mvn \
48+
-B \
49+
-ntp \
50+
-Djenkins.host.address=jenkins.default \
51+
-Dport=8000 \
52+
-DslaveAgentPort=8001 \
53+
-Dmaven.test.failure.ignore \
54+
verify \
55+
"$@"

pom.xml

+2-30
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>org.jenkins-ci.plugins</groupId>
66
<artifactId>plugin</artifactId>
7-
<version>4.84</version>
7+
<version>4.86</version>
88
<relativePath />
99
</parent>
1010

@@ -41,9 +41,6 @@
4141

4242
<properties>
4343
<changelist>999999-SNAPSHOT</changelist>
44-
<!-- in minikube
45-
minikube ip | sed -e 's/\([0-9]*\.[0-9]*\.[0-9]*\).*/\1.1/' -->
46-
<connectorHost />
4744
<jenkins.host.address />
4845
<slaveAgentPort />
4946
<jenkins.version>2.426.3</jenkins.version>
@@ -295,8 +292,6 @@
295292
<hudson.slaves.NodeProvisioner.initialDelay>0</hudson.slaves.NodeProvisioner.initialDelay>
296293
<hudson.slaves.NodeProvisioner.recurrencePeriod>3000</hudson.slaves.NodeProvisioner.recurrencePeriod>
297294
<org.jenkinsci.plugins.workflow.support.pickles.ExecutorPickle.timeoutForNodeMillis>60000</org.jenkinsci.plugins.workflow.support.pickles.ExecutorPickle.timeoutForNodeMillis>
298-
<!-- listen in this interface for connections from kubernetes pods -->
299-
<connectorHost>${connectorHost}</connectorHost>
300295
<!-- have pods connect to this address for Jenkins -->
301296
<jenkins.host.address>${jenkins.host.address}</jenkins.host.address>
302297
<slaveAgentPort>${slaveAgentPort}</slaveAgentPort>
@@ -312,6 +307,7 @@
312307
<hudson.slaves.NodeProvisioner.MARGIN>50</hudson.slaves.NodeProvisioner.MARGIN>
313308
<hudson.slaves.NodeProvisioner.MARGIN0>0.85</hudson.slaves.NodeProvisioner.MARGIN0>
314309
<jenkins.host.address>${jenkins.host.address}</jenkins.host.address>
310+
<port>${port}</port>
315311
<org.csanchez.jenkins.plugins.kubernetes.pipeline.PodTemplateStepExecution.verbose>true</org.csanchez.jenkins.plugins.kubernetes.pipeline.PodTemplateStepExecution.verbose>
316312
</systemProperties>
317313
</configuration>
@@ -347,28 +343,4 @@
347343
</plugins>
348344
</build>
349345

350-
<profiles>
351-
<profile>
352-
<id>docker</id>
353-
<properties>
354-
<connectorHost>192.168.1.27</connectorHost>
355-
<jenkins.host.address>192.168.1.27</jenkins.host.address>
356-
</properties>
357-
</profile>
358-
<profile>
359-
<id>microk8s</id>
360-
<properties>
361-
<connectorHost>10.1.1.1</connectorHost>
362-
<jenkins.host.address>10.1.1.1</jenkins.host.address>
363-
</properties>
364-
</profile>
365-
<profile>
366-
<id>docker-desktop</id>
367-
<properties>
368-
<connectorHost>127.0.0.1</connectorHost>
369-
<jenkins.host.address>host.docker.internal</jenkins.host.address>
370-
</properties>
371-
</profile>
372-
</profiles>
373-
374346
</project>

src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloud.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import jenkins.model.Jenkins;
6464
import jenkins.model.JenkinsLocationConfiguration;
6565
import jenkins.security.FIPS140;
66+
import jenkins.util.SystemProperties;
6667
import jenkins.websocket.WebSockets;
6768
import net.sf.json.JSONObject;
6869
import org.apache.commons.lang.StringUtils;
@@ -1294,7 +1295,8 @@ public static void hpiRunInit() {
12941295
if (hostAddress != null
12951296
&& jenkins.clouds.getAll(KubernetesCloud.class).isEmpty()) {
12961297
KubernetesCloud cloud = new KubernetesCloud("kubernetes");
1297-
cloud.setJenkinsUrl("http://" + hostAddress + ":8080/jenkins/");
1298+
cloud.setJenkinsUrl(
1299+
"http://" + hostAddress + ":" + SystemProperties.getInteger("port", 8080) + "/jenkins/");
12981300
jenkins.clouds.add(cloud);
12991301
}
13001302
}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
FROM jenkins/inbound-agent:3248.v65ecb_254c298-2
1+
FROM jenkins/inbound-agent:3256.v88a_f6e922152-4

src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTestUtil.java

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ public static void setupHost(KubernetesCloud cloud) throws Exception {
135135
URL nonLocalhostUrl = new URL(url.getProtocol(), hostAddress, url.getPort(), url.getFile());
136136
cloud.setJenkinsUrl(nonLocalhostUrl.toString());
137137

138+
// TODO could just use standard jenkins.model.Jenkins.slaveAgentPort and skip this code (also in SetupCloud):
138139
Integer slaveAgentPort = Integer.getInteger("slaveAgentPort");
139140
if (slaveAgentPort != null) {
140141
Jenkins.get().setSlaveAgentPort(slaveAgentPort);

src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineRJRTest.java

-5
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ public abstract class AbstractKubernetesPipelineRJRTest {
2323

2424
{
2525
rjr = new RealJenkinsRule();
26-
String connectorHost = System.getProperty("connectorHost");
27-
if (StringUtils.isNotBlank(connectorHost)) {
28-
System.err.println("Listening on host address: " + connectorHost);
29-
rjr.withHttpListenAddress(connectorHost);
30-
}
3126
String port = System.getProperty("port");
3227
if (StringUtils.isNotBlank(port)) {
3328
System.err.println("Overriding port using system property: " + port);

src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
import org.junit.Rule;
6363
import org.junit.rules.TestName;
6464
import org.jvnet.hudson.test.BuildWatcher;
65-
import org.jvnet.hudson.test.JenkinsRuleNonLocalhost;
65+
import org.jvnet.hudson.test.JenkinsRule;
6666
import org.jvnet.hudson.test.LoggerRule;
6767

6868
public abstract class AbstractKubernetesPipelineTest {
@@ -76,7 +76,7 @@ public abstract class AbstractKubernetesPipelineTest {
7676
protected KubernetesCloud cloud;
7777

7878
@Rule
79-
public JenkinsRuleNonLocalhost r = new JenkinsRuleNonLocalhost();
79+
public JenkinsRule r = new JenkinsRule();
8080

8181
@Rule
8282
public LoggerRule logs = new LoggerRule()

src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/DirectConnectionTest.java

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.csanchez.jenkins.plugins.kubernetes.pipeline;
1818

19+
import hudson.TcpSlaveAgentListener;
1920
import java.util.logging.Level;
2021
import org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil;
2122
import org.csanchez.jenkins.plugins.kubernetes.PodTemplateBuilder;
@@ -24,6 +25,11 @@
2425

2526
public final class DirectConnectionTest extends AbstractKubernetesPipelineTest {
2627

28+
static {
29+
System.setProperty(
30+
TcpSlaveAgentListener.class.getName() + ".hostName", System.getProperty("jenkins.host.address"));
31+
}
32+
2733
@Before
2834
public void setUp() throws Exception {
2935
KubernetesTestUtil.deletePods(cloud.connect(), KubernetesTestUtil.getLabels(cloud, this, name), false);

src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineTest.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@
105105
import org.jvnet.hudson.test.FlagRule;
106106
import org.jvnet.hudson.test.Issue;
107107
import org.jvnet.hudson.test.JenkinsRule;
108-
import org.jvnet.hudson.test.JenkinsRuleNonLocalhost;
109108
import org.jvnet.hudson.test.LoggerRule;
110109
import org.jvnet.hudson.test.MockAuthorizationStrategy;
111110
import org.jvnet.hudson.test.TestExtension;
@@ -436,7 +435,7 @@ public void runWithEnvVariablesInContext() throws Exception {
436435
r.assertLogContains("The value of WILL.NOT is ", b);
437436
}
438437

439-
private void assertEnvVars(JenkinsRuleNonLocalhost r2, WorkflowRun b) throws Exception {
438+
private void assertEnvVars(JenkinsRule r2, WorkflowRun b) throws Exception {
440439
r.assertLogNotContains(POD_ENV_VAR_FROM_SECRET_VALUE, b);
441440
r.assertLogNotContains(CONTAINER_ENV_VAR_FROM_SECRET_VALUE, b);
442441

src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecutionTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@
3838
import org.junit.BeforeClass;
3939
import org.junit.Rule;
4040
import org.junit.Test;
41-
import org.jvnet.hudson.test.JenkinsRuleNonLocalhost;
41+
import org.jvnet.hudson.test.JenkinsRule;
4242

4343
public class PodTemplateStepExecutionTest {
4444

4545
@Rule
46-
public JenkinsRuleNonLocalhost r = new JenkinsRuleNonLocalhost();
46+
public JenkinsRule r = new JenkinsRule();
4747

4848
protected KubernetesCloud cloud;
4949

0 commit comments

Comments
 (0)