diff --git a/BuildSourceImage.sh b/BuildSourceImage.sh index d0db1ca..ddee851 100755 --- a/BuildSourceImage.sh +++ b/BuildSourceImage.sh @@ -28,6 +28,10 @@ _usage() { echo -e " -D\t\tdebuging output. Can be set via DEBUG env variable" echo -e " -h\t\tthis usage information" echo -e " -v\t\tversion" + echo -e "" + echo -e " Subcommands:" + echo -e " unpack\tUnpack an OCI layout to a rootfs directory" + echo -e "" } # sanity checks on startup @@ -44,6 +48,23 @@ _init() { done } +# enable access to some of functions as subcommands! +_subcommand() { + local command="${1}" + local ret + + shift + + case "${command}" in + unpack) + # (vb) i'd prefer this subcommand directly match the function name, but it isn't as pretty. + unpack_img "${@}" + ret=$? + exit "${ret}" + ;; + esac +} + # _is_sourced tests whether this script is being source, or executed directly _is_sourced() { # https://unix.stackexchange.com/a/215279 @@ -292,6 +313,20 @@ unpack_img() { local unpack_dir="${2}" local ret + while getopts ":h" opts; do + case "${opts}" in + *) + echo "$0 unpack " + return 1 + ;; + esac + done + shift $((OPTIND-1)) + + if [ -z "${image_dir}" ] || [ -z "${unpack_dir}" ] ; then + _error "[unpack_img] blank arguments provided" + fi + if [ -d "${unpack_dir}" ] ; then _rm_rf "${unpack_dir}" fi @@ -336,9 +371,10 @@ unpack_img_bash() { return ${ret} fi - # Since we're landing the reference as an OCI layout, this mediaType is fairly predictable - # TODO don't always assume +gzip - layer_dgsts="$(jq '.layers[] | select(.mediaType == "application/vnd.oci.image.layer.v1.tar+gzip") | .digest' "${image_dir}"/blobs/"${mnfst_dgst/:/\/}" | tr -d \")" + # TODO this will need to be refactored when we start seeing +zstd layers. + # Then it will be better to no just get a list of digests, but maybe to + # iterate on each descriptor independently? + layer_dgsts="$(jq '.layers | map(select(.mediaType == "application/vnd.oci.image.layer.v1.tar+gzip"),select(.mediaType == "application/vnd.oci.image.layer.v1.tar"),select(.mediaType == "application/vnd.docker.image.rootfs.diff.tar.gzip")) | .[] | .digest' "${image_dir}"/blobs/"${mnfst_dgst/:/\/}" | tr -d \")" ret=$? if [ ${ret} -ne 0 ] ; then return ${ret} @@ -1026,8 +1062,9 @@ main() { local work_dir _init "${@}" + _subcommand "${@}" - base_dir="$(pwd)/${ABV_NAME}" + base_dir="${BASE_DIR:-$(pwd)/${ABV_NAME}}" # using the bash builtin to parse while getopts ":hlvDi:c:s:e:o:b:d:p:" opts; do case "${opts}" in diff --git a/Dockerfile b/Dockerfile index 0714352..8c64206 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,4 +4,6 @@ RUN dnf install -y jq skopeo findutils file 'dnf-command(download)' COPY ./BuildSourceImage.sh /usr/local/bin/BuildSourceImage.sh -ENTRYPOINT ["/usr/local/bin/BuildSourceImage.sh", "-b", "/tmp/"] +ENV BASE_DIR=/tmp + +ENTRYPOINT ["/usr/local/bin/BuildSourceImage.sh"] diff --git a/test/02-from_image_ref.bats b/test/02-from_image_ref.bats index 74595d2..b9f1ce3 100644 --- a/test/02-from_image_ref.bats +++ b/test/02-from_image_ref.bats @@ -3,6 +3,7 @@ load helpers @test "Build from image reference" { + #skip "this takes like 20min ..." local d d=$(mktemp -d) echo "temporary directory: ${d}" diff --git a/test/03-unpack.bats b/test/03-unpack.bats new file mode 100644 index 0000000..ee540cf --- /dev/null +++ b/test/03-unpack.bats @@ -0,0 +1,32 @@ +#!/usr/bin/env bats -t + +load helpers + +@test "unpack - no args" { + run_ctr $CTR_IMAGE unpack + [ "$status" -eq 1 ] + [[ ${lines[0]} =~ "[SrcImg][ERROR] [unpack_img] blank arguments provided" ]] +} + +@test "unpack - Help" { + run_ctr $CTR_IMAGE unpack -h + [ "$status" -eq 1 ] + [[ ${lines[0]} =~ "BuildSourceImage.sh unpack " ]] +} + +@test "unpack - from a SRPM build" { + local d + local r + + d=$(mktemp -d) + echo "temporary directories: output - ${d}" + run_ctr -v $(pwd)/.testprep/srpms/:/src:ro --mount type=bind,source=${d},destination=/output $CTR_IMAGE -s /src -o /output + [ "$status" -eq 0 ] + [ -f "${d}/index.json" ] + + r=$(mktemp -d) + echo "temporary directories: unpacked - ${r}" + run_ctr --mount type=bind,source=${d},destination=/output -v ${r}:/unpacked/ $CTR_IMAGE unpack /output/ /unpacked/ + [ "$(find ${r} -type f | wc -l)" -eq 3 ] # regular files + [ "$(find ${r} -type l | wc -l)" -eq 3 ] # and symlinks +} diff --git a/test/helpers.bash b/test/helpers.bash index 67428d9..8dbb1c1 100644 --- a/test/helpers.bash +++ b/test/helpers.bash @@ -1,3 +1,8 @@ +#!/bin/bash + +export CTR_IMAGE="${CTR_IMAGE:-localhost/containers/buildsourceimage}" +export CTR_ENGINE="${CTR_ENGINE:-podman}" + function run_ctr() { run $CTR_ENGINE run --security-opt label=disable --rm "$@" }