diff --git a/resources/podTemplate2.yaml b/resources/podTemplate2.yaml new file mode 100644 index 0000000..5da469f --- /dev/null +++ b/resources/podTemplate2.yaml @@ -0,0 +1,19 @@ +spec: + containers: + - name: buildah + image: quay.io/containers/buildah:v1 + command: + - cat + stdin: true + tty: true + securityContext: + capabilities: + add: + - SYS_ADMIN + - MKNOD + - SYS_CHROOT + - SETFCAP + resources: + limits: + github.com/fuse: 1 + hostUsers: false diff --git a/vars/buildContainerImage2.groovy b/vars/buildContainerImage2.groovy new file mode 100644 index 0000000..a9329d2 --- /dev/null +++ b/vars/buildContainerImage2.groovy @@ -0,0 +1,144 @@ +// vim: set sw=4 sts=4 ts=4 et : + +def call(args) { + properties([ + pipelineTriggers([cron('H H H * *')]) + ]) + + def registry = args?.registry + def project = args?.project + def name = args?.name + def tag = args?.tag + def archlist = args?.archlist + + if (registry == null) { + registry = 'git.pyrocufflink.net' + } + if (project == null) { + project = 'containerimages' + } + if (name == null) { + name = env.JOB_NAME. + split('/')[1]. + toLowerCase(). + replaceAll('[^a-zA-z0-9._-]', '-'). + replaceAll('^[.-]', '_') + } + if (tag == null) { + tag = env.BRANCH_NAME. + toLowerCase(). + replaceAll('[^a-zA-z0-9._-]', '-'). + replaceAll('^[.-]', '_') + } + if (archlist == null) { + archlist = ['amd64'] + } + def repo = "${registry}/${project}/${name}" + def full_name = "${repo}:${tag}" + + def stages = [:] + archlist.each { arch -> + def stageName = "Build ${arch}" + stages[stageName] = { + stage(stageName) { + buildStage( + name: name, + full_name: full_name, + registry: registry, + arch: arch, + ) + } + } + } + parallel stages + + runInPod { + container('buildah') { + withBuildahCreds(registry) { + if (archlist.size() > 1) { + stage('Build Manifest') { + sh "buildah manifest create '${full_name}'" + archlist.each { arch -> + unstash arch + sh "buildah manifest add '${full_name}' oci-archive:\${PWD}/${name}-${arch}.tar" + } + } + } + stage('Push') { + if (archlist.size() > 1) { + sh "buildah manifest push --all ${full_name} docker://${full_name}-${env.BUILD_NUMBER}" + sh "buildah manifest push ${full_name} docker://${full_name}" + if (env.BRANCH_NAME == 'main') { + sh "buildah manifest push ${full_name} docker://${repo}:latest" + } + } else { + sh "buildah push ${full_name} ${full_name}-${env.BUILD_NUMBER}" + sh "buildah push ${full_name}" + if (env.BRANCH_NAME == 'main') { + sh "buildah push ${full_name} ${repo}:latest" + } + } + } + } + } + } +} + +def buildStage(args) { + def name = args.name + def full_name = args.full_name + def registry = args.registry + def arch = args.arch + + runInPod(arch) { + checkout scm + + container('buildah') { + withBuildahCreds(registry) { + sh "buildah build -t '${full_name}' ." + sh "buildah push '${full_name}' oci-archive:\${PWD}/${name}-${arch}.tar" + stash name: arch, includes: "${name}-*.tar" + } + } + } +} + +def runInPod(... args) { + def arch = null + def block = args.last() + if (args.size() > 1) { + arch = args[0] + } + + def podTemplateYaml = libraryResource('podTemplate2.yaml') + podTemplate( + yaml: podTemplateYaml, + nodeSelector: arch ? "kubernetes.io/arch=${arch}" : null, + workspaceVolume: emptyDirWorkspaceVolume(), + ) { + node(POD_LABEL) { + block() + } + } +} + +def withBuildahCreds(registry, block) { + withEnv([ + "REGISTRY_AUTH_FILE=${env.WORKSPACE_TMP}/auth.json" + ]) { + withCredentials([usernamePassword( + credentialsId: 'jenkins-packages', + usernameVariable: 'BUILDAH_USERNAME', + passwordVariable: 'BUILDAH_PASSWORD', + )]) { + sh """ + buildah login \ + --username \${BUILDAH_USERNAME} \ + --password \${BUILDAH_PASSWORD} \ + ${registry} + """ + } + + block() + } +}