Nicolas Massé 6 months ago
parent
commit
876a9155a1
  1. 86
      tekton/README.md
  2. 26
      tekton/common/daemonset-qemu.yaml
  3. 6
      tekton/common/kustomization.yaml
  4. 32
      tekton/common/serviceaccount-buildbot.yaml
  5. 25
      tekton/common/storage.yaml
  6. 89
      tekton/common/task-buildah-bootc.yaml
  7. 242
      tekton/common/task-git-clone.yaml
  8. 62
      tekton/pipeline.yaml
  9. 39
      tekton/pipelinerun.yaml

86
tekton/README.md

@ -0,0 +1,86 @@
# Multi-architecture Tekton Pipeline
## Tekton configuration
```sh
oc patch configmap/feature-flags -n openshift-pipelines --type=merge -p '{"data":{"disable-affinity-assistant":"true"}}'
```
## Pipeline manifests
```sh
oc apply -k common/
oc apply -f pipeline.yaml
```
## Authentication to the registries
```sh
export REGISTRY_AUTH_FILE="$PWD/auth.json"
podman login quay.io
podman login registry.redhat.io
oc apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
annotations:
tekton.dev/docker-0: https://quay.io
name: registry-authentication
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: $(base64 -w0 "$PWD/auth.json")
EOF
```
## Initialize data inside the PVC
Create a Pod that uses the two previously created PVC :
```yaml
apiVersion: v1
kind: Pod
metadata:
name: rsync
labels:
app: rsync
spec:
containers:
- name: rsync
image: registry.redhat.io/ubi9/ubi:9.6
command: ["/bin/sleep"]
args: ["INF"]
volumeMounts:
- name: bootc-caches
mountPath: /caches
- name: bootc-entitlements
mountPath: /entitlements
volumes:
- name: bootc-caches
persistentVolumeClaim:
claimName: bootc-caches
- name: bootc-entitlements
persistentVolumeClaim:
claimName: bootc-entitlements
```
Then copy all the data to `/caches` and `/entitlements`.
```sh
mkdir -p entitlements
cp etc-x86_64.tar entitlements/x86_64.tar
cp etc-aarch64.tar entitlements/aarch64.tar
oc rsync entitlements rsync:/
oc rsh rsync mkdir -p /caches/{x86_64,aarch64}/{rpm-ostree,dnf}
```
You can leave the Pod running or delete it with :
```sh
oc delete pod rsync
```
## Run it!
```sh
oc create -f pipelinerun.yaml
```

26
tekton/common/daemonset-qemu.yaml

@ -0,0 +1,26 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: multiarch-qemu
spec:
selector:
matchLabels:
name: multiarch-qemu
template:
metadata:
labels:
name: multiarch-qemu
spec:
# The service account must have SCC "privileged"
serviceAccountName: buildbot
nodeSelector:
# foo: bar
containers:
- name: multiarch-qemu
image: docker.io/multiarch/qemu-user-static:7.2.0-1
command:
- /bin/sh
- -c
- /register --reset --persistent yes && sleep INF
securityContext:
privileged: true

6
tekton/common/kustomization.yaml

@ -0,0 +1,6 @@
resources:
- serviceaccount-buildbot.yaml
- task-buildah-bootc.yaml
- task-git-clone.yaml
- daemonset-qemu.yaml
- storage.yaml

32
tekton/common/serviceaccount-buildbot.yaml

@ -0,0 +1,32 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: buildbot
imagePullSecrets:
- name: registry-authentication
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: buildbot-scc
rules:
- apiGroups:
- security.openshift.io
resourceNames:
- privileged
resources:
- securitycontextconstraints
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: buildbot-scc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: buildbot-scc
subjects:
- kind: ServiceAccount
name: buildbot

25
tekton/common/storage.yaml

@ -0,0 +1,25 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bootc-caches
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
volumeMode: Filesystem
storageClassName: efs-csi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bootc-entitlements
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
volumeMode: Filesystem
storageClassName: efs-csi

89
tekton/common/task-buildah-bootc.yaml

