BuildahParallelBuild.groovy (3239B)
1 import BuildahBud 2 import BuildahPush 3 import BuildahManifest 4 5 // Matrix build for scripted pipelines: 6 // https://www.jenkins.io/blog/2019/12/02/matrix-building-with-scripted-pipeline/#full-pipeline-example-with-dynamic-choices 7 8 // A class to perform parallel builds with buildah 9 class BuildahParallelBuild implements Serializable { 10 private final Script script 11 12 private BuildahBud buildahbud 13 private BuildahPush buildahpush 14 private BuildahManifest buildahmanifest 15 16 // responses of dynamic choice 17 private Map response = [:] 18 19 // possible build dimensions 20 private Map matrix_axes = [ 21 PLATFORM: ['podman'], 22 ARCH: ['arm64', 'amd64'], 23 ] 24 25 // parallel task map 26 private Map tasks = [failFast: false] 27 28 BuildahParallelBuild(Script script) { 29 this.script = script 30 buildahbud = new BuildahBud(script) 31 buildahpush = new BuildahPush(script) 32 buildahmanifest = new BuildahManifest(script) 33 } 34 35 @NonCPS 36 private List getMatrixAxes(Map matrix_axes) { 37 List axes = [] 38 matrix_axes.each { axis, values -> 39 List axisList = [] 40 values.each { value -> 41 axisList << [(axis): value] 42 } 43 axes << axisList 44 } 45 // calculate cartesian product 46 axes.combinations()*.sum() 47 } 48 49 void build(String imgName, 50 String imgTag, 51 String imgContext, 52 Map imgBuildArgs = [:], 53 String dockerFile = "Dockerfile", 54 String imgRegistry = "haproxy.lan:5000") { 55 56 script.stage("Choose combinations") { 57 response = script.input( 58 id: 'Platform', 59 message: 'Customize your matrix build.', 60 parameters: this.matrix_axes.collect { key, options -> 61 script.choice( 62 choices: ['all'] + options.sort(), 63 description: "Choose a single ${key.toLowerCase()} or all to run tests.", 64 name: key) 65 }) 66 } 67 68 List axes = this.getMatrixAxes(this.matrix_axes) 69 70 for(int i = 0; i < axes.size(); i++) { 71 // convert the Axis into valid values for withEnv step 72 Map axis = axes[i] 73 List axisEnv = axis.collect { k, v -> 74 "${k}=${v}" 75 } 76 77 String nodeLabel = "${axis['PLATFORM']} && ${axis['ARCH']}" 78 this.tasks[axisEnv.join(', ')] = { -> 79 script.node(nodeLabel) { 80 script.withEnv(axisEnv) { 81 script.stage("Buildah Bud") { 82 buildahbud.execute(imgBuildArgs, imgContext, imgName, 83 "${imgTag}-${axis['ARCH']}", dockerFile, axis['ARCH']) 84 } 85 script.stage("Buildah Push") { 86 buildahpush.execute(imgName, "${imgTag}-${axis['ARCH']}") 87 } 88 } 89 } 90 } 91 } 92 93 script.stage("Matrix builds") { 94 script.parallel(this.tasks) 95 } 96 97 script.stage("Manifest creation") { 98 script.node('podman&&arm64') { 99 script.stage("Buildah Manifest Create") { 100 buildahmanifest.create("${imgRegistry}/${imgName}:${imgTag}", [ 101 "${imgRegistry}/${imgName}:${imgTag}-arm64", 102 "${imgRegistry}/${imgName}:${imgTag}-amd64" 103 ]) 104 } 105 script.stage("Buildah Manifest Push") { 106 buildahmanifest.push("${imgRegistry}/${imgName}:${imgTag}") 107 } 108 } 109 } 110 } 111 }