2023-03-17 10:54:08 +03:00
#!/bin/bash
registry = ""
image = ""
tag = ""
cosign_password = ""
metafile = ""
multiarch = ""
username = ""
2023-04-27 18:06:52 +03:00
password = ""
2023-03-17 10:54:08 +03:00
debug = 0
data_dir = $( pwd )
2023-03-20 17:51:50 +03:00
while ( ( " $# " ) ) ; do
case $1 in
-r| --registry)
if [ -z " $2 " ] ; then
echo "Option registry requires an argument"
exit 1
fi
registry = $2 ;
shift 2
; ;
-i| --image)
if [ -z " $2 " ] ; then
echo "Option image requires an argument"
exit 1
fi
image = $2
shift 2
; ;
-t| --tag)
if [ -z " $2 " ] ; then
echo "Option tag requires an argument"
exit 1
fi
tag = $2
shift 2
; ;
-u| --username)
if [ -z " $2 " ] ; then
echo "Option username requires an argument"
exit 1
fi
username = $2
shift 2
; ;
-p| --password)
if [ -z " $2 " ] ; then
echo "Option password requires an argument"
exit 1
fi
password = $2
shift 2
; ;
-c| --cosign-password)
if [ -z " $2 " ] ; then
echo "Option cosign-password requires an argument"
exit 1
fi
cosign_password = $2
shift 2
; ;
-m| --multiarch)
if [ -z " $2 " ] ; then
echo "Option multiarch requires an argument"
exit 1
fi
multiarch = $2
shift 2
; ;
-f| --file)
if [ -z " $2 " ] ; then
echo "Option metafile requires an argument"
exit 1
fi
metafile = $2
shift 2
; ;
--data-dir)
if [ -z " $2 " ] ; then
echo "Option data-dir requires an argument"
exit 1
fi
data_dir = $2
shift 2
; ;
-d| --debug)
debug = 1
shift 1
; ;
--)
shift 1
break
; ;
*)
break
; ;
2023-03-17 10:54:08 +03:00
esac
done
if [ ${ debug } -eq 1 ] ; then
set -x
fi
images_dir = ${ data_dir } /images
docker_docs_dir = ${ data_dir } /docs
cosign_key_path = ${ data_dir } /cosign.key
function verify_prerequisites {
mkdir -p ${ data_dir }
2023-04-27 18:06:52 +03:00
command -v regctl
if [ $? -ne 0 ] ; then
echo "you need to install regctl as a prerequisite"
exit 1
2023-03-17 10:54:08 +03:00
fi
2023-04-27 18:06:52 +03:00
command -v skopeo
if [ $? -ne 0 ] ; then
echo "you need to install skopeo as a prerequisite"
exit 1
2023-03-17 10:54:08 +03:00
fi
2023-04-27 18:06:52 +03:00
command -v cosign
if [ $? -ne 0 ] ; then
echo "you need to install cosign as a prerequisite"
2023-03-17 10:54:08 +03:00
return 1
fi
2023-04-27 18:06:52 +03:00
command -v trivy
if [ $? -ne 0 ] ; then
echo "you need to install trivy as a prerequisite"
2023-04-12 14:43:39 +03:00
return 1
fi
2023-04-27 18:06:52 +03:00
command -v jq
if [ $? -ne 0 ] ; then
echo "you need to install jq as a prerequisite"
2023-03-17 10:54:08 +03:00
return 1
fi
if [ ! -f " ${ cosign_key_path } " ] ; then
COSIGN_PASSWORD = ${ cosign_password } cosign generate-key-pair
key_dir = $( dirname ${ cosign_key_path } )
mv cosign.key ${ cosign_key_path }
mv cosign.pub ${ key_dir }
fi
# pull docker docs repo
if [ ! -d ${ docker_docs_dir } ]
then
git clone https://github.com/docker-library/docs.git ${ docker_docs_dir }
fi
return 0
}
verify_prerequisites
repo = $( cat ${ docker_docs_dir } /${ image } /github-repo)
description = " $( cat ${ docker_docs_dir } /${ image } /README-short.txt) "
license = " $( cat ${ docker_docs_dir } /${ image } /license.md) "
vendor = " $( cat ${ docker_docs_dir } /${ image } /maintainer.md) "
logo = $( base64 -w 0 ${ docker_docs_dir } /${ image } /logo.png)
echo ${ repo }
2023-03-20 17:51:50 +03:00
sed -i.bak " s|%%GITHUB-REPO%%| ${ repo } |g " ${ docker_docs_dir } /${ image } /maintainer.md; rm ${ docker_docs_dir } /${ image } /maintainer.md.bak
sed -i.bak " s|%%IMAGE%%| ${ image } |g " ${ docker_docs_dir } /${ image } /content.md; rm ${ docker_docs_dir } /${ image } /content.md.bak
2023-03-17 10:54:08 +03:00
doc = $( cat ${ docker_docs_dir } /${ image } /content.md)
local_image_ref_skopeo = oci:${ images_dir } :${ image } -${ tag }
local_image_ref_regtl = ocidir://${ images_dir } :${ image } -${ tag }
2023-04-12 14:43:39 +03:00
local_image_ref_trivy = ${ images_dir } :${ image } -${ tag }
2023-03-17 10:54:08 +03:00
remote_src_image_ref = docker://${ image } :${ tag }
remote_dest_image_ref = ${ registry } /${ image } :${ tag }
multiarch_arg = ""
if [ ! -z " ${ multiarch } " ] ; then
multiarch_arg = " --multi-arch= ${ multiarch } "
fi
# Verify if image is already present in local oci layout
skopeo inspect ${ local_image_ref_skopeo }
if [ $? -eq 0 ] ; then
echo " Image ${ local_image_ref_skopeo } found locally "
else
echo " Image ${ local_image_ref_skopeo } will be copied "
2023-05-30 10:35:08 +03:00
skopeo --insecure-policy --override-os= "linux" --override-arch= "amd64" copy --override-os= "linux" --override-arch= "amd64" --format= oci ${ multiarch_arg } ${ remote_src_image_ref } ${ local_image_ref_skopeo }
2023-03-17 10:54:08 +03:00
if [ $? -ne 0 ] ; then
exit 1
fi
fi
# Mofify image in local oci layout and update the old reference to point to the new index
regctl image mod --replace --annotation org.opencontainers.image.title= ${ image } ${ local_image_ref_regtl }
regctl image mod --replace --annotation org.opencontainers.image.description= " ${ description } " ${ local_image_ref_regtl }
regctl image mod --replace --annotation org.opencontainers.image.url= ${ repo } ${ local_image_ref_regtl }
regctl image mod --replace --annotation org.opencontainers.image.source= ${ repo } ${ local_image_ref_regtl }
regctl image mod --replace --annotation org.opencontainers.image.licenses= " ${ license } " ${ local_image_ref_regtl }
regctl image mod --replace --annotation org.opencontainers.image.vendor= " ${ vendor } " ${ local_image_ref_regtl }
regctl image mod --replace --annotation org.opencontainers.image.documentation= " ${ description } " ${ local_image_ref_regtl }
credentials_args = ""
if [ ! -z " ${ username } " ] ; then
2023-04-27 18:06:52 +03:00
credentials_args = " --dest-creds ${ username } : ${ password } "
2023-03-17 10:54:08 +03:00
fi
# Upload image to target registry
2023-05-30 10:35:08 +03:00
skopeo --override-os= "linux" --override-arch= "amd64" copy --dest-tls-verify= false ${ multiarch_arg } ${ credentials_args } ${ local_image_ref_skopeo } docker://${ remote_dest_image_ref }
2023-03-17 10:54:08 +03:00
if [ $? -ne 0 ] ; then
exit 1
fi
# Upload image logo as image media type
regctl artifact put --annotation artifact.type= com.zot.logo.image --annotation format = oci \
--artifact-type "application/vnd.zot.logo.v1" --subject ${ remote_dest_image_ref } ${ remote_dest_image_ref } -logo-image << EOF
${ logo }
EOF
if [ $? -ne 0 ] ; then
exit 1
fi
2023-04-12 14:43:39 +03:00
trivy_out_file = trivy-${ image } -${ tag } .json
if [ ! -z " ${ multiarch } " ] ; then
trivy image --scanners vuln --format json --input ${ local_image_ref_trivy } -o ${ trivy_out_file }
jq -n --argfile trivy_file ${ trivy_out_file } '.trivy=$trivy_file.Results' > ${ trivy_out_file } .tmp
mv ${ trivy_out_file } .tmp ${ trivy_out_file }
else
echo '{"trivy":[]}' > ${ trivy_out_file }
fi
2023-04-27 18:06:52 +03:00
layers_file = manifests-${ image } -${ tag } .json
rm -f ${ layers_file }
if [ -z " ${ multiarch } " ] ; then
regctl manifest --format raw-body get ${ local_image_ref_regtl } | jq '{ manifests: { default: { layers: [ .layers[].digest ] } } }' > ${ layers_file }
else
manifests = $( regctl manifest --format raw-body get ${ local_image_ref_regtl } | jq '[ .manifests[] | { "digest":.digest, "platform":(.platform | [ .os, .architecture, .variant ] | map(select(.!=null)) | join("/") )} ] ' )
echo $manifests | jq -c '.[]' | while read i; do
digest = $( echo $i | jq -r '.digest' )
platform = $( echo $i | jq -r '.platform' )
regctl manifest --format raw-body get ocidir://${ images_dir } @${ digest } | jq --arg platform " ${ platform } " '{ manifests: { ($platform): { layers: [ .layers[].digest ] } } }' >> layers-${ image } -${ tag } -${ digest // : /_ } .json
done
jq -n '{ manifests: [ inputs.manifests ] | add }' layers-${ image } -${ tag } *.json > ${ layers_file }
rm -f layers-${ image } -${ tag } *.json
fi
2023-03-17 10:54:08 +03:00
# Sign new updated image
2023-04-27 18:06:52 +03:00
COSIGN_PASSWORD = ${ cosign_password } cosign sign ${ remote_dest_image_ref } --key ${ cosign_key_path } --allow-insecure-registry --yes
2023-03-17 10:54:08 +03:00
if [ $? -ne 0 ] ; then
exit 1
fi
2023-04-12 14:43:39 +03:00
details_file = details-${ image } -${ tag } .json
jq -n \
2023-03-17 10:54:08 +03:00
--arg org.opencontainers.image.title " ${ image } " \
--arg org.opencontainers.image.description " $description " \
--arg org.opencontainers.image.url " ${ repo } " \
--arg org.opencontainers.image.source " ${ repo } " \
--arg org.opencontainers.image.licenses " ${ license } " \
--arg org.opencontainers.image.vendor " ${ vendor } " \
--arg org.opencontainers.image.documentation " ${ description } " \
2023-04-12 14:43:39 +03:00
'$ARGS.named' > ${ details_file }
2023-03-17 10:54:08 +03:00
2023-04-27 18:06:52 +03:00
jq -c -s add ${ details_file } ${ trivy_out_file } ${ layers_file } > ${ metafile }
rm ${ details_file } ${ trivy_out_file } ${ layers_file }