diff --git a/src/cmd-build b/src/cmd-build index fa1c826810..b9832a13ee 100755 --- a/src/cmd-build +++ b/src/cmd-build @@ -374,11 +374,11 @@ if [ ! -f /lib/coreos-assembler/.clean ]; then src_location="bind mount" fi -# And create the ostree repo tarball containing the commit -ostree_tarfile_path=${name}-${buildid}-ostree.${basearch}.tar +# And create the ostree repo export containing the commit ostree_tarfile_sha256= if [ "${commit}" == "${previous_commit}" ] && \ [ -f "${previous_builddir}/${previous_ostree_tarfile_path}" ]; then + ostree_tarfile_path=$(jq -r '.images.ostree.path' < "${previous_builddir}/meta.json") cp-reflink "${previous_builddir}/${previous_ostree_tarfile_path}" "${ostree_tarfile_path}" ostree_tarfile_sha256=$(jq -r '.images.ostree.sha256' < "${previous_builddir}/meta.json") # backcompat: allow older build without this field @@ -386,22 +386,30 @@ if [ "${commit}" == "${previous_commit}" ] && \ ostree_tarfile_sha256= fi else - ostree init --repo=repo --mode=archive - # Pass the ref if it's set - # shellcheck disable=SC2086 - if ! ostree pull-local --repo=repo "${tmprepo}" "${buildid}" ${ref}; then - echo '(maybe https://github.com/coreos/coreos-assembler/issues/972 ?)' - exit 1 - fi - # Don't compress; archive repos are already compressed individually and we'd - # gain ~20M at best. We could probably have better gains if we compress the - # whole repo in bare/bare-user mode, but that's a different story... - tar -cf "${ostree_tarfile_path}".tmp -C repo . + ostree_format=$(jq -r '.["ostree-format"]' < "${image_json}") + case "${ostree_format}" in + null|tar) + ostree_tarfile_path=${name}-${buildid}-ostree.${basearch}.tar + ostree init --repo=repo --mode=archive + # Pass the ref if it's set + # shellcheck disable=SC2086 + if ! ostree pull-local --repo=repo "${tmprepo}" "${buildid}" ${ref}; then + echo '(maybe https://github.com/coreos/coreos-assembler/issues/972 ?)' + exit 1 + fi + # Don't compress; archive repos are already compressed individually and we'd + # gain ~20M at best. We could probably have better gains if we compress the + # whole repo in bare/bare-user mode, but that's a different story... + tar -cf "${ostree_tarfile_path}".tmp -C repo . + rm -rf repo + ;; + oci) + ostree_tarfile_path="${name}-${buildid}-ostree.${basearch}.ociarchive" + rpm-ostree ex-container 'export' --repo="${tmprepo}" "${buildid}" oci-archive:"${ostree_tarfile_path}".tmp + ;; + *) fatal "Unknown ostree-format: ${ostree_format}" + esac /usr/lib/coreos-assembler/finalize-artifact "${ostree_tarfile_path}"{.tmp,} - rm -rf repo -fi - -if [ -z "${ostree_tarfile_sha256:-}" ]; then ostree_tarfile_sha256=$(sha256sum "${ostree_tarfile_path}" | awk '{print$1}') fi diff --git a/src/cosalib/cmdlib.py b/src/cosalib/cmdlib.py index 0df5143db7..7d976ceaa3 100644 --- a/src/cosalib/cmdlib.py +++ b/src/cosalib/cmdlib.py @@ -249,10 +249,29 @@ def import_ostree_commit(repo, buildpath, buildmeta, force=False): return # extract in a new tmpdir inside the repo itself so we can still hardlink - with tempfile.TemporaryDirectory(dir=repo) as d: - subprocess.check_call(['tar', '-C', d, '-xf', tarfile]) - subprocess.check_call(['ostree', 'pull-local', '--repo', repo, - d, commit]) + if tarfile.endswith('.tar'): + with tempfile.TemporaryDirectory(dir=repo) as d: + subprocess.check_call(['tar', '-C', d, '-xf', tarfile]) + subprocess.check_call(['ostree', 'pull-local', '--repo', repo, + d, commit]) + elif tarfile.endswith('.ociarchive'): + # We do this in two stages, because right now ex-container only writes to + # non-archive repos. Also, in the privileged case we need sudo to write + # to `repo-build`, though it might be good to change this by default. + if os.environ.get('COSA_PRIVILEGED', '') == '1': + build_repo = os.path.join(repo, '../../cache/repo-build') + subprocess.check_call(['sudo', 'rpm-ostree', 'ex-container', 'import', '--repo', build_repo, + '--write-ref', buildmeta['buildid'], 'oci-archive:' + tarfile]) + subprocess.check_call(['sudo', 'ostree', f'--repo={repo}', 'pull-local', build_repo, buildmeta['buildid']]) + uid = os.getuid() + gid = os.getgid() + subprocess.check_call(['sudo', 'chown', '-hR', f"{uid}:{gid}", repo]) + else: + with tempfile.TemporaryDirectory() as tmpd: + subprocess.check_call(['ostree', 'init', '--repo', tmpd, '--mode=bare-user']) + subprocess.check_call(['rpm-ostree', 'ex-container', 'import', '--repo', tmpd, + '--write-ref', buildmeta['buildid'], 'oci-archive:' + tarfile]) + subprocess.check_call(['ostree', f'--repo={repo}', 'pull-local', tmpd, buildmeta['buildid']]) def get_basearch(): diff --git a/tests/test_cosalib_cmdlib.py b/tests/test_cosalib_cmdlib.py index 299d01009b..0efa1c8d14 100644 --- a/tests/test_cosalib_cmdlib.py +++ b/tests/test_cosalib_cmdlib.py @@ -122,7 +122,7 @@ def __call__(self, *args, **kwargs): 'ostree', 'init', '--repo', tmpdir, '--mode=archive'] if self.check_call_count == 1: assert args[0][0:2] == ['tar', '-C'] - assert args[0][3:5] == ['-xf', './tarfile'] + assert args[0][3:5] == ['-xf', './tarfile.tar'] if self.check_call_count == 2: assert args[0][0:4] == [ 'ostree', 'pull-local', '--repo', tmpdir] @@ -142,7 +142,7 @@ def monkeyspcall(*args, **kwargs): 'ostree-commit': 'commit', 'images': { 'ostree': { - 'path': 'tarfile' + 'path': 'tarfile.tar' } } }