Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,9 @@ ARG rootfs=""
RUN --mount=type=bind,from=packaging,target=/run/packaging /run/packaging/configure-rootfs "${variant}" "${rootfs}"
COPY --from=packaging /usr-extras/ /usr/

# Default target for source builds (just build)
# Installs packages from the internal build stage
# Final target: installs pre-built packages from /run/packages volume mount.
# Use with: podman build --target=final -v path/to/packages:/run/packages:ro
FROM final-common as final
RUN --mount=type=bind,from=packaging,target=/run/packaging \
--mount=type=bind,from=build,target=/build-output \
--network=none \
/run/packaging/install-rpm-and-setup /build-output/out
RUN bootc container lint --fatal-warnings

# Alternative target for pre-built packages (CI workflow)
# Use with: podman build --target=final-from-packages -v path/to/packages:/run/packages:ro
FROM final-common as final-from-packages
RUN --mount=type=bind,from=packaging,target=/run/packaging \
--network=none \
/run/packaging/install-rpm-and-setup /run/packages
Expand Down
67 changes: 21 additions & 46 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ buildargs := base_buildargs + " --secret=id=secureboot_key,src=target/test-secur
# Args for build-sealed (no base arg, it sets that itself)
sealed_buildargs := "--build-arg=variant=" + variant + " --secret=id=secureboot_key,src=target/test-secureboot/db.key --secret=id=secureboot_cert,src=target/test-secureboot/db.crt"

# The default target: build the container image from current sources.
# Note commonly you might want to override the base image via e.g.
# `just build --build-arg=base=quay.io/fedora/fedora-bootc:42`
#
# This first builds RPMs via the `package` target, then injects them
# into the container image.
build: package _keygen
@just _build-from-package target/packages

# Compute SOURCE_DATE_EPOCH and VERSION from git for reproducible builds.
# Outputs shell variable assignments that can be eval'd.
_git-build-vars:
Expand All @@ -66,26 +75,20 @@ _git-build-vars:
echo "SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}"
echo "VERSION=${VERSION}"

# The default target: build the container image from current sources.
# Note commonly you might want to override the base image via e.g.
# `just build --build-arg=base=quay.io/fedora/fedora-bootc:42`
#
# The Dockerfile builds RPMs internally in its 'build' stage, so we don't need
# to call 'package' first. This avoids cache invalidation from external files.
build: _keygen
#!/bin/bash
set -xeuo pipefail
eval $(just _git-build-vars)
podman build {{base_buildargs}} --target=final \
--build-arg=SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} \
--build-arg=pkgversion=${VERSION} \
-t {{base_img}}-bin {{buildargs}} .
./hack/build-sealed {{variant}} {{base_img}}-bin {{base_img}} {{sealed_buildargs}}

# Generate Secure Boot keys (only for our own CI/testing)
_keygen:
./hack/generate-secureboot-keys

# Internal helper: build container image from packages at PATH
_build-from-package PATH:
#!/bin/bash
set -xeuo pipefail
# Resolve to absolute path for podman volume mount
# Use :z for SELinux relabeling
pkg_path=$(realpath "{{PATH}}")
podman build --target=final -v "${pkg_path}":/run/packages:ro,z -t {{base_img}}-bin {{buildargs}} .
./hack/build-sealed {{variant}} {{base_img}}-bin {{base_img}} {{sealed_buildargs}}

