Path: blob/main/release/scripts/make-oci-image.sh
102426 views
#! /bin/sh12# Build an Open Container Initiative (OCI) container image34curdir=$1; shift5rev=$1; shift6branch=$1; shift7arch=$1; shift8image=$1; shift9output=$1; shift1011major=${rev%.*}12minor=${rev#*.}1314abi=FreeBSD:${major}:${arch}15ver=${rev}-${branch}-${arch}1617echo "Building OCI freebsd${major}-${image} image for ${abi}"1819. ${curdir}/tools/oci-image-${image}.conf2021init_repo() {22local workdir=$1; shift23local abi=$1; shift24local srcdir=$(realpath ${curdir}/..)2526mkdir -p ${workdir}/repos27cat > ${workdir}/repos/base.conf <<EOF28FreeBSD-base: {29url: "file:///usr/obj${srcdir}/repo/${abi}/latest"30signature_type: "none"31fingerprints: "none"32}33EOF34}3536# Install packages using pkg(8) into a container with rootfs at $337install_packages() {38local abi=$1; shift39local workdir=$1; shift40local rootdir=${workdir}/rootfs4142# Make sure we have the keys needed for verifying package integrity if43# not already added by a parent image.44if [ ! -d ${rootdir}/usr/share/keys/pkg/trusted ]; then45mkdir -p ${rootdir}/usr/share/keys/pkg/trusted46fi47for i in ${curdir}/../share/keys/pkg/trusted/pkg.*; do48if [ ! -f ${rootdir}/usr/share/keys/pkg/trusted/$(basename $i) ]; then49cp $i ${rootdir}/usr/share/keys/pkg/trusted50fi51done5253# We install the packages and then remove repository metadata (keeping the54# metadata for what was installed). This trims more than 40Mb from the55# resulting image.56env IGNORE_OSVERSION=yes ABI=${abi} pkg --rootdir ${rootdir} --repo-conf-dir ${workdir}/repos \57install -yq -g "$@" || exit $?58rm -rf ${rootdir}/var/db/pkg/repos59}6061set_cmd() {62local workdir=$1; shift63oci_cmd="$@"64}6566# Convert FreeBSD architecture to OCI-style. See67# https://github.com/containerd/platforms/blob/main/platforms.go for details68normalize_arch() {69local arch=$1; shift70case ${arch} in71i386)72arch=38673;;74aarch64)75arch=arm6476;;77amd64) ;;78riscv64) ;;79*)80echo "Architecture ${arch} not supported for container images"81;;82esac83echo ${arch}84}8586create_container() {87local workdir=$1; shift88local base_workdir=$1; shift89oci_cmd=90if [ -d ${workdir}/rootfs ]; then91chflags -R 0 ${workdir}/rootfs92rm -rf ${workdir}/rootfs93fi94mkdir -p ${workdir}/rootfs95if [ "${base_workdir}" != "" ]; then96tar -C ${workdir}/rootfs -xf ${base_workdir}/rootfs.tar.gz97fi98}99100commit_container() {101local workdir=$1; shift102local image=$1; shift103local output=$1; shift104105# Note: the diff_id (needed for image config) is the hash of the106# uncompressed tar.107#108# For compatibility with Podman, we must disable sparse-file109# handling. See https://github.com/containers/podman/issues/25270 for110# more details.111tar -C ${workdir}/rootfs --strip-components 1 --no-read-sparse -cf ${workdir}/rootfs.tar .112local diff_id=$(sha256 -q < ${workdir}/rootfs.tar)113gzip -f ${workdir}/rootfs.tar114local create_time=$(date -u +%Y-%m-%dT%TZ)115local root_hash=$(sha256 -q < ${workdir}/rootfs.tar.gz)116local root_size=$(stat -f %z ${workdir}/rootfs.tar.gz)117118oci_arch=$(normalize_arch ${arch})119120config=121if [ -n "${oci_cmd}" ]; then122config=",\"config\":{\"cmd\":[\"${oci_cmd}\"]}"123fi124echo "{\"created\":\"${create_time}\",\"architecture\":\"${oci_arch}\",\"os\":\"freebsd\"${config},\"rootfs\":{\"type\":\"layers\",\"diff_ids\":[\"sha256:${diff_id}\"]},\"history\":[{\"created\":\"${create_time}\",\"created_by\":\"make-oci-image.sh\"}]}" > ${workdir}/config.json125local config_hash=$(sha256 -q < ${workdir}/config.json)126local config_size=$(stat -f %z ${workdir}/config.json)127128echo "{\"schemaVersion\":2,\"mediaType\":\"application/vnd.oci.image.manifest.v1+json\",\"config\":{\"mediaType\":\"application/vnd.oci.image.config.v1+json\",\"digest\":\"sha256:${config_hash}\",\"size\":${config_size}},\"layers\":[{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:${root_hash}\",\"size\":${root_size}}],\"annotations\":{}}" > ${workdir}/manifest.json129local manifest_hash=$(sha256 -q < ${workdir}/manifest.json)130local manifest_size=$(stat -f %z ${workdir}/manifest.json)131132mkdir -p ${workdir}/oci/blobs/sha256133echo "{\"imageLayoutVersion\": \"1.0.0\"}" > ${workdir}/oci/oci-layout134echo "{\"schemaVersion\":2,\"manifests\":[{\"mediaType\":\"application/vnd.oci.image.manifest.v1+json\",\"digest\":\"sha256:${manifest_hash}\",\"size\":${manifest_size},\"annotations\":{\"org.opencontainers.image.ref.name\":\"freebsd-${image}:${ver}\"}}]}" > ${workdir}/oci/index.json135ln ${workdir}/rootfs.tar.gz ${workdir}/oci/blobs/sha256/${root_hash}136ln ${workdir}/config.json ${workdir}/oci/blobs/sha256/${config_hash}137ln ${workdir}/manifest.json ${workdir}/oci/blobs/sha256/${manifest_hash}138139tar -C ${workdir}/oci --xz --strip-components 1 --no-read-sparse -a -cf ${output} .140}141142# Prefix with "container-image-" so that we can create a unique work area under143# ${.OBJDIR}. We can assume that make has set our working directory to144# ${.OBJDIR}.145workdir=${PWD}/container-image-${image}146init_repo ${workdir} ${abi}147148if [ -n "${OCI_BASE_IMAGE}" ]; then149base_workdir=${PWD}/container-image-${OCI_BASE_IMAGE}150else151base_workdir=152fi153154create_container ${workdir} ${base_workdir}155oci_image_build156commit_container ${workdir} ${image} ${output}157158159