@ -0,0 +1,89 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: buildah-bootc
spec:
params:
- name: context-dir
type: string
default: .
- name: containerfile-path
type: string
default: Containerfile
- name: image-name
type: string
workspaces:
- name: source-workspace
description: Workspace containing source code
- name: caches
description: RW storage to cache build artefacts
mountPath: /caches
- name: entitlements
description: RW storage for RHEL entitlements
mountPath: /entitlements
- 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 or .dockerconfigjson.
name: dockerconfig
optional: true
mountPath: /auth
volumes:
- name: container-storage
emptyDir: {}
steps:
- name: build
image: registry.redhat.io/rhel9/buildah:9.6
env:
- name: STORAGE_DRIVER
value: overlay
- name: RHEL_IMAGE
value: registry.redhat.io/rhel9/rhel-bootc
- name: RHEL_VERSION
value: "9.4"
- name: TARGET_IMAGE
value: "$(params.image-name)"
- name: REGISTRY_AUTH_FILE
value: /auth/.dockerconfigjson
script: |
#!/bin/bash
set -Eeuo pipefail
# All architectures to build for
declare -a ARCHITECTURES=("x86_64" "aarch64")
# Build images
declare -A PODMAN_ARCH_OPTS=(["aarch64"]="--platform linux/arm64/v8" ["x86_64"]="--platform linux/amd64")
for arch in "${ARCHITECTURES[@]}"; do
buildah pull ${PODMAN_ARCH_OPTS[$arch]} $RHEL_IMAGE:$RHEL_VERSION
buildah tag $RHEL_IMAGE:$RHEL_VERSION $RHEL_IMAGE-$arch:$RHEL_VERSION
buildah rmi $RHEL_IMAGE:$RHEL_VERSION
echo "Building image for $arch..."
mkdir -p /tmp/entitlements
tar -xf /entitlements/$arch.tar -C /tmp/entitlements
buildah bud ${PODMAN_ARCH_OPTS[$arch]} --no-cache --from "$RHEL_IMAGE-$arch:$RHEL_VERSION" \
-v /tmp/entitlements/etc/pki/entitlement/:/etc/pki/entitlement:z -v /tmp/entitlements/etc/rhsm:/etc/rhsm:z \
-v /tmp/entitlements/etc/pki/entitlement/:/run/secrets/etc-pki-entitlement:z -v /tmp/entitlements/etc/rhsm:/run/secrets/rhsm:z \
-v /tmp/entitlements/etc/yum.repos.d:/etc/yum.repos.d:z -v /caches/$arch/dnf:/var/cache/dnf:z \
-v /caches/$arch/rpm-ostree:/var/cache/rpm-ostree:z \
-t localhost/image-$arch \
-f $(workspaces.source-workspace.path)/$(params.containerfile-path) \
$(workspaces.source-workspace.path)/$(params.context-dir)
done
# Push Manifest
echo "Pushing to $TARGET_IMAGE..."
buildah manifest create localhost/image
for arch in "${ARCHITECTURES[@]}"; do
buildah manifest add localhost/image localhost/image-$arch
done
buildah manifest push localhost/image $TARGET_IMAGE
securityContext:
## Buildah needs privileges to use the "overlay" Storage Driver.
privileged: true
## The "vfs" Storage Driver however requires less privileges.
#capabilities:
# add:
# - SETFCAP
volumeMounts:
- name: container-storage
mountPath: /var/lib/containers

242
tekton/common/task-git-clone.yaml

