Skip to content

Commit cd246a1

Browse files
committed
feat: support rechunking using Chunkah
Add a `--chunkah` option to `bluebuild build` that rechunks the image using [Chunkah](https://github.com/coreos/chunkah), a more modern, content-agnostic rechunker that's actively maintained and should offer various improvements over build-chunked-oci and the legacy rechunker. This is implemented using a fairly generic "post-build hook" mechanism that allows a post-processing step (such as rechunking) to be applied after building the image but before tagging and pushing.
1 parent 76196f6 commit cd246a1

25 files changed

Lines changed: 912 additions & 214 deletions

.github/workflows/test.yml

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,44 @@ jobs:
247247
COSIGN_PRIVATE_KEY: ${{ secrets.TEST_SIGNING_SECRET }}
248248
run: just test-bluefin-build
249249

250+
chunkah-build:
251+
timeout-minutes: 40
252+
runs-on: ubuntu-24.04
253+
permissions:
254+
contents: read # read repo contents
255+
packages: write # write test package to ghcr
256+
id-token: write # docker auth
257+
258+
steps:
259+
- name: Maximize build space
260+
uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9
261+
262+
- uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
263+
with:
264+
install-dir: /usr/bin
265+
use-sudo: true
266+
267+
- uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1.16.1
268+
269+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
270+
with:
271+
persist-credentials: false
272+
fetch-depth: 0
273+
ref: ${{ inputs.ref }}
274+
repository: ${{ inputs.repo }}
275+
276+
277+
- uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
278+
279+
- name: Run Build
280+
env:
281+
GH_TOKEN: ${{ github.token }}
282+
GH_PR_EVENT_NUMBER: ${{ inputs.pr_event_number }}
283+
COSIGN_PRIVATE_KEY: ${{ secrets.TEST_SIGNING_SECRET }}
284+
run: |
285+
export CARGO_HOME=$HOME/.cargo
286+
just test-chunkah-build
287+
250288
build-chunked-oci-build:
251289
timeout-minutes: 40
252290
runs-on: ubuntu-24.04
@@ -598,6 +636,42 @@ jobs:
598636
COSIGN_PRIVATE_KEY: ${{ secrets.TEST_SIGNING_SECRET }}
599637
run: just test-multiplatform-buildah
600638

639+
multi-platform-chunkah:
640+
timeout-minutes: 120
641+
runs-on: ubuntu-latest
642+
permissions:
643+
contents: read
644+
packages: write
645+
id-token: write
646+
647+
steps:
648+
- name: Maximize build space
649+
uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9
650+
651+
- name: Set up QEMU
652+
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
653+
654+
- uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
655+
656+
- uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1.16.1
657+
658+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
659+
with:
660+
persist-credentials: false
661+
fetch-depth: 0
662+
ref: ${{ inputs.ref }}
663+
repository: ${{ inputs.repo }}
664+
665+
666+
- uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
667+
668+
- name: Run Build
669+
env:
670+
GH_TOKEN: ${{ github.token }}
671+
GH_PR_EVENT_NUMBER: ${{ inputs.pr_event_number }}
672+
COSIGN_PRIVATE_KEY: ${{ secrets.TEST_SIGNING_SECRET }}
673+
run: just test-multiplatform-chunkah
674+
601675
multi-platform-build-chunked-oci:
602676
timeout-minutes: 120
603677
runs-on: ubuntu-latest
@@ -821,6 +895,43 @@ jobs:
821895
COSIGN_PRIVATE_KEY: ${{ secrets.TEST_SIGNING_SECRET }}
822896
run: just test-container-podman-build
823897

898+
container-podman-chunkah:
899+
timeout-minutes: 60
900+
runs-on: ubuntu-latest
901+
permissions:
902+
contents: read # read repo contents
903+
packages: write # write test package to ghcr
904+
id-token: write # docker auth
905+
906+
steps:
907+
- name: Maximize build space
908+
uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9
909+
910+
- uses: earthly/actions-setup@43211c7a0eae5344d6d79fb4aaf209c8f8866203 # v1.0.13
911+
with:
912+
use-cache: false
913+
914+
- name: Set up Docker Buildx
915+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
916+
with:
917+
install: true
918+
919+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
920+
with:
921+
persist-credentials: false
922+
fetch-depth: 0
923+
ref: ${{ inputs.ref }}
924+
repository: ${{ inputs.repo }}
925+
926+
- uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
927+
928+
- name: Run Build
929+
env:
930+
GH_TOKEN: ${{ github.token }}
931+
GH_PR_EVENT_NUMBER: ${{ inputs.pr_event_number }}
932+
COSIGN_PRIVATE_KEY: ${{ secrets.TEST_SIGNING_SECRET }}
933+
run: just test-container-podman-chunkah
934+
824935
container-podman-build-chunked-oci:
825936
timeout-minutes: 60
826937
runs-on: ubuntu-latest

Cargo.lock

Lines changed: 0 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ clap = { workspace = true, features = ["derive", "cargo", "unicode", "env"] }
9494
colored.workspace = true
9595
comlexr.workspace = true
9696
indexmap.workspace = true
97-
indicatif.workspace = true
9897
log.workspace = true
9998
miette = { workspace = true, features = ["fancy"] }
10099
oci-client.workspace = true
@@ -105,8 +104,6 @@ semver.workspace = true
105104
serde.workspace = true
106105
serde_json.workspace = true
107106
serde_yaml.workspace = true
108-
syntect.workspace = true
109-
tempfile.workspace = true
110107
tokio.workspace = true
111108
bon.workspace = true
112109

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
# yaml-language-server: $schema=https://schema.blue-build.org/recipe-v1.json
3+
name: cli/test-chunkah
4+
description: This is my personal OS image.
5+
base-image: quay.io/fedora/fedora-bootc
6+
image-version: latest
7+
stages:
8+
- from-file: stages.yml
9+
modules:
10+
- from-file: common.yml
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
# yaml-language-server: $schema=https://schema.blue-build.org/recipe-v1.json
3+
name: cli/test-multiplatform-chunkah
4+
description: This is my personal OS image.
5+
base-image: quay.io/fedora/fedora-bootc
6+
image-version: latest
7+
platforms:
8+
- linux/amd64
9+
- linux/arm64
10+
stages:
11+
- from-file: stages.yml
12+
modules:
13+
- from-file: common.yml

justfile

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,14 @@ test-bluefin-build: generate-test-secret install-debug-all-features
188188
-vv \
189189
recipes/recipe-bluefin.yml
190190

191+
test-chunkah-build: generate-test-secret install-debug-all-features
192+
cd integration-tests/test-repo \
193+
&& bluebuild build \
194+
{{ should_push }} \
195+
-vv \
196+
--chunkah \
197+
recipes/recipe-chunkah.yml
198+
191199
test-build-chunked-oci-build: generate-test-secret install-debug-all-features
192200
cd integration-tests/test-repo \
193201
&& bluebuild build \
@@ -256,7 +264,7 @@ test-buildah-build: generate-test-secret install-debug-all-features
256264
recipes/recipe-buildah.yml
257265

258266
# Run the multi-platform builds
259-
test-multiplatform: test-multiplatform-docker test-multiplatform-podman test-multiplatform-buildah test-multiplatform-build-chunked-oci test-multiplatform-rechunk
267+
test-multiplatform: test-multiplatform-docker test-multiplatform-podman test-multiplatform-buildah test-multiplatform-chunkah test-multiplatform-build-chunked-oci test-multiplatform-rechunk
260268

261269
test-multiplatform-docker: generate-test-secret install-debug-all-features
262270
cd integration-tests/test-repo \
@@ -288,6 +296,17 @@ test-multiplatform-buildah: generate-test-secret install-debug-all-features
288296
-vv \
289297
recipes/recipe-multiplatform-buildah.yml
290298

299+
test-multiplatform-chunkah: generate-test-secret install-debug-all-features
300+
cd integration-tests/test-repo \
301+
&& bluebuild build \
302+
--retry-push \
303+
--chunkah \
304+
--remove-base-image \
305+
-S sigstore \
306+
{{ should_push }} \
307+
-vv \
308+
recipes/recipe-multiplatform-chunkah.yml
309+
291310
test-multiplatform-build-chunked-oci: generate-test-secret install-debug-all-features
292311
cd integration-tests/test-repo \
293312
&& bluebuild build \
@@ -351,6 +370,12 @@ test-container-podman-build: \
351370
generate-test-secret \
352371
(exec-cli-container "bluebuild" "build" "-B" "podman" "--squash" "-vv")
353372

373+
# Run a cli container using the podman build driver with chunkah
374+
test-container-podman-chunkah: \
375+
generate-test-secret \
376+
(exec-cli-container "bluebuild" "build" "-B" \
377+
"podman" "-vv" "--chunkah" "recipes/recipe-chunkah.yml")
378+
354379
# Run a cli container using the podman build driver with build-chunked-oci
355380
test-container-podman-build-chunked-oci: \
356381
generate-test-secret \

process/Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ blue-build-utils = { version = "=0.9.35", path = "../utils" }
1616
indicatif-log-bridge = "0.2.3"
1717
log4rs = { version = "1.4.0", features = ["background_rotation"] }
1818
nu-ansi-term = { version = "0.50.3", features = ["gnu_legacy"] }
19-
os_pipe = { version = "1.2.3", features = ["io_safety"] }
2019
signal-hook = { version = "0.4.4", features = ["extended-siginfo"] }
2120
sigstore = { version = "0.13.0", features = ["rustls-tls", "cached-client", "sigstore-trust-root", "sign", "cosign"], default-features = false }
2221

@@ -26,15 +25,13 @@ chrono.workspace = true
2625
clap = { workspace = true, features = ["derive", "env"] }
2726
colored.workspace = true
2827
comlexr.workspace = true
29-
indexmap.workspace = true
3028
indicatif.workspace = true
3129
lazy-regex.workspace = true
3230
log.workspace = true
3331
miette.workspace = true
3432
nix = { workspace = true, features = ["signal"] }
3533
rayon.workspace = true
3634
oci-client.workspace = true
37-
reqwest.workspace = true
3835
semver.workspace = true
3936
serde.workspace = true
4037
serde_json.workspace = true

process/drivers.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ use crate::{logging::Logger, signal_handler::DetachedContainer};
3636
use opts::{
3737
BuildChunkedOciOpts, BuildOpts, BuildRechunkTagPushOpts, BuildTagPushOpts, CheckKeyPairOpts,
3838
ContainerOpts, CopyOciOpts, CreateContainerOpts, GenerateImageNameOpts, GenerateKeyPairOpts,
39-
GenerateTagsOpts, GetMetadataOpts, ManifestCreateOpts, ManifestPushOpts, PruneOpts, PullOpts,
40-
PushOpts, RechunkOpts, RemoveContainerOpts, RemoveImageOpts, RunOpts, SignOpts, SwitchOpts,
41-
TagOpts, UntagOpts, VerifyOpts, VolumeOpts,
39+
GenerateTagsOpts, GetMetadataOpts, ManifestCreateOpts, ManifestPushOpts, PostBuildDriverOpts,
40+
PruneOpts, PullOpts, PushOpts, RechunkOpts, RemoveContainerOpts, RemoveImageOpts, RunOpts,
41+
SignOpts, SwitchOpts, TagOpts, UntagOpts, VerifyOpts, VolumeOpts,
4242
};
4343
use types::{
4444
BootDriverType, BuildDriverType, CiDriverType, ImageMetadata, InspectDriverType, RunDriverType,
@@ -67,6 +67,7 @@ mod local_driver;
6767
mod oci_client_driver;
6868
pub mod opts;
6969
mod podman_driver;
70+
pub mod post_build;
7071
mod rpm_ostree_driver;
7172
mod rpm_ostree_runner;
7273
mod sigstore_driver;
@@ -325,7 +326,11 @@ fn get_version_run_image(oci_ref: &Reference) -> Result<Version> {
325326
}
326327

327328
if should_remove {
328-
Driver::remove_image(RemoveImageOpts::builder().image(oci_ref).build())?;
329+
Driver::remove_image(
330+
RemoveImageOpts::builder()
331+
.image(&oci_ref.to_string())
332+
.build(),
333+
)?;
329334
}
330335

331336
progress.finish_and_clear();
@@ -396,6 +401,15 @@ impl BuildDriver for Driver {
396401
}
397402
}
398403

404+
impl PostBuildDriver for Driver {
405+
fn build_tag_push_with_post_build(
406+
opts: BuildTagPushOpts,
407+
pb_opts: PostBuildDriverOpts,
408+
) -> Result<Vec<String>> {
409+
PodmanDriver::build_tag_push_with_post_build(opts, pb_opts)
410+
}
411+
}
412+
399413
macro_rules! impl_signing_driver {
400414
($func:ident($($args:expr),*)) => {
401415
match Self::get_signing_driver() {

process/drivers/buildah_driver.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,8 @@ impl ImageStorageDriver for BuildahDriver {
352352
sudo_check = opts.privileged,
353353
"buildah",
354354
"rmi",
355-
opts.image.to_string(),
355+
"--",
356+
opts.image,
356357
);
357358
trace!("{c:?}");
358359
c

0 commit comments

Comments
 (0)