From ae330820225f562c4ec8942aefc1dd6b1a194e53 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Wed, 17 Jan 2024 21:18:24 -0600 Subject: [PATCH] ci: Build container image In addition to building an RPM package for regular Fedora machines, we now build a container image containing a statically-linked `sshca-cli` executable. --- .containerignore | 4 ++ Containerfile | 18 +++++++++ ci/Jenkinsfile | 71 +++++++++++++++++++++++++++++++++-- ci/build-container.sh | 6 +++ ci/common.sh | 13 +++++++ ci/podTemplate-container.yaml | 19 ++++++++++ ci/publish-container.sh | 15 ++++++++ 7 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 .containerignore create mode 100644 Containerfile create mode 100644 ci/build-container.sh create mode 100644 ci/common.sh create mode 100644 ci/podTemplate-container.yaml create mode 100644 ci/publish-container.sh diff --git a/.containerignore b/.containerignore new file mode 100644 index 0000000..3ab56d6 --- /dev/null +++ b/.containerignore @@ -0,0 +1,4 @@ +* +!src +!Cargo.lock +!Cargo.toml diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..50f98f7 --- /dev/null +++ b/Containerfile @@ -0,0 +1,18 @@ +FROM docker.io/library/rust:1.73-alpine AS build + +COPY . /build + +WORKDIR /build + +RUN --mount=type=cache,target=/var/cache \ + apk add --no-cache g++ \ + && : + +RUN cargo build --release --no-default-features --features rustls \ + && strip target/release/sshca-cli + +FROM scratch + +COPY --from=build /build/target/release/sshca-cli / + +ENTRYPOINT ["/sshca-cli"] diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile index 9aa02b1..c2da6a3 100644 --- a/ci/Jenkinsfile +++ b/ci/Jenkinsfile @@ -2,7 +2,7 @@ pipeline { agent none stages { - stage('SSHCA CLI') { + stage('RPM') { matrix { axes { axis { @@ -16,7 +16,7 @@ pipeline { } stages { - stage('CLI') { + stage('Build RPM') { agent { kubernetes { yamlFile 'ci/podTemplate.yaml' @@ -79,8 +79,73 @@ pipeline { } } } - } } + + stage('Build Container') { + matrix { + axes { + axis { + name 'ARCH' + values 'amd64', 'arm64' + } + } + stages { + stage('Container') { + agent { + kubernetes { + yamlFile 'ci/podTemplate-container.yaml' + yamlMergeStrategy merge() + defaultContainer 'buildah' + nodeSelector "kubernetes.io/arch=${ARCH}" + } + } + + stages { + stage('Build') { + steps { + sh '. ci/build-container.sh' + stash name: env.ARCH, includes: "*.oci.tar" + } + } + } + } + } + } + } + + stage('Publish Container') { + agent { + kubernetes { + yamlFile 'ci/podTemplate-container.yaml' + yamlMergeStrategy merge() + defaultContainer 'buildah' + } + } + + environment { + REGISTRY_AUTH_FILE = "${env.WORKSPACE_TMP}/auth.json" + } + + steps { + unstash 'amd64' + unstash 'arm64' + withCredentials([usernamePassword( + credentialsId: 'jenkins-packages', + usernameVariable: 'BUILDAH_USERNAME', + passwordVariable: 'BUILDAH_PASSWORD', + )]) { + sh """ + buildah login \ + --username \${BUILDAH_USERNAME} \ + --password \${BUILDAH_PASSWORD} \ + git.pyrocufflink.net + """ + } + sh '. ci/publish.sh' + } + } + + } } diff --git a/ci/build-container.sh b/ci/build-container.sh new file mode 100644 index 0000000..5e1315e --- /dev/null +++ b/ci/build-container.sh @@ -0,0 +1,6 @@ +. ci/common.sh + +buildah build -t "${IMAGE_NAME}:${TAG}" . +buildah push \ + "${IMAGE_NAME}:${TAG}" \ + oci-archive:"${PWD}/${NAME}-${ARCH}.oci.tar:${IMAGE_NAME}:${TAG}" diff --git a/ci/common.sh b/ci/common.sh new file mode 100644 index 0000000..060e8cb --- /dev/null +++ b/ci/common.sh @@ -0,0 +1,13 @@ +escape_name() { + echo "$1" \ + | tr A-Z a-z \ + | sed -e 's/[^a-zA-Z0-9._-]/-/g' -e 's/^[.-]/_/' +} + +REGISTRY_URL=git.pyrocufflink.net +NAMESPACE=containerimages +NAME="${JOB_NAME#*/}" +NAME=$(escape_name "${NAME%/*}") +TAG=$(escape_name "${BRANCH_NAME}") + +IMAGE_NAME="${REGISTRY_URL}/${NAMESPACE}/${NAME}" diff --git a/ci/podTemplate-container.yaml b/ci/podTemplate-container.yaml new file mode 100644 index 0000000..5da469f --- /dev/null +++ b/ci/podTemplate-container.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/ci/publish-container.sh b/ci/publish-container.sh new file mode 100644 index 0000000..5e69dd7 --- /dev/null +++ b/ci/publish-container.sh @@ -0,0 +1,15 @@ +. ci/common.sh + +buildah manifest create "${IMAGE_NAME}:${TAG}" +for arch in amd64 arm64; do + buildah manifest add "${IMAGE_NAME}:${TAG}" \ + oci-archive:"${PWD}/${NAME}-${arch}.oci.tar:${IMAGE_NAME}:${TAG}" +done + +buildah manifest push --all "${IMAGE_NAME}:${TAG}" \ + "docker://${IMAGE_NAME}:${TAG}-${BUILD_NUMBER}" +buildah manifest push "${IMAGE_NAME}:${TAG}" "docker://${IMAGE_NAME}:${TAG}" +if [ ${BRANCH_NAME} = master ]; then + buildah manifest push "${IMAGE_NAME}:${TAG}" \ + "docker://${IMAGE_NAME}:latest" +fi