Skip to content

Commit

Permalink
Add an architecture suffix to images pushed for multi-platform
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
arewm committed Aug 12, 2024
1 parent a6e5d9e commit 420bc92
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 58 deletions.
4 changes: 2 additions & 2 deletions hack/generate-buildah-remote.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
64 changes: 56 additions & 8 deletions task-generator/remote/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"flag"
"os"
"path/filepath"
"regexp"
"strings"

tektonapi "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
Expand All @@ -33,18 +34,20 @@ 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,
}
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)
}

Expand All @@ -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)
Expand Down Expand Up @@ -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{}
Expand All @@ -96,14 +99,44 @@ func convertToSsh(task *tektonapi.Task) {
syncVolumes[i.Name] = true
}
}
// The images produced in multi-platform builds need to have unique tags in order
// to prevent them from getting garbage collected before generating the image index.
// We can simplify this process, preventing the need for users to manually specify
// the image by auto-appending the architecture from the PLATFORM parameter. For
// example, this will append -arm64 if PLATFORM is linux/arm64 if not present. Since
// we cannot modify the parameter itself, this replacement needs to happen in any task
// step where the IMAGE parameter is used.
// If a user defines the IMAGE parameter with an -arm64 suffix, the arm64 suffix will
// not be appended again based on the PLATFORM.
adjustRemoteImage := `if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then
export IMAGE="${IMAGE}-${PLATFORM##*/}"
fi
`