# Build a sealed image from current sources.
build-sealed:
@just --justfile {{justfile()}} variant=composefs-sealeduki-sdboot build
Expand All @@ -108,34 +111,6 @@ package: _packagecontainer
chmod a+r target/packages/*.rpm
podman rmi localhost/bootc-pkg

# Copy pre-existing packages from PATH into target/packages/
# Note: This is mainly for CI artifact extraction; build-from-package
# now uses volume mounts directly instead of copying to target/packages/.
copy-packages-from PATH:
#!/bin/bash
set -xeuo pipefail
if ! compgen -G "{{PATH}}/*.rpm" > /dev/null; then
echo "Error: No packages found in {{PATH}}" >&2
exit 1
fi
mkdir -p target/packages
rm -vf target/packages/*.rpm
cp -v {{PATH}}/*.rpm target/packages/
chmod a+rx target target/packages
chmod a+r target/packages/*.rpm

# Build the container image using pre-existing packages from PATH
# Uses the 'final-from-packages' target with a volume mount to inject packages,
# avoiding Docker context cache invalidation issues.
build-from-package PATH: _keygen
#!/bin/bash
set -xeuo pipefail
# Resolve to absolute path for podman volume mount
# Use :z for SELinux relabeling
pkg_path=$(realpath "{{PATH}}")
podman build {{base_buildargs}} --target=final-from-packages -v "${pkg_path}":/run/packages:ro,z -t {{base_img}}-bin {{buildargs}} .
./hack/build-sealed {{variant}} {{base_img}}-bin {{base_img}} {{sealed_buildargs}}

# Pull images used by hack/lbi
_pull-lbi-images:
podman pull -q --retry 5 --retry-delay 5s {{lbi_images}}
Expand All @@ -146,8 +121,8 @@ build-integration-test-image: build _pull-lbi-images
./hack/build-sealed {{variant}} {{integration_img}}-bin {{integration_img}} {{sealed_buildargs}}

# Build integration test image using pre-existing packages from PATH
build-integration-test-image-from-package PATH: _pull-lbi-images
@just build-from-package {{PATH}}
build-integration-test-image-from-package PATH: _keygen _pull-lbi-images
@just _build-from-package {{PATH}}
cd hack && podman build {{base_buildargs}} -t {{integration_img}}-bin -f Containerfile .
./hack/build-sealed {{variant}} {{integration_img}}-bin {{integration_img}} {{sealed_buildargs}}

Expand Down
53 changes: 31 additions & 22 deletions crates/ostree-ext/src/container/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1508,13 +1508,7 @@ pub(crate) fn export_to_oci(
let srcinfo = query_image(repo, imgref)?.ok_or_else(|| anyhow!("No such image"))?;
let (commit_layer, component_layers, remaining_layers) =
parse_manifest_layout(&srcinfo.manifest, &srcinfo.configuration)?;
let commit_layer = commit_layer.ok_or_else(|| anyhow!("Missing {DIFFID_LABEL}"))?;
let commit_chunk_ref = ref_for_layer(commit_layer)?;
let commit_chunk_rev = repo.require_rev(&commit_chunk_ref)?;
let mut chunking = chunking::Chunking::new(repo, &commit_chunk_rev)?;
for layer in component_layers {
chunking_from_layer_committed(repo, layer, &mut chunking)?;
}

// Unfortunately today we can't guarantee we reserialize the same tar stream
// or compression, so we'll need to generate a new copy of the manifest and config
// with the layers reset.
Expand All @@ -1526,8 +1520,6 @@ pub(crate) fn export_to_oci(
}
new_config.rootfs_mut().diff_ids_mut().clear();

let mut dest_oci = ocidir::OciDir::ensure(dest_oci.try_clone()?)?;

let opts = ExportOpts {
skip_compression: opts.skip_compression,
authfile: opts.authfile,
Expand All @@ -1536,19 +1528,36 @@ pub(crate) fn export_to_oci(

let mut labels = HashMap::new();

// Given the object chunking information we recomputed from what
// we found on disk, re-serialize to layers (tarballs).
export_chunked(
repo,
&srcinfo.base_commit,
&mut dest_oci,
&mut new_manifest,
&mut new_config,
&mut labels,
chunking,
&opts,
"",
)?;
let mut dest_oci = ocidir::OciDir::ensure(dest_oci.try_clone()?)?;

let commit_chunk_ref = commit_layer
.as_ref()
.map(|l| ref_for_layer(l))
.transpose()?;
let commit_chunk_rev = commit_chunk_ref
.as_ref()
.map(|r| repo.require_rev(&r))
.transpose()?;
if let Some(commit_chunk_rev) = commit_chunk_rev {
let mut chunking = chunking::Chunking::new(repo, &commit_chunk_rev)?;
for layer in component_layers {
chunking_from_layer_committed(repo, layer, &mut chunking)?;
}

// Given the object chunking information we recomputed from what
// we found on disk, re-serialize to layers (tarballs).
export_chunked(
repo,
&srcinfo.base_commit,
&mut dest_oci,
&mut new_manifest,
&mut new_config,
&mut labels,
chunking,
&opts,
"",
)?;
}

// Now, handle the non-ostree layers; this is a simple conversion of
//
Expand Down
Loading