Skip to content

Commit

Permalink
Allow creating Pod templates from yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
carlossg committed Jan 20, 2018
1 parent 465d4fb commit 318a7ba
Show file tree
Hide file tree
Showing 13 changed files with 547 additions and 62 deletions.
30 changes: 30 additions & 0 deletions README.md
Expand Up @@ -113,6 +113,7 @@ Either way it provides access to the following fields:
* **name** The name of the pod.
* **namespace** The namespace of the pod.
* **label** The label of the pod.
* **yaml** yaml representation of the Pod, to allow setting any values not supported as fields
* **containers** The container templates that are use to create the containers of the pod *(see below)*.
* **serviceAccount** The service account of the pod.
* **nodeSelector** The node selector of the pod.
Expand Down Expand Up @@ -140,6 +141,35 @@ The `containerTemplate` is a template of container that will be added to the pod
* **livenessProbe** Parameters to be added to a exec liveness probe in the container (does not suppot httpGet liveness probes)
* **ports** Expose ports on the container.

#### Using yaml to Define Pod Templates

In order to support any possible value in Kubernetes `Pod` object, we can pass a yaml snippet that will be used as a base
for the template. If any other properties are set outside of the yaml they will take precedence.

```groovy
podTemplate(label: 'mypod', yaml: """
apiVersion: v1
kind: Pod
metadata:
labels:
some-label: some-label-value
spec:
containers:
- name: busybox
image: busybox
command:
- cat
tty: true
"""
) {
node ('mypod') {
container('busybox') {
sh "hostname"
}
}
}
```

#### Liveness Probe Usage
```groovy
containerTemplate(name: 'busybox', image: 'busybox', ttyEnabled: true, command: 'cat', livenessProbe: containerLivenessProbe( execArgs: 'some --command', initialDelaySeconds: 30, timeoutSeconds: 1, failureThreshold: 3, periodSeconds: 10, successThreshold: 1))
Expand Down
32 changes: 32 additions & 0 deletions examples/maven-yaml.groovy
@@ -0,0 +1,32 @@
/**
* This pipeline will execute a simple Maven build using a pod template in yaml
*/

podTemplate(label: 'maven', yaml: """
apiVersion: v1
kind: Pod
metadata:
labels:
some-label: some-label-value
spec:
containers:
- name: maven
image: maven:3.3.9-jdk-8-alpine
command:
- cat
tty: true
env:
- name: CONTAINER_ENV_VAR
value: container-env-var-value
"""
) {

node('maven') {
stage('Build a Maven project') {
git 'https://github.com/jenkinsci/kubernetes-plugin.git'
container('maven') {
sh 'mvn -B clean package'
}
}
}
}
6 changes: 6 additions & 0 deletions pom.xml
Expand Up @@ -179,6 +179,12 @@
<version>${jenkins-workflow-cps.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.9.0</version>
<scope>test</scope>
</dependency>

<!-- for ContainerExecDecoratorPipelineTest -->
<dependency>
Expand Down
Expand Up @@ -33,11 +33,9 @@
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.csanchez.jenkins.plugins.kubernetes.pipeline.PodTemplateStepExecution;
import org.kohsuke.stapler.DataBoundConstructor;

import com.google.common.base.Throwables;
Expand All @@ -56,17 +54,7 @@
* Launches on Kubernetes the specified {@link KubernetesComputer} instance.
*/
public class KubernetesLauncher extends JNLPLauncher {
private static final Pattern SPLIT_IN_SPACES = Pattern.compile("([^\"]\\S*|\".+?\")\\s*");

private static final String WORKSPACE_VOLUME_NAME = "workspace-volume";

private static final String DEFAULT_JNLP_ARGUMENTS = "${computer.jnlpmac} ${computer.name}";

private static final String DEFAULT_JNLP_IMAGE = System
.getProperty(PodTemplateStepExecution.class.getName() + ".defaultImage", "jenkins/jnlp-slave:alpine");

private static final String JNLPMAC_REF = "\\$\\{computer.jnlpmac\\}";
private static final String NAME_REF = "\\$\\{computer.name\\}";
private static final Logger LOGGER = Logger.getLogger(KubernetesLauncher.class.getName());

private boolean launched;
Expand Down Expand Up @@ -108,7 +96,7 @@ public void launch(SlaveComputer computer, TaskListener listener) {
final PodTemplate unwrappedTemplate = slave.getTemplate();
try {
KubernetesClient client = cloud.connect();
Pod pod = getPodTemplate(slave, unwrappedTemplate);
Pod pod = getPodTemplate(client, slave, unwrappedTemplate);

String podId = pod.getMetadata().getName();
String namespace = StringUtils.defaultIfBlank(slave.getNamespace(), client.getNamespace());
Expand Down Expand Up @@ -221,8 +209,8 @@ public void launch(SlaveComputer computer, TaskListener listener) {
}
}

private Pod getPodTemplate(KubernetesSlave slave, PodTemplate template) {
return template == null ? null : template.build(slave);
private Pod getPodTemplate(KubernetesClient client, KubernetesSlave slave, PodTemplate template) {
return template == null ? null : template.build(client, slave);
}

/**
Expand Down
Expand Up @@ -31,6 +31,7 @@
import hudson.model.labels.LabelAtom;
import hudson.tools.ToolLocationNodeProperty;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.client.KubernetesClient;

/**
* Kubernetes Pod Template
Expand Down Expand Up @@ -104,6 +105,8 @@ public class PodTemplate extends AbstractDescribableImpl<PodTemplate> implements

private transient List<ToolLocationNodeProperty> nodeProperties;

private String yaml;

@DataBoundConstructor
public PodTemplate() {
}
Expand All @@ -124,6 +127,7 @@ public PodTemplate(PodTemplate from) {
this.setActiveDeadlineSeconds(from.getActiveDeadlineSeconds());
this.setVolumes(from.getVolumes());
this.setWorkspaceVolume(from.getWorkspaceVolume());
this.setYaml(from.getYaml());
}

@Deprecated
Expand Down Expand Up @@ -559,6 +563,15 @@ public List<ContainerTemplate> getContainers() {
return containers;
}

public String getYaml() {
return yaml;
}

@DataBoundSetter
public void setYaml(String yaml) {
this.yaml = yaml;
}

@SuppressWarnings("deprecation")
protected Object readResolve() {
if (containers == null) {
Expand Down Expand Up @@ -588,10 +601,11 @@ protected Object readResolve() {
/**
* Build a Pod object from a PodTemplate
*
* @param client
* @param slave
*/
public Pod build(KubernetesSlave slave) {
return new PodTemplateBuilder(this).build(slave);
public Pod build(KubernetesClient client, KubernetesSlave slave) {
return new PodTemplateBuilder(this).withSlave(slave).build();
}

@Extension
Expand Down

0 comments on commit 318a7ba

Please sign in to comment.