From 82a2a61e200bfb4a74eff6ea9001c57cbf3d3def Mon Sep 17 00:00:00 2001 From: Jimmy Jones Date: Sat, 22 Jun 2024 19:46:00 +0100 Subject: [PATCH] buildah 0.8 * don't use interpolation * easier way of specifying build args * move to v1 resources --- task/buildah/0.8/README.md | 76 +++++++++++ task/buildah/0.8/buildah.yaml | 129 ++++++++++++++++++ task/buildah/0.8/samples/dockerconfig.yaml | 67 +++++++++ .../samples/openshift-internal-registry.yaml | 87 ++++++++++++ .../internal-registry/internal-registry.yaml | 50 +++++++ task/buildah/0.8/tests/pre-apply-task-hook.sh | 6 + task/buildah/0.8/tests/run.yaml | 126 +++++++++++++++++ 7 files changed, 541 insertions(+) create mode 100644 task/buildah/0.8/README.md create mode 100644 task/buildah/0.8/buildah.yaml create mode 100644 task/buildah/0.8/samples/dockerconfig.yaml create mode 100644 task/buildah/0.8/samples/openshift-internal-registry.yaml create mode 100644 task/buildah/0.8/tests/internal-registry/internal-registry.yaml create mode 100755 task/buildah/0.8/tests/pre-apply-task-hook.sh create mode 100644 task/buildah/0.8/tests/run.yaml diff --git a/task/buildah/0.8/README.md b/task/buildah/0.8/README.md new file mode 100644 index 00000000..aa5047c5 --- /dev/null +++ b/task/buildah/0.8/README.md @@ -0,0 +1,76 @@ +# Buildah + +This Task builds source into a container image using Project Atomic's +[Buildah](https://github.com/projectatomic/buildah) build tool. It uses +Buildah's support for building from +[`Dockerfile`](https://docs.docker.com/engine/reference/builder/)s, using its +`buildah bud` command. This command executes the directives in the `Dockerfile` +to assemble a container image, then pushes that image to a container registry. + +## Install the Task + +``` +kubectl apply -f https://api.hub.tekton.dev/v1/resource/tekton/task/buildah/0.8/raw +``` + +## Parameters + +* **IMAGE**: The name (reference) of the image to build. +* **BUILDER_IMAGE:**: The name of the image containing the Buildah tool. See + note below. (_default:_ `quay.io/buildah/stable:v1`) +* **DOCKERFILE**: The path to the `Dockerfile` to execute (_default:_ + `./Dockerfile`) +* **CONTEXT**: Path to the directory to use as context (_default:_ + `.`) +* **TLSVERIFY**: Verify the TLS on the registry endpoint (for push/pull to a + non-TLS registry) (_default:_ `true`) +* **FORMAT**: The format of the built container, oci or docker (_default:_ + `oci`) +* **BUILD_EXTRA_ARGS**: Extra parameters passed for the build command when + building images. WARNING - must be sanitized to avoid command injection + (_default:_ `""`) +* **PUSH_EXTRA_ARGS**: Extra parameters passed for the push command when + pushing images. WARNING - must be sanitized to avoid command injection + (_default:_ `""`) +* **SKIP_PUSH**: Skip pushing the built image (_default:_ `false`) +* **BUILD_ARGS**: Dockerfile build arguments, array of key=value (_default:_ [""]) + +## Results + +* **IMAGE_URL**: Image repository where the built image would be pushed to +* **IMAGE_DIGEST**: Digest of the image just built + +## Workspaces + +* **source**: A [Workspace](https://github.com/tektoncd/pipeline/blob/main/docs/workspaces.md) containing the source to build. +* **sslcertdir**: An [*optional* Workspace](https://github.com/tektoncd/pipeline/blob/v0.17.0/docs/workspaces.md#optional-workspaces) containing your custom SSL certificates to connect to the registry. Buildah will look for files ending with *.crt, *.cert, *.key into this workspace. See [this sample](./samples/openshift-internal-registry.yaml) for a complete example on how to use it with OpenShift internal registry. +- **dockerconfig**: An [optional workspace](https://github.com/tektoncd/pipeline/blob/main/docs/workspaces.md#using-workspaces-in-tasks) that allows providing a `.docker/config.json` file for Buildah to access the container registry. The file should be placed at the root of the Workspace with name `config.json`. See [this sample](./samples/dockerconfig.yaml) for a complete example on how to use `dockerconfig` to access container registry. _(optional)_ + +## Platforms + +The Task can be run on `linux/amd64`, `linux/s390x`, `linux/arm64` and `linux/ppc64le` platforms. + +## Usage + +This TaskRun runs the Task to fetch a Git repo, and build and push a container +image using Buildah. + +```yaml +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: buildah-build-my-repo +spec: + taskRef: + name: buildah + params: + - name: IMAGE + value: gcr.io/my-repo/my-image + workspaces: + - name: source + persistentVolumeClaim: + claimName: my-source +``` + +In this example, the Git repo being built is expected to have a `Dockerfile` at +the root of the repository. diff --git a/task/buildah/0.8/buildah.yaml b/task/buildah/0.8/buildah.yaml new file mode 100644 index 00000000..7866810f --- /dev/null +++ b/task/buildah/0.8/buildah.yaml @@ -0,0 +1,129 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: buildah + labels: + app.kubernetes.io/version: "0.8" + annotations: + tekton.dev/categories: Image Build + tekton.dev/pipelines.minVersion: "0.50.0" + tekton.dev/tags: image-build + tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64" + tekton.dev/displayName: buildah +spec: + description: >- + Buildah task builds source into a container image and + then pushes it to a container registry. + + Buildah Task builds source into a container image using Project Atomic's + Buildah build tool.It uses Buildah's support for building from Dockerfiles, + using its buildah bud command.This command executes the directives in the + Dockerfile to assemble a container image, then pushes that image to a + container registry. + + params: + - name: IMAGE + description: Reference of the image buildah will produce. + - name: BUILDER_IMAGE + description: The location of the buildah builder image. + default: quay.io/buildah/stable:v1 + - name: STORAGE_DRIVER + description: Set buildah storage driver + default: overlay + - name: DOCKERFILE + description: Path to the Dockerfile to build. + default: ./Dockerfile + - name: CONTEXT + description: Path to the directory to use as context. + default: . + - name: TLSVERIFY + description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) + default: "true" + - name: FORMAT + description: The format of the built container, oci or docker + default: "oci" + - name: BUILD_EXTRA_ARGS + description: Extra parameters passed for the build command when building images. WARNING - must be sanitized to avoid command injection + default: "" + - name: PUSH_EXTRA_ARGS + description: Extra parameters passed for the push command when pushing images. WARNING - must be sanitized to avoid command injection + type: string + default: "" + - name: SKIP_PUSH + description: Skip pushing the built image + default: "false" + - name: BUILD_ARGS + description: Dockerfile build arguments, array of key=value + type: array + default: + - "" + workspaces: + - name: source + - name: sslcertdir + optional: true + - name: dockerconfig + description: >- + An optional workspace that allows providing a .docker/config.json file + for Buildah to access the container registry. + The file should be placed at the root of the Workspace with name config.json. + optional: true + results: + - name: IMAGE_DIGEST + description: Digest of the image just built. + - name: IMAGE_URL + description: Image repository where the built image would be pushed to + steps: + - name: build-and-push + image: $(params.BUILDER_IMAGE) + workingDir: $(workspaces.source.path) + env: + - name: PARAM_IMAGE + value: $(params.IMAGE) + - name: PARAM_STORAGE_DRIVER + value: $(params.STORAGE_DRIVER) + - name: PARAM_DOCKERFILE + value: $(params.DOCKERFILE) + - name: PARAM_CONTEXT + value: $(params.CONTEXT) + - name: PARAM_TLSVERIFY + value: $(params.TLSVERIFY) + - name: PARAM_FORMAT + value: $(params.FORMAT) + - name: PARAM_BUILD_EXTRA_ARGS + value: $(params.BUILD_EXTRA_ARGS) + - name: PARAM_PUSH_EXTRA_ARGS + value: $(params.PUSH_EXTRA_ARGS) + - name: PARAM_SKIP_PUSH + value: $(params.SKIP_PUSH) + args: + - $(params.BUILD_ARGS[*]) + script: | + BUILD_ARGS=() + for buildarg in "$@" + do + BUILD_ARGS+=("--build-arg=$buildarg") + done + [ "$(workspaces.sslcertdir.bound)" = "true" ] && CERT_DIR_FLAG="--cert-dir=$(workspaces.sslcertdir.path)" + [ "$(workspaces.dockerconfig.bound)" = "true" ] && DOCKER_CONFIG="$(workspaces.dockerconfig.path)" && export DOCKER_CONFIG + # build the image (CERT_DIR_FLAG should be omitted if empty and BUILD_EXTRA_ARGS can contain multiple args) + # shellcheck disable=SC2046,SC2086 + buildah ${CERT_DIR_FLAG} "--storage-driver=${PARAM_STORAGE_DRIVER}" bud "${BUILD_ARGS[@]}" ${PARAM_BUILD_EXTRA_ARGS} \ + "--format=${PARAM_FORMAT}" "--tls-verify=${PARAM_TLSVERIFY}" \ + -f "${PARAM_DOCKERFILE}" -t "${PARAM_IMAGE}" "${PARAM_CONTEXT}" + [ "${PARAM_SKIP_PUSH}" = "true" ] && echo "Push skipped" && exit 0 + # push the image (CERT_DIR_FLAG should be omitted if empty and PUSH_EXTRA_ARGS can contain multiple args) + # shellcheck disable=SC2046,SC2086 + buildah ${CERT_DIR_FLAG} "--storage-driver=${PARAM_STORAGE_DRIVER}" push ${PARAM_PUSH_EXTRA_ARGS} \ + "--tls-verify=${PARAM_TLSVERIFY}" --digestfile /tmp/image-digest "${PARAM_IMAGE}" \ + "docker://${PARAM_IMAGE}" + tee "$(results.IMAGE_DIGEST.path)" < /tmp/image-digest + printf '%s' "${PARAM_IMAGE}" | tee "$(results.IMAGE_URL.path)" + volumeMounts: + - name: varlibcontainers + mountPath: /var/lib/containers + securityContext: + privileged: true + volumes: + - name: varlibcontainers + emptyDir: {} diff --git a/task/buildah/0.8/samples/dockerconfig.yaml b/task/buildah/0.8/samples/dockerconfig.yaml new file mode 100644 index 00000000..9002eb52 --- /dev/null +++ b/task/buildah/0.8/samples/dockerconfig.yaml @@ -0,0 +1,67 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: dockerconfig-secret +stringData: + config.json: | + { + "auths" : { + "icr.io" : { + "auth" : "iamapikey", + "identitytoken" : "test123test123" + } + } + } +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: buildah-test-pipeline-run +spec: + pipelineSpec: + workspaces: + - name: shared-workspace + - name: sslcertdir + optional: true + - name: dockerconfig-ws + optional: true + tasks: + - name: fetch-repository + taskRef: + name: git-clone + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: https://github.com/sclorg/nodejs-ex + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + - name: buildah + taskRef: + name: buildah + runAfter: + - fetch-repository + workspaces: + - name: source + workspace: shared-workspace + - name: dockerconfig + workspace: dockerconfig-ws + params: + - name: IMAGE + value: + workspaces: + - name: shared-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi + - name: dockerconfig-ws + secret: + secretName: dockerconfig-secret diff --git a/task/buildah/0.8/samples/openshift-internal-registry.yaml b/task/buildah/0.8/samples/openshift-internal-registry.yaml new file mode 100644 index 00000000..491406b8 --- /dev/null +++ b/task/buildah/0.8/samples/openshift-internal-registry.yaml @@ -0,0 +1,87 @@ +# Your custom CA, on OpenShift to be able to get the internal registry custom +# certificates you can just import it to your namespace with : +# oc get configmaps \ +# -n openshift-controller-manager openshift-service-ca -o yaml | \ +# sed '/namespace/d'|kubectl apply -f- +--- +kind: ConfigMap +metadata: + name: openshift-service-ca +apiVersion: v1 +data: + service-ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDUTCCAjmgAwIB................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + ................................................................ + .................................................... + -----END CERTIFICATE----- +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + generateName: buildah-custom-ca- +spec: + workspaces: + - name: shared-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + # Make sure the path ends up as ca.crt or buildah would not be able to find + # it. + - name: sslcertdir + configMap: + name: openshift-service-ca + defaultMode: 420 + items: + - key: service-ca.crt + path: ca.crt + namespace: openshift-controller-manager + pipelineSpec: + workspaces: + - name: shared-workspace + - name: sslcertdir + optional: true + tasks: + - name: fetch-repository + taskRef: + name: git-clone + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: https://github.com/kelseyhightower/nocode + - name: buildah + taskRef: + name: buildah + runAfter: + - fetch-repository + workspaces: + - name: source + workspace: shared-workspace + - name: sslcertdir + workspace: sslcertdir + params: + # This will push to the openshift internal registry + - name: IMAGE + value: image-registry.openshift-image-registry.svc:5000/$(context.pipelineRun.namespace)/$(context.pipelineRun.name) diff --git a/task/buildah/0.8/tests/internal-registry/internal-registry.yaml b/task/buildah/0.8/tests/internal-registry/internal-registry.yaml new file mode 100644 index 00000000..7fc6f7d1 --- /dev/null +++ b/task/buildah/0.8/tests/internal-registry/internal-registry.yaml @@ -0,0 +1,50 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: registry +spec: + selector: + matchLabels: + run: registry + replicas: 1 + template: + metadata: + labels: + run: registry + spec: + containers: + - name: registry + image: docker.io/registry:2 + ports: + - containerPort: 5000 + volumeMounts: + - name: sslcert + mountPath: /certs + env: + - name: REGISTRY_HTTP_TLS_CERTIFICATE + value: "/certs/ca.crt" + - name: REGISTRY_HTTP_TLS_KEY + value: "/certs/ca.key" + - name: REGISTRY_HTTP_SECRET + value: "tekton" + volumes: + - name: sslcert + configMap: + defaultMode: 420 + items: + - key: ca.crt + path: ca.crt + - key: ca.key + path: ca.key + name: sslcert +--- +apiVersion: v1 +kind: Service +metadata: + name: registry +spec: + ports: + - port: 5000 + selector: + run: registry diff --git a/task/buildah/0.8/tests/pre-apply-task-hook.sh b/task/buildah/0.8/tests/pre-apply-task-hook.sh new file mode 100755 index 00000000..3e061a90 --- /dev/null +++ b/task/buildah/0.8/tests/pre-apply-task-hook.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +add_sidecar_secure_registry + +# Add git-clone +add_task git-clone latest diff --git a/task/buildah/0.8/tests/run.yaml b/task/buildah/0.8/tests/run.yaml new file mode 100644 index 00000000..cf48756f --- /dev/null +++ b/task/buildah/0.8/tests/run.yaml @@ -0,0 +1,126 @@ +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: buildah-test-pipeline-run +spec: + pipelineSpec: + workspaces: + - name: shared-workspace + - name: sslcertdir + optional: true + tasks: + - name: fetch-repository + taskRef: + name: git-clone + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: https://github.com/kelseyhightower/nocode + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + - name: buildah + taskRef: + name: buildah + runAfter: + - fetch-repository + workspaces: + - name: source + workspace: shared-workspace + - name: sslcertdir + workspace: sslcertdir + params: + - name: IMAGE + value: registry:5000/nocode + - name: test-buildah-results + params: + - name: OUTPUT_IMAGE + value: "$(tasks.buildah.results.IMAGE_URL)" + - name: ORIGINAL_IMAGE + value: registry:5000/nocode + taskSpec: + params: + - name: ORIGINAL_IMAGE + - name: OUTPUT_IMAGE + steps: + - name: evaluate + image: alpine + script: | + #!/usr/bin/env sh + [[ "$(params.ORIGINAL_IMAGE)" = "$(params.OUTPUT_IMAGE)" ]] && exit 0 || exit 1 + workspaces: + - name: shared-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Mi + - name: sslcertdir + configMap: + name: sslcert + defaultMode: 420 + items: + - key: ca.crt + path: ca.crt +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: buildah-test-skip-push-pipeline-run +spec: + pipelineSpec: + workspaces: + - name: shared-workspace + - name: sslcertdir + optional: true + tasks: + - name: fetch-repository + taskRef: + name: git-clone + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: https://github.com/kelseyhightower/nocode + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + - name: buildah + taskRef: + name: buildah + runAfter: + - fetch-repository + workspaces: + - name: source + workspace: shared-workspace + - name: sslcertdir + workspace: sslcertdir + params: + - name: IMAGE + value: registry:5000/nocode + - name: SKIP_PUSH + value: "true" + workspaces: + - name: shared-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Mi + - name: sslcertdir + configMap: + name: sslcert + defaultMode: 420 + items: + - key: ca.crt + path: ca.crt