From bf4fbf6a3e1c6c824cc90840dec0305a46f23d31 Mon Sep 17 00:00:00 2001 From: arewm Date: Tue, 23 Jul 2024 14:51:37 -0400 Subject: [PATCH] Add an architecture suffix to images pushed for multi-platform In order to reduce the likelihood of users accidentally forgetting to specify unique tags for each architecture, we can add a suffix to the pushed image if an arch-specific one doesn't exist. Signed-off-by: arewm --- hack/generate-buildah-remote.sh | 4 +- task-generator/remote/main.go | 47 +++++++++++++++---- .../0.1/build-image-manifest.yaml | 2 +- task/buildah-oci-ta/0.2/buildah-oci-ta.yaml | 20 ++++---- .../0.1/buildah-remote-oci-ta.yaml | 4 +- .../0.2/buildah-remote-oci-ta.yaml | 33 ++++++++----- task/buildah-remote/0.1/buildah-remote.yaml | 4 +- task/buildah-remote/0.2/buildah-remote.yaml | 33 ++++++++----- task/buildah/0.2/buildah.yaml | 20 ++++---- 9 files changed, 111 insertions(+), 56 deletions(-) diff --git a/hack/generate-buildah-remote.sh b/hack/generate-buildah-remote.sh index da061ed821..27ea1fdcfb 100755 --- a/hack/generate-buildah-remote.sh +++ b/hack/generate-buildah-remote.sh @@ -8,7 +8,7 @@ go build -o /tmp/remote-generator ./remote/main.go for version in 0.1 0.2; do /tmp/remote-generator --buildah-task="${SCRIPTDIR}/../task/buildah/${version}/buildah.yaml" \ - --remote-task="${SCRIPTDIR}/../task/buildah-remote/${version}/buildah-remote.yaml" + --remote-task="${SCRIPTDIR}/../task/buildah-remote/${version}/buildah-remote.yaml" --task-version="$version" /tmp/remote-generator --buildah-task="${SCRIPTDIR}/../task/buildah-oci-ta/${version}/buildah-oci-ta.yaml" \ - --remote-task="${SCRIPTDIR}/../task/buildah-remote-oci-ta/${version}/buildah-remote-oci-ta.yaml" + --remote-task="${SCRIPTDIR}/../task/buildah-remote-oci-ta/${version}/buildah-remote-oci-ta.yaml" --task-version="$version" done diff --git a/task-generator/remote/main.go b/task-generator/remote/main.go index d03c0e4359..e8755245b3 100644 --- a/task-generator/remote/main.go +++ b/task-generator/remote/main.go @@ -18,6 +18,7 @@ import ( "flag" "os" "path/filepath" + "regexp" "strings" tektonapi "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" @@ -33,9 +34,11 @@ import ( func main() { var buildahTask string var buildahRemoteTask string + var taskVersion string flag.StringVar(&buildahTask, "buildah-task", "", "The location of the buildah task") flag.StringVar(&buildahRemoteTask, "remote-task", "", "The location of the buildah-remote task to overwrite") + flag.StringVar(&taskVersion, "task-version", "", "The version of the task to overwrite") opts := zap.Options{ Development: true, @@ -43,8 +46,8 @@ func main() { opts.BindFlags(flag.CommandLine) klog.InitFlags(flag.CommandLine) flag.Parse() - if buildahTask == "" || buildahRemoteTask == "" { - println("Must specify both buildah-task and remote-task params") + if buildahTask == "" || buildahRemoteTask == "" || taskVersion == "" { + println("Must specify both buildah-task, remote-task, and task-version params") os.Exit(1) } @@ -53,7 +56,7 @@ func main() { decodingScheme := runtime.NewScheme() utilruntime.Must(tektonapi.AddToScheme(decodingScheme)) - convertToSsh(&task) + convertToSsh(&task, taskVersion) y := printers.YAMLPrinter{} b := bytes.Buffer{} _ = y.PrintObj(&task, &b) @@ -87,7 +90,7 @@ func streamFileYamlToTektonObj(path string, obj runtime.Object) runtime.Object { return decodeBytesToTektonObjbytes(bytes, obj) } -func convertToSsh(task *tektonapi.Task) { +func convertToSsh(task *tektonapi.Task, taskVersion string) { builderImage := "" syncVolumes := map[string]bool{} @@ -96,14 +99,27 @@ func convertToSsh(task *tektonapi.Task) { syncVolumes[i.Name] = true } } + adjustRemoteImage := "if [[ \"${IMAGE##*-}\" != \"${PLATFORM##*/}\" ]]; then" + adjustRemoteImage += "\n export IMAGE=\"${IMAGE}-${PLATFORM##*/}\"\nfi\n" + for stepPod := range task.Spec.Steps { + ret := "" step := &task.Spec.Steps[stepPod] - if step.Name != "build" { + if step.Name == "inject-sbom-and-push" && taskVersion == "0.2" { + scriptHeaderRE := regexp.MustCompile(`#!/bin/bash\nset -e\n`) + if scriptHeaderRE.FindString(step.Script) != "" { + ret = scriptHeaderRE.ReplaceAllString(step.Script, "") + } + step.Script = "#!/bin/bash\nset -e\n" + adjustRemoteImage + "\n" + ret + continue + } else if step.Name != "build" { continue } podmanArgs := "" - ret := `set -o verbose + ret = `#!/bin/bash +set -e +set -o verbose mkdir -p ~/.ssh if [ -e "/ssh/error" ]; then #no server could be provisioned @@ -130,7 +146,9 @@ PORT_FORWARD=" -L 80:$JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR:80" PODMAN_PORT_FORWARD=" -e JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR=localhost" fi ` - + if taskVersion == "0.2" { + ret += adjustRemoteImage + } env := "$PODMAN_PORT_FORWARD \\\n" // disable podman subscription-manager integration @@ -160,9 +178,17 @@ fi script := "scripts/script-" + step.Name + ".sh" ret += "\ncat >" + script + " <<'REMOTESSHEOF'\n" - if !strings.HasPrefix(step.Script, "#!") { - ret += "#!/bin/bash\nset -o verbose\nset -e\n" + + reShebang := regexp.MustCompile(`(#!.*\n)(set -.*\n)*`) + shebangMatch := reShebang.FindStringSubmatch(step.Script) + if shebangMatch != nil && strings.HasPrefix(shebangMatch[0], "#!") { + for _, match := range shebangMatch[1:] { + ret += match + step.Script = strings.TrimPrefix(step.Script, match) + } } + ret += "set -o verbose\n" + if step.WorkingDir != "" { ret += "cd " + step.WorkingDir + "\n" } @@ -229,4 +255,7 @@ fi }, }) task.Spec.StepTemplate.Env = append(task.Spec.StepTemplate.Env, v1.EnvVar{Name: "BUILDER_IMAGE", Value: builderImage}) + if taskVersion == "0.2" { + task.Spec.StepTemplate.Env = append(task.Spec.StepTemplate.Env, v1.EnvVar{Name: "PLATFORM", Value: "$(params.PLATFORM)"}) + } } diff --git a/task/build-image-manifest/0.1/build-image-manifest.yaml b/task/build-image-manifest/0.1/build-image-manifest.yaml index e0d1a08cd7..273c82b98d 100644 --- a/task/build-image-manifest/0.1/build-image-manifest.yaml +++ b/task/build-image-manifest/0.1/build-image-manifest.yaml @@ -62,7 +62,7 @@ spec: requests: memory: 512Mi cpu: 250m - args: ["$(params.IMAGES[*])"] + args: ["$(params.IMAGES)"] script: | #!/bin/bash # Fixing group permission on /var/lib/containers diff --git a/task/buildah-oci-ta/0.2/buildah-oci-ta.yaml b/task/buildah-oci-ta/0.2/buildah-oci-ta.yaml index 92f9c295e7..52e4bbb60f 100644 --- a/task/buildah-oci-ta/0.2/buildah-oci-ta.yaml +++ b/task/buildah-oci-ta/0.2/buildah-oci-ta.yaml @@ -242,6 +242,8 @@ spec: - name: COMMIT_SHA value: $(params.COMMIT_SHA) script: | + #!/bin/bash + set -e ca_bundle=/mnt/trusted-ca/ca-bundle.crt if [ -f "$ca_bundle" ]; then echo "INFO: Using mounted CA bundle: $ca_bundle" @@ -533,6 +535,8 @@ spec: volumeMounts: - mountPath: /var/lib/containers name: varlibcontainers + - mountPath: /shared + name: shared script: | #!/bin/bash set -e @@ -572,6 +576,7 @@ spec: echo -n "${IMAGE}@" cat "/var/workdir/image-digest" } >"$(results.IMAGE_REF.path)" + cp "$(results.IMAGE_REF.path)" /shared/image_ref # Remove tag from IMAGE while allowing registry to contain a port number. sbom_repo="${IMAGE%:*}" @@ -584,13 +589,10 @@ spec: - SETFCAP runAsUser: 0 - name: upload-sbom - image: quay.io/redhat-appstudio/cosign:v2.1.1@sha256:c883d6f8d39148f2cea71bff4622d196d89df3e510f36c140c097b932f0dd5d5 - args: - - attach - - sbom - - --sbom - - sbom-cyclonedx.json - - --type - - cyclonedx - - $(params.IMAGE) + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 workingDir: /var/workdir + volumeMounts: + - mountPath: /shared + name: shared + script: | + cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat /shared/image_ref)" diff --git a/task/buildah-remote-oci-ta/0.1/buildah-remote-oci-ta.yaml b/task/buildah-remote-oci-ta/0.1/buildah-remote-oci-ta.yaml index fe3f2e4405..edd22e25a4 100644 --- a/task/buildah-remote-oci-ta/0.1/buildah-remote-oci-ta.yaml +++ b/task/buildah-remote-oci-ta/0.1/buildah-remote-oci-ta.yaml @@ -214,6 +214,8 @@ spec: image: quay.io/redhat-appstudio/multi-platform-runner:01c7670e81d5120347cf0ad13372742489985e5f@sha256:246adeaaba600e207131d63a7f706cffdcdc37d8f600c56187123ec62823ff44 name: build script: |- + #!/bin/bash + set -e set -o verbose mkdir -p ~/.ssh if [ -e "/ssh/error" ]; then @@ -250,9 +252,7 @@ spec: rsync -ra "$HOME/.docker/" "$SSH_HOST:$BUILD_DIR/.docker/" rsync -ra "/tekton/results/" "$SSH_HOST:$BUILD_DIR/tekton-results/" cat >scripts/script-build.sh <<'REMOTESSHEOF' - #!/bin/bash set -o verbose - set -e cd /var/workdir ca_bundle=/mnt/trusted-ca/ca-bundle.crt if [ -f "$ca_bundle" ]; then diff --git a/task/buildah-remote-oci-ta/0.2/buildah-remote-oci-ta.yaml b/task/buildah-remote-oci-ta/0.2/buildah-remote-oci-ta.yaml index 6db39a03ca..3160fcbd5d 100644 --- a/task/buildah-remote-oci-ta/0.2/buildah-remote-oci-ta.yaml +++ b/task/buildah-remote-oci-ta/0.2/buildah-remote-oci-ta.yaml @@ -187,6 +187,8 @@ spec: value: $(params.YUM_REPOS_D_TARGET) - name: BUILDER_IMAGE value: quay.io/konflux-ci/buildah:latest@sha256:9ef792d74bcc1d330de6be58b61f2cdbfa1c23b74a291eb2136ffd452d373050 + - name: PLATFORM + value: $(params.PLATFORM) volumeMounts: - mountPath: /shared name: shared @@ -214,6 +216,8 @@ spec: image: quay.io/redhat-appstudio/multi-platform-runner:01c7670e81d5120347cf0ad13372742489985e5f@sha256:246adeaaba600e207131d63a7f706cffdcdc37d8f600c56187123ec62823ff44 name: build script: |- + #!/bin/bash + set -e set -o verbose mkdir -p ~/.ssh if [ -e "/ssh/error" ]; then @@ -240,6 +244,9 @@ spec: PORT_FORWARD=" -L 80:$JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR:80" PODMAN_PORT_FORWARD=" -e JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR=localhost" fi + if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then + export IMAGE="${IMAGE}-${PLATFORM##*/}" + fi rsync -ra /shared/ "$SSH_HOST:$BUILD_DIR/volumes/shared/" rsync -ra /var/workdir/ "$SSH_HOST:$BUILD_DIR/volumes/workdir/" @@ -251,8 +258,8 @@ spec: rsync -ra "/tekton/results/" "$SSH_HOST:$BUILD_DIR/tekton-results/" cat >scripts/script-build.sh <<'REMOTESSHEOF' #!/bin/bash - set -o verbose set -e + set -o verbose cd /var/workdir ca_bundle=/mnt/trusted-ca/ca-bundle.crt if [ -f "$ca_bundle" ]; then @@ -607,6 +614,10 @@ spec: script: | #!/bin/bash set -e + if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then + export IMAGE="${IMAGE}-${PLATFORM##*/}" + fi + base_image_name=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.name"}}' $IMAGE | cut -f1 -d'@') base_image_digest=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.digest"}}' $IMAGE) container=$(buildah from --pull-never $IMAGE) @@ -643,6 +654,7 @@ spec: echo -n "${IMAGE}@" cat "/var/workdir/image-digest" } >"$(results.IMAGE_REF.path)" + cp "$(results.IMAGE_REF.path)" /shared/image_ref # Remove tag from IMAGE while allowing registry to contain a port number. sbom_repo="${IMAGE%:*}" @@ -657,18 +669,17 @@ spec: volumeMounts: - mountPath: /var/lib/containers name: varlibcontainers + - mountPath: /shared + name: shared workingDir: /var/workdir - - args: - - attach - - sbom - - --sbom - - sbom-cyclonedx.json - - --type - - cyclonedx - - $(params.IMAGE) - computeResources: {} - image: quay.io/redhat-appstudio/cosign:v2.1.1@sha256:c883d6f8d39148f2cea71bff4622d196d89df3e510f36c140c097b932f0dd5d5 + - computeResources: {} + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 name: upload-sbom + script: | + cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat /shared/image_ref)" + volumeMounts: + - mountPath: /shared + name: shared workingDir: /var/workdir volumes: - name: activation-key diff --git a/task/buildah-remote/0.1/buildah-remote.yaml b/task/buildah-remote/0.1/buildah-remote.yaml index b81d15e982..87f38555b1 100644 --- a/task/buildah-remote/0.1/buildah-remote.yaml +++ b/task/buildah-remote/0.1/buildah-remote.yaml @@ -202,6 +202,8 @@ spec: image: quay.io/redhat-appstudio/multi-platform-runner:01c7670e81d5120347cf0ad13372742489985e5f@sha256:246adeaaba600e207131d63a7f706cffdcdc37d8f600c56187123ec62823ff44 name: build script: |- + #!/bin/bash + set -e set -o verbose mkdir -p ~/.ssh if [ -e "/ssh/error" ]; then @@ -238,9 +240,7 @@ spec: rsync -ra "$HOME/.docker/" "$SSH_HOST:$BUILD_DIR/.docker/" rsync -ra "/tekton/results/" "$SSH_HOST:$BUILD_DIR/tekton-results/" cat >scripts/script-build.sh <<'REMOTESSHEOF' - #!/bin/bash set -o verbose - set -e cd $(workspaces.source.path) if [ -n "${PARAM_BUILDER_IMAGE}" ]; then echo "WARNING: provided deprecated BUILDER_IMAGE parameter has no effect." diff --git a/task/buildah-remote/0.2/buildah-remote.yaml b/task/buildah-remote/0.2/buildah-remote.yaml index f23ebb69c9..92e11e9d27 100644 --- a/task/buildah-remote/0.2/buildah-remote.yaml +++ b/task/buildah-remote/0.2/buildah-remote.yaml @@ -178,6 +178,8 @@ spec: value: $(params.SKIP_UNUSED_STAGES) - name: BUILDER_IMAGE value: quay.io/konflux-ci/buildah:latest@sha256:9ef792d74bcc1d330de6be58b61f2cdbfa1c23b74a291eb2136ffd452d373050 + - name: PLATFORM + value: $(params.PLATFORM) volumeMounts: - mountPath: /shared name: shared @@ -196,6 +198,8 @@ spec: image: quay.io/redhat-appstudio/multi-platform-runner:01c7670e81d5120347cf0ad13372742489985e5f@sha256:246adeaaba600e207131d63a7f706cffdcdc37d8f600c56187123ec62823ff44 name: build script: |- + #!/bin/bash + set -e set -o verbose mkdir -p ~/.ssh if [ -e "/ssh/error" ]; then @@ -222,6 +226,9 @@ spec: PORT_FORWARD=" -L 80:$JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR:80" PODMAN_PORT_FORWARD=" -e JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR=localhost" fi + if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then + export IMAGE="${IMAGE}-${PLATFORM##*/}" + fi rsync -ra $(workspaces.source.path)/ "$SSH_HOST:$BUILD_DIR/workspaces/source/" rsync -ra /shared/ "$SSH_HOST:$BUILD_DIR/volumes/shared/" @@ -233,8 +240,8 @@ spec: rsync -ra "/tekton/results/" "$SSH_HOST:$BUILD_DIR/tekton-results/" cat >scripts/script-build.sh <<'REMOTESSHEOF' #!/bin/bash - set -o verbose set -e + set -o verbose cd $(workspaces.source.path) ca_bundle=/mnt/trusted-ca/ca-bundle.crt if [ -f "$ca_bundle" ]; then @@ -589,6 +596,10 @@ spec: script: | #!/bin/bash set -e + if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then + export IMAGE="${IMAGE}-${PLATFORM##*/}" + fi + base_image_name=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.name"}}' $IMAGE | cut -f1 -d'@') base_image_digest=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.digest"}}' $IMAGE) container=$(buildah from --pull-never $IMAGE) @@ -625,6 +636,7 @@ spec: echo -n "${IMAGE}@" cat "$(workspaces.source.path)/image-digest" } > "$(results.IMAGE_REF.path)" + cp "$(results.IMAGE_REF.path)" /shared/image_ref # Remove tag from IMAGE while allowing registry to contain a port number. sbom_repo="${IMAGE%:*}" @@ -639,18 +651,17 @@ spec: volumeMounts: - mountPath: /var/lib/containers name: varlibcontainers + - mountPath: /shared + name: shared workingDir: $(workspaces.source.path) - - args: - - attach - - sbom - - --sbom - - sbom-cyclonedx.json - - --type - - cyclonedx - - $(params.IMAGE) - computeResources: {} - image: quay.io/redhat-appstudio/cosign:v2.1.1@sha256:c883d6f8d39148f2cea71bff4622d196d89df3e510f36c140c097b932f0dd5d5 + - computeResources: {} + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 name: upload-sbom + script: | + cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat /shared/image_ref)" + volumeMounts: + - mountPath: /shared + name: shared workingDir: $(workspaces.source.path) volumes: - emptyDir: {} diff --git a/task/buildah/0.2/buildah.yaml b/task/buildah/0.2/buildah.yaml index 425ec93ae7..082dd014f9 100644 --- a/task/buildah/0.2/buildah.yaml +++ b/task/buildah/0.2/buildah.yaml @@ -178,6 +178,8 @@ spec: args: - $(params.BUILD_ARGS[*]) script: | + #!/bin/bash + set -e ca_bundle=/mnt/trusted-ca/ca-bundle.crt if [ -f "$ca_bundle" ]; then echo "INFO: Using mounted CA bundle: $ca_bundle" @@ -521,6 +523,7 @@ spec: echo -n "${IMAGE}@" cat "$(workspaces.source.path)/image-digest" } > "$(results.IMAGE_REF.path)" + cp "$(results.IMAGE_REF.path)" /shared/image_ref # Remove tag from IMAGE while allowing registry to contain a port number. sbom_repo="${IMAGE%:*}" @@ -535,18 +538,17 @@ spec: volumeMounts: - mountPath: /var/lib/containers name: varlibcontainers + - mountPath: /shared + name: shared workingDir: $(workspaces.source.path) - name: upload-sbom - image: quay.io/redhat-appstudio/cosign:v2.1.1@sha256:c883d6f8d39148f2cea71bff4622d196d89df3e510f36c140c097b932f0dd5d5 - args: - - attach - - sbom - - --sbom - - sbom-cyclonedx.json - - --type - - cyclonedx - - $(params.IMAGE) + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 + script: | + cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat /shared/image_ref)" + volumeMounts: + - mountPath: /shared + name: shared workingDir: $(workspaces.source.path) volumes: