diff --git a/src/cmd-build b/src/cmd-build index 7173aae9c1..932cecbaf1 100755 --- a/src/cmd-build +++ b/src/cmd-build @@ -182,6 +182,9 @@ if [ -n "${previous_commit}" ]; then ostree refs --repo="${tmprepo}" --create "${ref}" "${previous_commit}" fi + # also make sure the previous build ref exists + ostree refs --repo="${tmprepo}" --create "${previous_build}" "${previous_commit}" --force + # Corner-case here: if the previous build was for a different ref, then we # want to make sure rpm-ostree doesn't select the same version. Do this by # pretending the ref is currently pointing at the last commit on the diff --git a/src/cmdlib.sh b/src/cmdlib.sh index 0b63d53674..7768ca964c 100755 --- a/src/cmdlib.sh +++ b/src/cmdlib.sh @@ -432,8 +432,7 @@ runcompose_tree() { rm -f "${changed_stamp}" # shellcheck disable=SC2086 - set - ${COSA_RPMOSTREE_GDB:-} rpm-ostree compose tree --repo="${repo}" \ - --write-composejson-to "${composejson}" \ + set - ${COSA_RPMOSTREE_GDB:-} rpm-ostree compose tree \ --touch-if-changed "${changed_stamp}" --cachedir="${workdir}"/cache \ ${COSA_RPMOSTREE_ARGS:-} --unified-core "${manifest}" "$@" @@ -441,12 +440,30 @@ runcompose_tree() { # this is the heart of the privs vs no privs dual path if has_privileges; then + set - "$@" --repo "${repo}" --write-composejson-to "${composejson}" # we hardcode a umask of 0022 here to make sure that composes are run # with a consistent value, regardless of the environment (umask 0022 && sudo -E "$@") sudo chown -R -h "${USER}":"${USER}" "${tmprepo}" else - runvm_with_cache "$@" + local tarball="${workdir}/tmp/repo/commit.tar" + rm -f "${tarball}" + runvm_with_cache /usr/lib/coreos-assembler/compose.sh \ + "${tarball}" "${composejson}" "$@" + if [ ! -f "${tarball}" ]; then + return + fi + local commit + commit=$(jq -r '.["ostree-commit"]' < "${composejson}") + local import_repo="${workdir}/tmp/repo-import" + rm -rf "${import_repo}" && mkdir "${import_repo}" + tar -C "${import_repo}" -xf "${tarball}" && rm -f "${tarball}" + # this is archive to archive so will hardlink + ostree pull-local --repo "${repo}" "${import_repo}" "${commit}" + if [ -n "${ref}" ]; then + ostree refs --repo "${repo}" "${commit}" --create "${ref}" --force + fi + rm -rf "${import_repo}" fi } diff --git a/src/compose.sh b/src/compose.sh new file mode 100644 index 0000000000..5d401002a4 --- /dev/null +++ b/src/compose.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -euo pipefail + +output_tarball=$1; shift +output_composejson=$1; shift + +tarball=cache/output.tar +composejson=cache/compose.json + +repo=cache/repo +rm -rf "${repo}" "${composejson}" +ostree init --repo="${repo}" --mode=archive-z2 + +# we do need to pull at least the overlay bits over 9p, but it shouldn't be that +# many files +ostree refs --repo tmp/repo overlay --list | \ + xargs -r ostree pull-local --repo "${repo}" tmp/repo +# And import commit metadata for all refs; this will bring in the previous +# build if there is one. Ideally, we'd import the SELinux policy too to take +# advantage of https://github.com/coreos/rpm-ostree/pull/1704 but that's yet +# more files over 9p and our pipelines don't have cache anyway (and devs likely +# use the privileged path). +ostree refs --repo tmp/repo | \ + xargs -r ostree pull-local --commit-metadata-only --repo "${repo}" tmp/repo + +# run rpm-ostree +"$@" --repo "${repo}" --write-composejson-to "${composejson}" + +if [ ! -f "${composejson}" ]; then + # no commit was produced; we're done + exit 0 +fi + +tar -f "${tarball}" -C "${repo}" -c . + +# this is key bit where we move the OSTree content over 9p +mv "${tarball}" "${output_tarball}" +mv "${composejson}" "${output_composejson}" diff --git a/src/vmdeps.txt b/src/vmdeps.txt index 6c60458402..5ffc0a37c9 100644 --- a/src/vmdeps.txt +++ b/src/vmdeps.txt @@ -27,3 +27,5 @@ gdisk xfsprogs e2fsprogs dosfstools btrfs-progs # needed for basic CA support ca-certificates + +tar