@ -0,0 +1,242 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: git-clone
labels:
app.kubernetes.io/version: "0.9"
annotations:
tekton.dev/pipelines.minVersion: "0.38.0"
tekton.dev/categories: Git
tekton.dev/tags: git
tekton.dev/displayName: "git clone"
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
spec:
description: >-
These Tasks are Git tasks to work with repositories used by other tasks
in your Pipeline.
The git-clone Task will clone a repo from the provided url into the
output Workspace. By default the repo will be cloned into the root of
your Workspace. You can clone into a subdirectory by setting this Task's
subdirectory param. This Task also supports sparse checkouts. To perform
a sparse checkout, pass a list of comma separated directory patterns to
this Task's sparseCheckoutDirectories param.
workspaces:
- name: output
description: The git repo will be cloned onto the volume backing this Workspace.
- name: ssh-directory
optional: true
description: |
A .ssh directory with private key, known_hosts, config, etc. Copied to
the user's home before git commands are executed. Used to authenticate
with the git remote when performing the clone. Binding a Secret to this
Workspace is strongly recommended over other volume types.
- name: basic-auth
optional: true
description: |
A Workspace containing a .gitconfig and .git-credentials file. These
will be copied to the user's home before any git commands are run. Any
other files in this Workspace are ignored. It is strongly recommended
to use ssh-directory over basic-auth whenever possible and to bind a
Secret to this Workspace over other volume types.
- name: ssl-ca-directory
optional: true
description: |
A workspace containing CA certificates, this will be used by Git to
verify the peer with when fetching or pushing over HTTPS.
params:
- name: url
description: Repository URL to clone from.
type: string
- name: revision
description: Revision to checkout. (branch, tag, sha, ref, etc...)
type: string
default: ""
- name: refspec
description: Refspec to fetch before checking out revision.
default: ""
- name: submodules
description: Initialize and fetch git submodules.
type: string
default: "true"
- name: depth
description: Perform a shallow clone, fetching only the most recent N commits.
type: string
default: "1"
- name: sslVerify
description: Set the `http.sslVerify` global git config. Setting this to `false` is not advised unless you are sure that you trust your git remote.
type: string
default: "true"
- name: crtFileName
description: file name of mounted crt using ssl-ca-directory workspace. default value is ca-bundle.crt.
type: string
default: "ca-bundle.crt"
- name: subdirectory
description: Subdirectory inside the `output` Workspace to clone the repo into.
type: string
default: ""
- name: sparseCheckoutDirectories
description: Define the directory patterns to match or exclude when performing a sparse checkout.
type: string
default: ""
- name: deleteExisting
description: Clean out the contents of the destination directory if it already exists before cloning.
type: string
default: "true"
- name: httpProxy
description: HTTP proxy server for non-SSL requests.
type: string
default: ""
- name: httpsProxy
description: HTTPS proxy server for SSL requests.
type: string
default: ""
- name: noProxy
description: Opt out of proxying HTTP/HTTPS requests.
type: string
default: ""
- name: verbose
description: Log the commands that are executed during `git-clone`'s operation.
type: string
default: "true"
- name: gitInitImage
description: The image providing the git-init binary that this Task runs.
type: string
default: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.40.2"
- name: userHome
description: |
Absolute path to the user's home directory.
type: string
default: "/home/git"
results:
- name: commit
description: The precise commit SHA that was fetched by this Task.
- name: url
description: The precise URL that was fetched by this Task.
- name: committer-date
description: The epoch timestamp of the commit that was fetched by this Task.
steps:
- name: clone
image: "$(params.gitInitImage)"
env:
- name: HOME
value: "$(params.userHome)"
- name: PARAM_URL
value: $(params.url)
- name: PARAM_REVISION
value: $(params.revision)
- name: PARAM_REFSPEC
value: $(params.refspec)
- name: PARAM_SUBMODULES
value: $(params.submodules)
- name: PARAM_DEPTH
value: $(params.depth)
- name: PARAM_SSL_VERIFY
value: $(params.sslVerify)
- name: PARAM_CRT_FILENAME
value: $(params.crtFileName)
- name: PARAM_SUBDIRECTORY
value: $(params.subdirectory)
- name: PARAM_DELETE_EXISTING
value: $(params.deleteExisting)
- name: PARAM_HTTP_PROXY
value: $(params.httpProxy)
- name: PARAM_HTTPS_PROXY
value: $(params.httpsProxy)
- name: PARAM_NO_PROXY
value: $(params.noProxy)
- name: PARAM_VERBOSE
value: $(params.verbose)
- name: PARAM_SPARSE_CHECKOUT_DIRECTORIES
value: $(params.sparseCheckoutDirectories)
- name: PARAM_USER_HOME
value: $(params.userHome)
- name: WORKSPACE_OUTPUT_PATH
value: $(workspaces.output.path)
- name: WORKSPACE_SSH_DIRECTORY_BOUND
value: $(workspaces.ssh-directory.bound)
- name: WORKSPACE_SSH_DIRECTORY_PATH
value: $(workspaces.ssh-directory.path)
- name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND
value: $(workspaces.basic-auth.bound)
- name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH
value: $(workspaces.basic-auth.path)
- name: WORKSPACE_SSL_CA_DIRECTORY_BOUND
value: $(workspaces.ssl-ca-directory.bound)
- name: WORKSPACE_SSL_CA_DIRECTORY_PATH
value: $(workspaces.ssl-ca-directory.path)
securityContext:
runAsNonRoot: false
runAsUser: 0
script: |
#!/usr/bin/env sh
set -eu
if [ "${PARAM_VERBOSE}" = "true" ] ; then
set -x
fi
if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ] ; then
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" "${PARAM_USER_HOME}/.git-credentials"
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" "${PARAM_USER_HOME}/.gitconfig"
chmod 400 "${PARAM_USER_HOME}/.git-credentials"
chmod 400 "${PARAM_USER_HOME}/.gitconfig"
fi
if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then
cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh
chmod 700 "${PARAM_USER_HOME}"/.ssh
chmod -R 400 "${PARAM_USER_HOME}"/.ssh/*
fi
if [ "${WORKSPACE_SSL_CA_DIRECTORY_BOUND}" = "true" ] ; then
export GIT_SSL_CAPATH="${WORKSPACE_SSL_CA_DIRECTORY_PATH}"
if [ "${PARAM_CRT_FILENAME}" != "" ] ; then
export GIT_SSL_CAINFO="${WORKSPACE_SSL_CA_DIRECTORY_PATH}/${PARAM_CRT_FILENAME}"
fi
fi
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf ${CHECKOUT_DIR}" because ${CHECKOUT_DIR} might be "/"
# or the root of a mounted volume.
if [ -d "${CHECKOUT_DIR}" ] ; then
# Delete non-hidden files and directories
rm -rf "${CHECKOUT_DIR:?}"/*
# Delete files and directories starting with . but excluding ..
rm -rf "${CHECKOUT_DIR}"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "${CHECKOUT_DIR}"/..?*
fi
}
if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then
cleandir || true
fi
test -z "${PARAM_HTTP_PROXY}" || export HTTP_PROXY="${PARAM_HTTP_PROXY}"
test -z "${PARAM_HTTPS_PROXY}" || export HTTPS_PROXY="${PARAM_HTTPS_PROXY}"
test -z "${PARAM_NO_PROXY}" || export NO_PROXY="${PARAM_NO_PROXY}"
git config --global --add safe.directory "${WORKSPACE_OUTPUT_PATH}"
/ko-app/git-init \
-url="${PARAM_URL}" \
-revision="${PARAM_REVISION}" \
-refspec="${PARAM_REFSPEC}" \
-path="${CHECKOUT_DIR}" \
-sslVerify="${PARAM_SSL_VERIFY}" \
-submodules="${PARAM_SUBMODULES}" \
-depth="${PARAM_DEPTH}" \
-sparseCheckoutDirectories="${PARAM_SPARSE_CHECKOUT_DIRECTORIES}"
cd "${CHECKOUT_DIR}"
RESULT_SHA="$(git rev-parse HEAD)"
EXIT_CODE="$?"
if [ "${EXIT_CODE}" != 0 ] ; then
exit "${EXIT_CODE}"
fi
RESULT_COMMITTER_DATE="$(git log -1 --pretty=%ct)"
printf "%s" "${RESULT_COMMITTER_DATE}" > "$(results.committer-date.path)"
printf "%s" "${RESULT_SHA}" > "$(results.commit.path)"
printf "%s" "${PARAM_URL}" > "$(results.url.path)"

62
tekton/pipeline.yaml

@ -0,0 +1,62 @@
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: bootc
spec:
workspaces:
- name: source-workspace
- name: registry-token
- name: caches
- name: entitlements
params:
- name: git-url
type: string
- name: git-revision
type: string
default: main
- name: image-name
type: string
- name: context-dir
type: string
default: "."
- name: containerfile-path
type: string
default: "Containerfile"
tasks:
- name: clone-repo
taskRef:
kind: Task
name: git-clone
params:
- name: url
value: $(params.git-url)
- name: revision
value: $(params.git-revision)
workspaces:
- name: output
workspace: source-workspace
- name: buildah-bootc
runAfter: ["clone-repo"]
taskRef:
name: buildah-bootc
params:
- name: image-name
value: $(params.image-name)
- name: context-dir
value: $(params.context-dir)
- name: containerfile-path
value: $(params.containerfile-path)
workspaces:
- name: source-workspace
workspace: source-workspace
- name: dockerconfig
workspace: registry-token
- name: caches
workspace: caches
- name: entitlements
workspace: entitlements

39
tekton/pipelinerun.yaml

@ -0,0 +1,39 @@
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: bootc-
spec:
pipelineRef:
name: bootc
params:
- name: git-url
value: https://github.com/nmasse-itix/bootc-edge-ai.git
- name: git-revision
value: main
- name: image-name
value: quay.io/nmasse-redhat/bootc-edge-ai
- name: context-dir
value: bootc
- name: containerfile-path
value: "bootc/Containerfile"
workspaces:
- name: caches
persistentVolumeClaim:
claimName: bootc-caches
- name: entitlements
persistentVolumeClaim:
claimName: bootc-entitlements
- name: source-workspace
volumeClaimTemplate:
spec:
storageClassName: efs-csi
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
- name: registry-token
secret:
secretName: registry-authentication
taskRunTemplate:
serviceAccountName: buildbot
Loading…
Cancel
Save