Skip to content

Commit

Permalink
fix(EC-972): Add support for attaching trusted artifacts
Browse files Browse the repository at this point in the history
If trusted artifacts are generated after an image has been built, we can
use oras to attach the artifacts instead of just pushing them to the
same registry location and tag where the image will eventually be
pushed.

Signed-off-by: arewm <[email protected]>
  • Loading branch information
arewm committed Oct 28, 2024
1 parent a809434 commit d903e2f
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 30 deletions.
42 changes: 23 additions & 19 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
FROM scratch AS files

COPY centos9-stream.repo /etc/yum.repos.d/centos9-stream.repo
COPY RPM-GPG-KEY-centosofficial /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
COPY create-oci.sh /usr/local/bin/create-archive
COPY select-oci-auth.sh /usr/local/bin/select-oci-auth.sh
COPY use-oci.sh /usr/local/bin/use-archive
COPY oras_opts.sh /usr/local/bin/oras_opts.sh
COPY entrypoint.sh /usr/local/bin/entrypoint
COPY LICENSE /licenses/LICENSE

FROM registry.access.redhat.com/ubi9/ubi-minimal:latest as oras
ARG ORAS_VERSION=1.2.0
ARG TARGETARCH
ADD https://github.com/oras-project/oras/releases/download/v${ORAS_VERSION}/oras_${ORAS_VERSION}_linux_${TARGETARCH}.tar.gz /tmp
RUN microdnf install --assumeyes tar gzip && tar -x -C /tmp -f /tmp/oras_${ORAS_VERSION}_linux_${TARGETARCH}.tar.gz

FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest as parent

LABEL \
description="RHTAP Trusted Artifacts implementation creates and restores archives of files maintaining their integrity." \
io.k8s.description="RHTAP Trusted Artifacts implementation creates and restores archives of files maintaining their integrity." \
summary="RHTAP Trusted Artifacts implementation" \
io.k8s.display-name="RHTAP Trusted Artifacts implementation" \
io.openshift.tags="rhtap build build-trusted-artifacts trusted-application-pipeline tekton pipeline security" \
name="RHTAP Trusted Artifacts implementation" \
description="Konflux Trusted Artifacts implementation creates and restores archives of files maintaining their integrity." \
io.k8s.description="Konflux Trusted Artifacts implementation creates and restores archives of files maintaining their integrity." \
summary="Konflux Trusted Artifacts implementation" \
io.k8s.display-name="Konflux Trusted Artifacts implementation" \
io.openshift.tags="konflux build build-trusted-artifacts trusted-application-pipeline tekton pipeline security" \
name="Konflux Trusted Artifacts implementation" \
com.redhat.component="build-trusted-artifacts"

COPY --from=files / /
COPY --chown=0:0 --from=oras /tmp/oras /usr/local/bin/oras

RUN microdnf update --assumeyes --nodocs --setopt=keepcache=0 && \
Expand All @@ -38,3 +26,19 @@ RUN oras version
USER notroot

ENTRYPOINT [ "/usr/local/bin/entrypoint" ]

# These files are more likely to change when developing and debugging
# so copy them at a later step to reuse the cached earlier layers
FROM scratch AS files

COPY centos9-stream.repo /etc/yum.repos.d/centos9-stream.repo
COPY RPM-GPG-KEY-centosofficial /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
COPY create-oci.sh /usr/local/bin/create-archive
COPY select-oci-auth.sh /usr/local/bin/select-oci-auth.sh
COPY use-oci.sh /usr/local/bin/use-archive
COPY oras_opts.sh /usr/local/bin/oras_opts.sh
COPY entrypoint.sh /usr/local/bin/entrypoint
COPY LICENSE /licenses/LICENSE

FROM parent
COPY --from=files / /
86 changes: 75 additions & 11 deletions create-oci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
# The --store parameter is an image reference used to specify the repository, e.g.
# registry.local/org/repo. If the image reference contains a tag, it is ignored.
#
# The --attach parameter is used to specify to use oras attach instead of oras push.
#
# The --oci-type-scope parameter is used to further define a scope for mediaType and artifactType
# properties when attaching artifacts.
#
# The --no-tar parameter skips tarring steps. Since a single artifact needs to be uploaded,
# this only supports single (or missing) files
#
# The --results parameter is unused. It is left here for compatibility with non-oci support.
#
# Positional parametes are artifact pairs. These are strings. Each contains two parts separated by
Expand All @@ -29,6 +37,9 @@ fi