for stepPod := range task.Spec.Steps {
ret := ""
step := &task.Spec.Steps[stepPod]
if step.Name != "build" {
if step.Script != "" && taskVersion != "0.1" && step.Name != "build" {
scriptHeaderRE := regexp.MustCompile(`^#!/bin/bash\nset -e\n`)
if scriptHeaderRE.FindString(step.Script) != "" {
ret = scriptHeaderRE.ReplaceAllString(step.Script, "")
} else {
ret = step.Script
}
if !strings.HasPrefix(ret, "#!") {
// If there is a shebang, it is explicitly non-bash, so don't adjust the image
ret = "#!/bin/bash\nset -e\n" + adjustRemoteImage + ret
}
step.Script = 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
Expand All @@ -130,7 +163,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.1" {
ret += adjustRemoteImage
}
env := "$PODMAN_PORT_FORWARD \\\n"

// disable podman subscription-manager integration
Expand Down Expand Up @@ -160,9 +195,19 @@ fi
script := "scripts/script-" + step.Name + ".sh"

ret += "\ncat >" + script + " <<'REMOTESSHEOF'\n"
if !strings.HasPrefix(step.Script, "#!") {

// The base task might now be using a bash shell, so we need to make sure
// that we only have one shebang declaration. If there is a shebang declaration,
// we should also consolidate the set declarations.
reShebang := regexp.MustCompile(`(#!.*\n)(set -.*\n)*`)
shebangMatch := reShebang.FindString(step.Script)
if shebangMatch != "" {
ret += shebangMatch
step.Script = strings.TrimPrefix(step.Script, shebangMatch)
} else {
ret += "#!/bin/bash\nset -o verbose\nset -e\n"
}

if step.WorkingDir != "" {
ret += "cd " + step.WorkingDir + "\n"
}
Expand Down Expand Up @@ -229,4 +274,7 @@ fi
},
})
task.Spec.StepTemplate.Env = append(task.Spec.StepTemplate.Env, v1.EnvVar{Name: "BUILDER_IMAGE", Value: builderImage})
if taskVersion != "0.1" {
task.Spec.StepTemplate.Env = append(task.Spec.StepTemplate.Env, v1.EnvVar{Name: "PLATFORM", Value: "$(params.PLATFORM)"})
}
}
24 changes: 13 additions & 11 deletions task/buildah-oci-ta/0.2/buildah-oci-ta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -600,18 +602,18 @@ 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: /etc/ssl/certs/ca-bundle.crt
- mountPath: /mnt/trusted-ca
name: trusted-ca
readOnly: true
subPath: ca-bundle.crt
script: |
ca_bundle=/mnt/trusted-ca/ca-bundle.crt
if [ -f "$ca_bundle" ]; then
echo "INFO: Using mounted CA bundle: $ca_bundle"
cp -vf $ca_bundle /etc/pki/ca-trust/source/anchors
update-ca-trust
fi
cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat "$(results.IMAGE_REF.path)")"
2 changes: 2 additions & 0 deletions task/buildah-remote-oci-ta/0.1/buildah-remote-oci-ta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,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
Expand Down
60 changes: 47 additions & 13 deletions task/buildah-remote-oci-ta/0.2/buildah-remote-oci-ta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ spec:
value: $(params.YUM_REPOS_D_TARGET)
- name: BUILDER_IMAGE
value: quay.io/konflux-ci/buildah:latest@sha256:7cb5a35b7fe44e397fbf3b834f3bd8dcd9403a7c0a0b51469e6ec75b107d0846
- name: PLATFORM
value: $(params.PLATFORM)
volumeMounts:
- mountPath: /shared
name: shared
Expand Down Expand Up @@ -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
Expand All @@ -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/"
Expand All @@ -251,7 +258,6 @@ spec:
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
Expand Down Expand Up @@ -500,6 +506,11 @@ spec:
image: quay.io/redhat-appstudio/syft:v0.105.1@sha256:1910b829997650c696881e5fc2fc654ddf3184c27edb1b2024e9cb2ba51ac431
name: sbom-syft-generate
script: |
#!/bin/bash
set -e
if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then
export IMAGE="${IMAGE}-${PLATFORM##*/}"
fi
echo "Running syft on the source directory"
syft dir:/var/workdir/source --output cyclonedx-json=/var/workdir/sbom-source.json
find $(cat /shared/container_path) -xtype l -delete
Expand All @@ -515,6 +526,11 @@ spec:
image: quay.io/redhat-appstudio/hacbs-jvm-build-request-processor:127ee0c223a2b56a9bd20a6f2eaeed3bd6015f77
name: analyse-dependencies-java-sbom
script: |
#!/bin/bash
set -e
if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then
export IMAGE="${IMAGE}-${PLATFORM##*/}"
fi
if [ -f /var/lib/containers/java ]; then
/opt/jboss/container/java/run/run-java.sh analyse-dependencies path $(cat /shared/container_path) -s /var/workdir/sbom-image.json --task-run-name $(context.taskRun.name) --publishers $(results.SBOM_JAVA_COMPONENTS_COUNT.path)
sed -i 's/^/ /' $(results.SBOM_JAVA_COMPONENTS_COUNT.path) # Workaround for SRVKP-2875
Expand Down Expand Up @@ -567,6 +583,11 @@ spec:
image: quay.io/redhat-appstudio/cachi2:0.9.1@sha256:df67f9e063b544a8c49a271359377fed560562615e0278f6d0b9a3485f3f8fad
name: merge-cachi2-sbom
script: |
#!/bin/bash
set -e
if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then
export IMAGE="${IMAGE}-${PLATFORM##*/}"
fi
if [ -f "sbom-cachi2.json" ]; then
echo "Merging contents of sbom-cachi2.json into sbom-cyclonedx.json"
merge_syft_sbom sbom-cachi2.json sbom-cyclonedx.json >sbom-temp.json
Expand Down Expand Up @@ -599,6 +620,11 @@ spec:
image: quay.io/redhat-appstudio/base-images-sbom-script@sha256:667669e3def018f9dbb8eaf8868887a40bc07842221e9a98f6787edcff021840
name: create-base-images-sbom
script: |
#!/bin/bash
set -e
if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then
export IMAGE="${IMAGE}-${PLATFORM##*/}"
fi
python3 /app/base_images_sbom_script.py \
--sbom=sbom-cyclonedx.json \
--base-images-from-dockerfile=/shared/base_images_from_dockerfile \
Expand All @@ -612,6 +638,9 @@ spec:
script: |
#!/bin/bash
set -e
if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then
export IMAGE="${IMAGE}-${PLATFORM##*/}"
fi
ca_bundle=/mnt/trusted-ca/ca-bundle.crt
if [ -f "$ca_bundle" ]; then
Expand Down Expand Up @@ -674,22 +703,27 @@ spec:
name: trusted-ca
readOnly: true
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: |
#!/bin/bash
set -e
if [[ "${IMAGE##*-}" != "${PLATFORM##*/}" ]]; then
export IMAGE="${IMAGE}-${PLATFORM##*/}"
fi
ca_bundle=/mnt/trusted-ca/ca-bundle.crt
if [ -f "$ca_bundle" ]; then
echo "INFO: Using mounted CA bundle: $ca_bundle"
cp -vf $ca_bundle /etc/pki/ca-trust/source/anchors
update-ca-trust
fi
cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat "$(results.IMAGE_REF.path)")"
volumeMounts:
- mountPath: /etc/ssl/certs/ca-bundle.crt
- mountPath: /mnt/trusted-ca
name: trusted-ca
readOnly: true
subPath: ca-bundle.crt
workingDir: /var/workdir
volumes:
- name: activation-key
Expand Down
2 changes: 2 additions & 0 deletions task/buildah-remote/0.1/buildah-remote.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,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
Expand Down
Loading

0 comments on commit 420bc92

Please sign in to comment.