You can nest podTemplate blocks within each other to compose complex environments. This is particularly useful when creating reusable Pipeline Library functions.
Crucial Requirement: When nesting, you must use the label generated by the innermost podTemplate to call the node step. This ensures the agent runs on a pod that contains all the combined containers from the outer templates.
// Example of nesting templates in a Pipeline Library
package com.foo.utils
public void dockerTemplate(body) {
def label = "worker-${UUID.randomUUID().toString()}"
podTemplate(label: label,
containers: [containerTemplate(name: 'docker', image: 'docker', command: 'cat', ttyEnabled: true)],
volumes: [hostPathVolume(hostPath: '/var/run/docker.sock', mountPath: '/var/run/docker.sock')]) {
body.call(label)
}
}
public void mavenTemplate(body) {
def label = "worker-${UUID.randomUUID().toString()}"
podTemplate(label: label,
containers: [containerTemplate(name: 'maven', image: 'maven', command: 'cat', ttyEnabled: true)],
volumes: [secretVolume(secretName: 'maven-settings', mountPath: '/root/.m2'),
persistentVolumeClaim(claimName: 'maven-local-repo', mountPath: '/root/.m2nrepo')]) {
body.call(label)
}
}
return this
// --- Usage in a Pipeline ---
import com.foo.utils
slaveTemplates = new PodTemplates()
slaveTemplates.dockerTemplate {
slaveTemplates.mavenTemplate { label ->
node(label) {
container('docker') {
sh 'echo from docker'
}
container('maven') {
sh 'echo from maven'
}
}
}
}