# contains {result path}={artifact source path} pairs
artifact_pairs=()
attach=""
no_tar=""
oci_type_scope=""

while [[ $# -gt 0 ]]; do
case $1 in
Expand All @@ -37,6 +48,19 @@ while [[ $# -gt 0 ]]; do
shift
shift
;;
--oci-type-scope)
oci_type_scope="$2"
shift
shift
;;
--attach)
attach="true"
shift
;;
--no-tar)
no_tar="true"
shift
;;
-*)
echo "Unknown option $1"
exit 1
Expand All @@ -57,7 +81,8 @@ archive_dir="$(mktemp -d)"

artifacts=()

repo="$(echo -n $store | sed 's_/\(.*\):\(.*\)_/\1_g')"
# Trim off digests and tags
repo="$(echo -n $store | cut -d@ -f1 | cut -d: -f1)"

for artifact_pair in "${artifact_pairs[@]}"; do
result_path="${artifact_pair/=*}"
Expand All @@ -74,15 +99,31 @@ for artifact_pair in "${artifact_pairs[@]}"; do

# log "creating tar archive %s with files from %s" "${archive}" "${path}"

if [ ! -r "${path}" ]; then
# non-existent paths result in empty archives
tar "${tar_opts[@]}" "${archive}" --files-from /dev/null
elif [ -d "${path}" ]; then
# archive the whole directory
tar "${tar_opts[@]}" "${archive}" --directory="${path}" .
if [ -z "${no_tar}" ]; then
if [ ! -r "${path}" ]; then
# non-existent paths result in empty archives
tar "${tar_opts[@]}" "${archive}" --files-from /dev/null
elif [ -d "${path}" ]; then
# archive the whole directory
tar "${tar_opts[@]}" "${archive}" --directory="${path}" .
else
# archive a single file
tar "${tar_opts[@]}" "${archive}" --directory="${path%/*}" "${path##*/}"
fi
else
# archive a single file
tar "${tar_opts[@]}" "${archive}" --directory="${path%/*}" "${path##*/}"
artifact_name="$(basename ${path})"
archive="${archive_dir}/${artifact_name}"
if [ ! -r "${path}" ]; then
# non-existent paths result in empty files
touch "${archive}"
elif [ -d "${path}" ]; then
# directories cannot be uploaded without being tarred
echo WARN: Directories need to be tarred. Do not use the option "--no-tar"
continue
else
# archive a single file
cp ${path} ${archive}
fi
fi

sha256sum_output="$(sha256sum "${archive}")"
Expand Down Expand Up @@ -114,8 +155,31 @@ if [ ${#artifacts[@]} != 0 ]; then
source oras_opts.sh

pushd "${archive_dir}" > /dev/null
oras push "${oras_opts[@]}" --registry-config <(select-oci-auth.sh ${repo}) "${store}" --config="${config:-}" \
"${artifacts[@]}"
if [ -z "${attach}" ]; then
oras push "${oras_opts[@]}" --registry-config <(select-oci-auth.sh ${repo}) "${store}" --config="${config:-}" \
"${artifacts[@]}"
else
oci_artifact_type="application/vnd.konflux-ci.trusted-artifact"
if [ -n "${oci_type_scope}" ]; then
oci_artifact_type="${oci_artifact_type}.${oci_type_scope}"
fi
attached_artifacts=()
for artifact in "${artifacts[@]}"; do
file_base="${artifact%.*}"
file_extension="${artifact##*.}"
media_type_descriptor="${file_base}"
if [[ "${file_base}" != "${file_extension}" ]]; then
media_type_descriptor="${media_type_descriptor}+${file_extension}"
fi
echo "registering artifact:"
echo "${artifact}:${oci_artifact_type}.${media_type_descriptor}"
attached_artifacts+=("${artifact}:${oci_artifact_type}.${media_type_descriptor}")
done
oras attach "${oras_opts[@]}" --no-tty --registry-config <(select-oci-auth.sh ${repo}) --artifact-type "${oci_artifact_type}" \
--distribution-spec v1.1-referrers-api "${store}" "${attached_artifacts[@]}"
oras attach "${oras_opts[@]}" --no-tty --registry-config <(select-oci-auth.sh ${repo}) --artifact-type "${oci_artifact_type}" \
--distribution-spec v1.1-referrers-tag "${store}" "${attached_artifacts[@]}"
fi
popd > /dev/null

echo 'Artifacts created'
Expand Down

0 comments on commit d903e2f

Please sign in to comment.