From 43701836e664748ad2f185a0c6fa4eb61a8bdb7d Mon Sep 17 00:00:00 2001 From: Gerald Pinder Date: Sun, 18 Oct 2026 23:27:05 -0400 Subject: [PATCH] chore(next-builder): Hook the next-gen builder into the cli frontend --- .github/workflows/test.yml | 13 ++ Cargo.toml | 6 +- justfile | 53 +++-- next/src/lib.rs | 2 +- next/tests/repo/recipes/recipe-v2.yml | 48 ++++ next/tests/repo/recipes/recipe.yml | 26 +-- process/Cargo.toml | 1 + process/drivers.rs | 321 +++++++++++++++++++------- process/drivers/opts.rs | 21 ++ process/drivers/opts/build.rs | 10 - process/drivers/podman_driver.rs | 186 +++++++++------ process/drivers/post_build/chunkah.rs | 4 +- process/drivers/sigstore_driver.rs | 8 +- process/drivers/traits.rs | 87 ++++--- process/drivers/types/drivers.rs | 87 ++++--- src/bin/bluebuild.rs | 1 + src/commands.rs | 2 + src/commands/build.rs | 168 +++++++++++--- src/commands/generate_iso.rs | 10 +- src/commands/init.rs | 10 +- src/commands/login.rs | 10 +- src/commands/prune.rs | 10 +- src/commands/switch.rs | 29 ++- src/lib.rs | 4 + utils/src/macros.rs | 1 - 25 files changed, 803 insertions(+), 315 deletions(-) create mode 100644 next/tests/repo/recipes/recipe-v2.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d860c36..82a9fe6f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -98,6 +98,19 @@ jobs: earth bootstrap earth --ci -P ./integration-tests+all + next-gen-build: + uses: ./.github/workflows/run-test.yml + secrets: + TEST_SIGNING_SECRET: ${{ secrets.TEST_SIGNING_SECRET }} + with: + repo: ${{ inputs.repo }} + ref: ${{ inputs.ref }} + fork_pr: ${{ inputs.fork_pr }} + pr_event_number: ${{ inputs.pr_event_number }} + install_cosign: ${{ ! inputs.fork_pr }} + install_docker: true + run: test-next-gen-build + docker-build: uses: ./.github/workflows/run-test.yml secrets: diff --git a/Cargo.toml b/Cargo.toml index 800229eb..2890b401 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,7 +85,7 @@ blue-build-recipe = { version = "=0.9.37", path = "./recipe" } blue-build-template = { version = "=0.9.37", path = "./template" } blue-build-utils = { version = "=0.9.37", path = "./utils" } blue-build-process-management = { version = "=0.9.37", path = "./process" } -blue-build-next-builder = { version = "=0.9.37", path = "./next" } +blue-build-next-builder = { version = "=0.9.37", path = "./next", optional = true } clap-verbosity-flag = "=3.0.4" clap_complete = "=4.6.9" clap_complete_nushell = "=4.6.2" @@ -124,8 +124,10 @@ default = [] v1_0_0 = [ "bootc", - "recipe-v2" + "recipe-v2", + "next-builder", ] +next-builder = ["dep:blue-build-next-builder", "blue-build-process-management/next-builder"] bootc = ["blue-build-process-management/bootc"] vendored-libgit2 = ["dep:git2", "git2/vendored-libgit2"] recipe-v2 = ["blue-build-recipe/recipe-v2"] diff --git a/justfile b/justfile index 85e7a24a..2437fe0a 100644 --- a/justfile +++ b/justfile @@ -186,8 +186,17 @@ generate-test-secret: # Run all integration tests integration-tests: generate-test-secret test-docker-build test-empty-files-build test-arm64-build test-podman-build test-buildah-build test-generate-iso-image test-generate-iso-recipe test-multiplatform +test-next-gen-build: generate-test-secret install-debug-all-features + cd next/tests/repo \ + && {{ cargo_bin }} build \ + --retry-push \ + {{ should_push }} \ + {{ should_not_sign }} \ + -vv \ + recipes/recipe.yml recipes/recipe-v2.yml + # Run docker driver integration test -test-docker-build: generate-test-secret install-debug-all-features +test-docker-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -198,7 +207,7 @@ test-docker-build: generate-test-secret install-debug-all-features -vv \ recipes/recipe.yml recipes/recipe-gts.yml -test-recipe-v2-build: generate-test-secret install-debug-all-features +test-recipe-v2-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -208,7 +217,7 @@ test-recipe-v2-build: generate-test-secret install-debug-all-features -vv \ recipes/recipe-v2.yml -test-empty-files-build: generate-test-secret install-debug-all-features +test-empty-files-build: generate-test-secret install-debug cd integration-tests/empty-files-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -218,7 +227,7 @@ test-empty-files-build: generate-test-secret install-debug-all-features {{ should_not_sign }} \ -vv -test-env-expansion-build: generate-test-secret install-debug-all-features +test-env-expansion-build: generate-test-secret install-debug cd integration-tests/test-repo \ && DESC_EXT="Test description" \ VERSION="43" \ @@ -231,7 +240,7 @@ test-env-expansion-build: generate-test-secret install-debug-all-features -vv \ recipes/recipe-env-expansion.yml -test-bluefin-build: generate-test-secret install-debug-all-features +test-bluefin-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -242,7 +251,7 @@ test-bluefin-build: generate-test-secret install-debug-all-features -vv \ recipes/recipe-bluefin.yml -test-chunkah-build: generate-test-secret install-debug-all-features +test-chunkah-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ {{ should_push }} \ @@ -251,7 +260,7 @@ test-chunkah-build: generate-test-secret install-debug-all-features --chunkah \ recipes/recipe-chunkah.yml -test-build-chunked-oci-build: generate-test-secret install-debug-all-features +test-build-chunked-oci-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ {{ should_push }} \ @@ -260,7 +269,7 @@ test-build-chunked-oci-build: generate-test-secret install-debug-all-features --build-chunked-oci \ recipes/recipe-build-chunked-oci.yml -test-rechunk-build: generate-test-secret install-debug-all-features +test-rechunk-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ {{ should_push }} \ @@ -269,7 +278,7 @@ test-rechunk-build: generate-test-secret install-debug-all-features --rechunk \ recipes/recipe-rechunk.yml -test-fresh-rechunk-build: generate-test-secret install-debug-all-features +test-fresh-rechunk-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ {{ should_push }} \ @@ -280,7 +289,7 @@ test-fresh-rechunk-build: generate-test-secret install-debug-all-features recipes/recipe-rechunk.yml # Run arm integration test -test-arm64-build: generate-test-secret install-debug-all-features +test-arm64-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -291,7 +300,7 @@ test-arm64-build: generate-test-secret install-debug-all-features recipes/recipe-arm64.yml # Run docker driver external login integration test -test-docker-build-external-login: generate-test-secret install-debug-all-features +test-docker-build-external-login: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -302,7 +311,7 @@ test-docker-build-external-login: generate-test-secret install-debug-all-feature recipes/recipe-docker-external.yml # Run podman driver integration test -test-podman-build: generate-test-secret install-debug-all-features +test-podman-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -314,7 +323,7 @@ test-podman-build: generate-test-secret install-debug-all-features recipes/recipe-podman.yml # Run buildah driver integration test -test-buildah-build: generate-test-secret install-debug-all-features +test-buildah-build: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -328,7 +337,7 @@ test-buildah-build: generate-test-secret install-debug-all-features # Run the multi-platform builds test-multiplatform: test-multiplatform-docker test-multiplatform-podman test-multiplatform-buildah test-multiplatform-chunkah test-multiplatform-build-chunked-oci test-multiplatform-rechunk -test-multiplatform-docker: generate-test-secret install-debug-all-features +test-multiplatform-docker: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -339,7 +348,7 @@ test-multiplatform-docker: generate-test-secret install-debug-all-features -vv \ recipes/recipe-multiplatform-docker.yml -test-multiplatform-podman: generate-test-secret install-debug-all-features +test-multiplatform-podman: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -350,7 +359,7 @@ test-multiplatform-podman: generate-test-secret install-debug-all-features -vv \ recipes/recipe-multiplatform-podman.yml -test-multiplatform-buildah: generate-test-secret install-debug-all-features +test-multiplatform-buildah: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -361,7 +370,7 @@ test-multiplatform-buildah: generate-test-secret install-debug-all-features -vv \ recipes/recipe-multiplatform-buildah.yml -test-multiplatform-chunkah: generate-test-secret install-debug-all-features +test-multiplatform-chunkah: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -373,7 +382,7 @@ test-multiplatform-chunkah: generate-test-secret install-debug-all-features -vv \ recipes/recipe-multiplatform-chunkah.yml -test-multiplatform-build-chunked-oci: generate-test-secret install-debug-all-features +test-multiplatform-build-chunked-oci: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -385,7 +394,7 @@ test-multiplatform-build-chunked-oci: generate-test-secret install-debug-all-fea -vv \ recipes/recipe-multiplatform-build-chunked-oci.yml -test-multiplatform-rechunk: generate-test-secret install-debug-all-features +test-multiplatform-rechunk: generate-test-secret install-debug cd integration-tests/test-repo \ && {{ cargo_bin }} build \ --retry-push \ @@ -397,21 +406,21 @@ test-multiplatform-rechunk: generate-test-secret install-debug-all-features recipes/recipe-multiplatform-rechunk.yml # Run ISO generator for images -test-generate-iso-image: generate-test-secret install-debug-all-features +test-generate-iso-image: generate-test-secret install-debug #!/usr/bin/env bash set -eu ISO_OUT=$(mktemp -d) {{ cargo_bin }} generate-iso -vv --output-dir "$ISO_OUT" image ghcr.io/{{ project_path }}/test:latest # Run ISO generator for images using web-ui -test-generate-iso-web-ui: generate-test-secret install-debug-all-features +test-generate-iso-web-ui: generate-test-secret install-debug #!/usr/bin/env bash set -eu ISO_OUT=$(mktemp -d) {{ cargo_bin }} generate-iso -vv --output-dir "$ISO_OUT" --web-ui image ghcr.io/{{ project_path }}/test:latest # Run ISO generator for images -test-generate-iso-recipe: generate-test-secret install-debug-all-features +test-generate-iso-recipe: generate-test-secret install-debug #!/usr/bin/env bash set -eu ISO_OUT=$(mktemp -d) diff --git a/next/src/lib.rs b/next/src/lib.rs index ca666747..a895ecbf 100644 --- a/next/src/lib.rs +++ b/next/src/lib.rs @@ -8,7 +8,7 @@ //! #![doc = include_str!("../LGPL_2.1.txt")] -mod build_scripts; +pub mod build_scripts; pub mod layer; pub mod path; pub mod reference; diff --git a/next/tests/repo/recipes/recipe-v2.yml b/next/tests/repo/recipes/recipe-v2.yml new file mode 100644 index 00000000..0dc2cd78 --- /dev/null +++ b/next/tests/repo/recipes/recipe-v2.yml @@ -0,0 +1,48 @@ +--- +# yaml-language-server: $schema=https://schema.blue-build.org/recipe.json +base: + image: + registry: ghcr.io + repository: blue-build/base-images + tag: 44 + public-key: https://github.com/blue-build/base-images/raw/refs/heads/main/cosign.pub +metadata: + name: cli/test-next-gen + description: Test recipe for the BlueBuild Next Gen Builder + labels: + org.bluebuild.cli.test: "true" + tags: + - v2 +spec: + platforms: + - linux/amd64 + - linux/arm64 + tool-versions: + bluebuild: main +modules: + - type: files + files: + - source: system + destination: / + - type: dnf + repos: + copr: + - atim/starship + install: + packages: + - micro + - starship + remove: + packages: + - firefox + - firefox-langpacks + - type: default-flatpaks + configurations: + - notify: true + scope: system + install: + - org.mozilla.firefox + - org.gnome.Loupe + - scope: user + - type: signing +version: 2 diff --git a/next/tests/repo/recipes/recipe.yml b/next/tests/repo/recipes/recipe.yml index f1388d46..206b727f 100644 --- a/next/tests/repo/recipes/recipe.yml +++ b/next/tests/repo/recipes/recipe.yml @@ -1,21 +1,14 @@ --- # yaml-language-server: $schema=https://schema.blue-build.org/recipe-v1.json -# image will be published to ghcr.io// name: cli/test-next-gen -# description will be included in the image's metadata description: Test recipe for the BlueBuild Next Gen Builder - -# the base image to build on top of (FROM) and the version tag to use -base-image: ghcr.io/ublue-os/silverblue-main -image-version: latest # You can pin to a specific version of Fedora as well - -# module configuration, executed in order -# you can include multiple instances of the same module +base-image: ghcr.io/blue-build/base-images/fedora-kinoite +image-version: latest modules: - type: files files: - source: system - destination: / # copies files/system/* (* means everything inside it) into your image's root folder / + destination: / - type: dnf repos: @@ -27,19 +20,16 @@ modules: - starship remove: packages: - # example: removing firefox (in favor of the flatpak) - # "firefox" is the main package, "firefox-langpacks" is a dependency - firefox - - firefox-langpacks # also remove firefox dependency (not required for all packages, this is a special case) + - firefox-langpacks - type: default-flatpaks configurations: - - notify: true # Send notification after install/uninstall is finished (true/false) + - notify: true scope: system - # If no repo information is specified, Flathub will be used by default - install: # system flatpaks we want all users to have and not remove + install: - org.mozilla.firefox - org.gnome.Loupe - - scope: user # Also add Flathub user repo, but no user packages + - scope: user - - type: signing # this sets up the proper policy & signing files for signed images to work fully + - type: signing diff --git a/process/Cargo.toml b/process/Cargo.toml index 8c6692a5..f580b996 100644 --- a/process/Cargo.toml +++ b/process/Cargo.toml @@ -52,3 +52,4 @@ workspace = true [features] bootc = [] +next-builder = [] diff --git a/process/drivers.rs b/process/drivers.rs index fbde4eeb..2033a763 100644 --- a/process/drivers.rs +++ b/process/drivers.rs @@ -8,7 +8,6 @@ use std::{ borrow::Borrow, - fmt::Debug, process::{ExitStatus, Output}, sync::{LazyLock, RwLock, atomic::AtomicBool}, time::Duration, @@ -16,15 +15,11 @@ use std::{ use blue_build_utils::{ BUILD_ID, - constants::{ - BB_BOOT_DRIVER, BB_BUILD_DRIVER, BB_INSPECT_DRIVER, BB_RUN_DRIVER, BB_SIGNING_DRIVER, - }, - container::{ContainerId, ImageRef, MountId, Tag}, + container::{ContainerId, Tag}, semver::Version, }; -use bon::{Builder, bon}; +use bon::bon; use cached::cached; -use clap::Args; use colored::Colorize; use indicatif::{ProgressBar, ProgressStyle}; use log::{info, trace, warn}; @@ -32,25 +27,26 @@ use miette::{Context, Result, bail}; use oci_client::Reference; use uuid::Uuid; -use crate::{ASYNC_RUNTIME, logging::Logger, signal_handler::DetachedContainer}; -use opts::{ - BuildChunkedOciOpts, BuildOpts, BuildRechunkTagPushOpts, BuildTagPushOpts, CheckKeyPairOpts, - ContainerOpts, CopyOciOpts, CreateContainerOpts, GenerateImageNameOpts, GenerateKeyPairOpts, - GenerateTagsOpts, GetMetadataOpts, InspectImageOpts, ManifestCreateOpts, ManifestPushOpts, - PostBuildDriverOpts, PruneOpts, PullOpts, PushOpts, RechunkOpts, RemoveContainerOpts, - RemoveImageOpts, RunOpts, SignOpts, SwitchOpts, TagOpts, UntagOpts, VerifyOpts, VolumeOpts, +use crate::{ + ASYNC_RUNTIME, + drivers::opts::{InspectImageOpts, RemoveImageOpts}, + logging::Logger, + signal_handler::DetachedContainer, }; -use types::{ - BootDriverType, BuildDriverType, CiDriverType, ImageMetadata, InspectDriverType, RunDriverType, - SigningDriverType, +use opts::{ + CheckKeyPairOpts, CreateContainerOpts, GenerateImageNameOpts, GenerateKeyPairOpts, + GenerateTagsOpts, GetMetadataOpts, RemoveContainerOpts, RunOpts, SignOpts, SwitchOpts, + VerifyOpts, }; +use types::{BootDriverType, CiDriverType, ImageMetadata}; + +#[cfg(not(feature = "next-builder"))] +use blue_build_utils::container::{ImageRef, MountId}; pub use self::{ - buildah_driver::BuildahDriver, cosign_driver::CosignDriver, docker_driver::DockerDriver, github_driver::GithubDriver, gitlab_driver::GitlabDriver, local_driver::LocalDriver, oci_client_driver::OciClientDriver, podman_driver::PodmanDriver, - rpm_ostree_driver::RpmOstreeDriver, rpm_ostree_runner::RpmOstreeRunner, - sigstore_driver::SigstoreDriver, skopeo_driver::SkopeoDriver, traits::*, + sigstore_driver::SigstoreDriver, traits::*, }; #[cfg(feature = "bootc")] @@ -58,8 +54,11 @@ pub use bootc_driver::BootcDriver; #[cfg(feature = "bootc")] mod bootc_driver; +#[cfg(not(feature = "next-builder"))] mod buildah_driver; +#[cfg(not(feature = "next-builder"))] mod cosign_driver; +#[cfg(not(feature = "next-builder"))] mod docker_driver; mod github_driver; mod gitlab_driver; @@ -67,20 +66,27 @@ mod local_driver; mod oci_client_driver; pub mod opts; mod podman_driver; +#[cfg(not(feature = "next-builder"))] pub mod post_build; +#[cfg(not(feature = "next-builder"))] mod rpm_ostree_driver; +#[cfg(not(feature = "next-builder"))] mod rpm_ostree_runner; mod sigstore_driver; +#[cfg(not(feature = "next-builder"))] mod skopeo_driver; mod traits; pub mod types; static INIT: AtomicBool = AtomicBool::new(false); -static SELECTED_BUILD_DRIVER: LazyLock>> = +#[cfg(not(feature = "next-builder"))] +static SELECTED_BUILD_DRIVER: LazyLock>> = LazyLock::new(|| RwLock::new(None)); -static SELECTED_RUN_DRIVER: LazyLock>> = +#[cfg(not(feature = "next-builder"))] +static SELECTED_RUN_DRIVER: LazyLock>> = LazyLock::new(|| RwLock::new(None)); -static SELECTED_SIGNING_DRIVER: LazyLock>> = +#[cfg(not(feature = "next-builder"))] +static SELECTED_SIGNING_DRIVER: LazyLock>> = LazyLock::new(|| RwLock::new(None)); static SELECTED_CI_DRIVER: LazyLock>> = LazyLock::new(|| RwLock::new(None)); @@ -91,30 +97,31 @@ static SELECTED_BOOT_DRIVER: LazyLock>> = /// /// If the args are left uninitialized, the program will determine /// the best one available. -#[derive(Default, Clone, Copy, Debug, Builder, Args)] +#[cfg(not(feature = "next-builder"))] +#[derive(Default, Clone, Copy, Debug, bon::Builder, clap::Args)] pub struct DriverArgs { /// Select which driver to use to build /// your image. - #[arg(short = 'B', long, env = BB_BUILD_DRIVER)] - pub build_driver: Option, + #[arg(short = 'B', long, env = blue_build_utils::constants::BB_BUILD_DRIVER)] + pub build_driver: Option, /// Select which driver to use to inspect /// images. - #[arg(short = 'I', long, env = BB_INSPECT_DRIVER)] - pub inspect_driver: Option, + #[arg(short = 'I', long, env = blue_build_utils::constants::BB_INSPECT_DRIVER)] + pub inspect_driver: Option, /// Select which driver to use to sign /// images. - #[arg(short = 'S', long, env = BB_SIGNING_DRIVER)] - pub signing_driver: Option, + #[arg(short = 'S', long, env = blue_build_utils::constants::BB_SIGNING_DRIVER)] + pub signing_driver: Option, /// Select which driver to use to run /// containers. - #[arg(short = 'R', long, env = BB_RUN_DRIVER)] - pub run_driver: Option, + #[arg(short = 'R', long, env = blue_build_utils::constants::BB_RUN_DRIVER)] + pub run_driver: Option, - #[arg(short = 'T', long, env = BB_BOOT_DRIVER)] - pub boot_driver: Option, + #[arg(short = 'T', long, env = blue_build_utils::constants::BB_BOOT_DRIVER)] + pub boot_driver: Option, } macro_rules! impl_driver_type { @@ -174,13 +181,15 @@ impl Driver { /// /// # Panics /// Will panic if it is unable to initialize drivers. - pub fn init(mut args: DriverArgs) { + pub fn init(#[cfg(not(feature = "next-builder"))] mut args: DriverArgs) { trace!("Driver::init()"); + #[cfg(not(feature = "next-builder"))] if args.inspect_driver.is_some() { warn!("Setting the inspect driver is deprecated."); } + #[cfg(not(feature = "next-builder"))] impl_driver_init! { INIT; args.build_driver => SELECTED_BUILD_DRIVER; @@ -189,6 +198,11 @@ impl Driver { args.boot_driver => SELECTED_BOOT_DRIVER; default => SELECTED_CI_DRIVER; } + #[cfg(feature = "next-builder")] + impl_driver_init! { + INIT; + default => SELECTED_CI_DRIVER; + } } /// Gets the current build's UUID @@ -248,25 +262,46 @@ impl Driver { Ok(os_version.major) } - pub fn get_build_driver() -> BuildDriverType { + #[cfg(not(feature = "next-builder"))] + pub fn get_build_driver() -> types::BuildDriverType { impl_driver_type!(SELECTED_BUILD_DRIVER) } - pub fn get_signing_driver() -> SigningDriverType { + #[cfg(not(feature = "next-builder"))] + pub fn get_signing_driver() -> types::SigningDriverType { impl_driver_type!(SELECTED_SIGNING_DRIVER) } - pub fn get_run_driver() -> RunDriverType { + #[cfg(not(feature = "next-builder"))] + pub fn get_run_driver() -> types::RunDriverType { impl_driver_type!(SELECTED_RUN_DRIVER) } - pub fn get_ci_driver() -> CiDriverType { + pub fn get_ci_driver() -> types::CiDriverType { impl_driver_type!(SELECTED_CI_DRIVER) } - pub fn get_boot_driver() -> BootDriverType { + pub fn get_boot_driver() -> types::BootDriverType { impl_driver_type!(SELECTED_BOOT_DRIVER) } + + /// Runs the login logic for the driver. + /// + /// # Errors + /// Will error if login fails. + #[cfg(feature = "next-builder")] + pub fn login(server: &str) -> Result<()> { + PodmanDriver::login(server) + } + + /// Runs prune commands for the driver. + /// + /// # Errors + /// Will error if the driver fails to prune. + #[cfg(feature = "next-builder")] + pub fn prune(opts: opts::PruneOpts) -> Result<()> { + PodmanDriver::prune(opts) + } } #[cached( @@ -290,7 +325,8 @@ fn get_version_run_image(oci_ref: &Reference) -> Result { ); progress.enable_steady_tick(Duration::from_millis(100)); - let should_remove = if matches!(Driver::get_run_driver(), RunDriverType::Docker) { + #[cfg(not(feature = "next-builder"))] + let should_remove = if matches!(Driver::get_run_driver(), types::RunDriverType::Docker) { !Driver::list_images(false)?.contains(oci_ref) } else { false @@ -327,6 +363,7 @@ fn get_version_run_image(oci_ref: &Reference) -> Result { ); } + #[cfg(not(feature = "next-builder"))] if should_remove { Driver::remove_image(RemoveImageOpts::builder().image(oci_ref).build())?; } @@ -337,48 +374,71 @@ fn get_version_run_image(oci_ref: &Reference) -> Result { String::from_utf8_lossy(&output.stdout).trim().parse() } +#[cfg(not(feature = "next-builder"))] macro_rules! impl_build_driver { ($func:ident($($args:expr),*)) => { match Self::get_build_driver() { - BuildDriverType::Buildah => BuildahDriver::$func($($args,)*), - BuildDriverType::Podman => PodmanDriver::$func($($args,)*), - BuildDriverType::Docker => DockerDriver::$func($($args,)*), + types::BuildDriverType::Buildah => buildah_driver::BuildahDriver::$func($($args,)*), + types::BuildDriverType::Podman => PodmanDriver::$func($($args,)*), + types::BuildDriverType::Docker => docker_driver::DockerDriver::$func($($args,)*), } }; } impl ImageStorageDriver for Driver { fn inspect_image(opts: InspectImageOpts) -> Result>> { - impl_build_driver!(inspect_image(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_build_driver!(inspect_image(opts)) + } + #[cfg(feature = "next-builder")] + { + PodmanDriver::inspect_image(opts) + } } fn remove_image(opts: RemoveImageOpts) -> Result<()> { - impl_build_driver!(remove_image(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_build_driver!(remove_image(opts)) + } + #[cfg(feature = "next-builder")] + { + PodmanDriver::remove_image(opts) + } } fn list_images(privileged: bool) -> Result> { - impl_build_driver!(list_images(privileged)) + #[cfg(not(feature = "next-builder"))] + { + impl_build_driver!(list_images(privileged)) + } + #[cfg(feature = "next-builder")] + { + PodmanDriver::list_images(privileged) + } } } +#[cfg(not(feature = "next-builder"))] impl BuildDriver for Driver { - fn build(opts: BuildOpts) -> Result<()> { + fn build(opts: opts::BuildOpts) -> Result<()> { impl_build_driver!(build(opts)) } - fn tag(opts: TagOpts) -> Result<()> { + fn tag(opts: opts::TagOpts) -> Result<()> { impl_build_driver!(tag(opts)) } - fn untag(opts: UntagOpts) -> Result<()> { + fn untag(opts: opts::UntagOpts) -> Result<()> { impl_build_driver!(untag(opts)) } - fn push(opts: PushOpts) -> Result<()> { + fn push(opts: opts::PushOpts) -> Result<()> { impl_build_driver!(push(opts)) } - fn pull(opts: PullOpts) -> Result { + fn pull(opts: opts::PullOpts) -> Result { impl_build_driver!(pull(opts)) } @@ -386,60 +446,97 @@ impl BuildDriver for Driver { impl_build_driver!(login(server)) } - fn prune(opts: PruneOpts) -> Result<()> { + fn prune(opts: opts::PruneOpts) -> Result<()> { impl_build_driver!(prune(opts)) } - fn manifest_create(opts: ManifestCreateOpts) -> Result<()> { + fn manifest_create(opts: opts::ManifestCreateOpts) -> Result<()> { impl_build_driver!(manifest_create(opts)) } - fn manifest_push(opts: ManifestPushOpts) -> Result<()> { + fn manifest_push(opts: opts::ManifestPushOpts) -> Result<()> { impl_build_driver!(manifest_push(opts)) } - fn build_tag_push(opts: BuildTagPushOpts) -> Result> { + fn build_tag_push(opts: opts::BuildTagPushOpts) -> Result> { impl_build_driver!(build_tag_push(opts)) } } +#[cfg(not(feature = "next-builder"))] impl PostBuildDriver for Driver { fn build_tag_push_with_post_build( - opts: BuildTagPushOpts, - pb_opts: PostBuildDriverOpts, + opts: opts::BuildTagPushOpts, + pb_opts: opts::PostBuildDriverOpts, ) -> Result> { PodmanDriver::build_tag_push_with_post_build(opts, pb_opts) } } +#[cfg(not(feature = "next-builder"))] macro_rules! impl_signing_driver { ($func:ident($($args:expr),*)) => { match Self::get_signing_driver() { - SigningDriverType::Cosign => CosignDriver::$func($($args,)*), - SigningDriverType::Sigstore => SigstoreDriver::$func($($args,)*), + types::SigningDriverType::Cosign => cosign_driver::CosignDriver::$func($($args,)*), + types::SigningDriverType::Sigstore => sigstore_driver::SigstoreDriver::$func($($args,)*), } }; } impl SigningDriver for Driver { fn generate_key_pair(opts: GenerateKeyPairOpts) -> Result<()> { - impl_signing_driver!(generate_key_pair(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_signing_driver!(generate_key_pair(opts)) + } + #[cfg(feature = "next-builder")] + { + SigstoreDriver::generate_key_pair(opts) + } } fn check_signing_files(opts: CheckKeyPairOpts) -> Result<()> { - impl_signing_driver!(check_signing_files(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_signing_driver!(check_signing_files(opts)) + } + #[cfg(feature = "next-builder")] + { + SigstoreDriver::check_signing_files(opts) + } } fn sign(opts: SignOpts) -> Result<()> { - impl_signing_driver!(sign(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_signing_driver!(sign(opts)) + } + #[cfg(feature = "next-builder")] + { + SigstoreDriver::sign(opts) + } } fn verify(opts: VerifyOpts) -> Result<()> { - impl_signing_driver!(verify(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_signing_driver!(verify(opts)) + } + #[cfg(feature = "next-builder")] + { + SigstoreDriver::verify(opts) + } } fn signing_login(server: &str) -> Result<()> { - impl_signing_driver!(signing_login(server)) + #[cfg(not(feature = "next-builder"))] + { + impl_signing_driver!(signing_login(server)) + } + #[cfg(feature = "next-builder")] + { + SigstoreDriver::signing_login(server) + } } } @@ -449,34 +546,70 @@ impl InspectDriver for Driver { } } +#[cfg(not(feature = "next-builder"))] macro_rules! impl_run_driver { ($func:ident($($args:expr),*)) => { match Self::get_run_driver() { - RunDriverType::Docker => DockerDriver::$func($($args,)*), - RunDriverType::Podman => PodmanDriver::$func($($args,)*), + types::RunDriverType::Docker => docker_driver::DockerDriver::$func($($args,)*), + types::RunDriverType::Podman => PodmanDriver::$func($($args,)*), } }; } impl RunDriver for Driver { fn run(opts: RunOpts) -> Result { - impl_run_driver!(run(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_run_driver!(run(opts)) + } + #[cfg(feature = "next-builder")] + { + PodmanDriver::run(opts) + } } fn run_output(opts: RunOpts) -> Result { - impl_run_driver!(run_output(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_run_driver!(run_output(opts)) + } + #[cfg(feature = "next-builder")] + { + PodmanDriver::run_output(opts) + } } fn run_detached(opts: RunOpts) -> Result { - impl_run_driver!(run_detached(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_run_driver!(run_detached(opts)) + } + #[cfg(feature = "next-builder")] + { + PodmanDriver::run_detached(opts) + } } fn create_container(opts: CreateContainerOpts) -> Result { - impl_run_driver!(create_container(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_run_driver!(create_container(opts)) + } + #[cfg(feature = "next-builder")] + { + PodmanDriver::create_container(opts) + } } fn remove_container(opts: RemoveContainerOpts) -> Result<()> { - impl_run_driver!(remove_container(opts)) + #[cfg(not(feature = "next-builder"))] + { + impl_run_driver!(remove_container(opts)) + } + #[cfg(feature = "next-builder")] + { + PodmanDriver::remove_container(opts) + } } } @@ -527,62 +660,75 @@ impl CiDriver for Driver { } } +#[cfg(not(feature = "next-builder"))] impl BuildChunkedOciDriver for Driver { fn manifest_create_with_runner( - runner: &RpmOstreeRunner, - opts: ManifestCreateOpts, + runner: &rpm_ostree_runner::RpmOstreeRunner, + opts: opts::ManifestCreateOpts, ) -> Result<()> { PodmanDriver::manifest_create_with_runner(runner, opts) } - fn manifest_push_with_runner(runner: &RpmOstreeRunner, opts: ManifestPushOpts) -> Result<()> { + fn manifest_push_with_runner( + runner: &rpm_ostree_runner::RpmOstreeRunner, + opts: opts::ManifestPushOpts, + ) -> Result<()> { PodmanDriver::manifest_push_with_runner(runner, opts) } - fn pull_with_runner(runner: &RpmOstreeRunner, opts: PullOpts) -> Result { + fn pull_with_runner( + runner: &rpm_ostree_runner::RpmOstreeRunner, + opts: opts::PullOpts, + ) -> Result { PodmanDriver::pull_with_runner(runner, opts) } - fn remove_image_with_runner(runner: &RpmOstreeRunner, image_ref: &str) -> Result<()> { + fn remove_image_with_runner( + runner: &rpm_ostree_runner::RpmOstreeRunner, + image_ref: &str, + ) -> Result<()> { PodmanDriver::remove_image_with_runner(runner, image_ref) } fn build_chunked_oci( - runner: &RpmOstreeRunner, + runner: &rpm_ostree_runner::RpmOstreeRunner, unchunked_image: &ImageRef<'_>, final_image: &ImageRef<'_>, - opts: BuildChunkedOciOpts, + opts: opts::BuildChunkedOciOpts, ) -> Result<()> { PodmanDriver::build_chunked_oci(runner, unchunked_image, final_image, opts) } - fn build_rechunk_tag_push(opts: BuildRechunkTagPushOpts) -> Result> { + fn build_rechunk_tag_push(opts: opts::BuildRechunkTagPushOpts) -> Result> { PodmanDriver::build_rechunk_tag_push(opts) } } +#[cfg(not(feature = "next-builder"))] impl ContainerMountDriver for Driver { - fn mount_container(opts: ContainerOpts) -> Result { + fn mount_container(opts: opts::ContainerOpts) -> Result { PodmanDriver::mount_container(opts) } - fn unmount_container(opts: ContainerOpts) -> Result<()> { + fn unmount_container(opts: opts::ContainerOpts) -> Result<()> { PodmanDriver::unmount_container(opts) } - fn remove_volume(opts: VolumeOpts) -> Result<()> { + fn remove_volume(opts: opts::VolumeOpts) -> Result<()> { PodmanDriver::remove_volume(opts) } } +#[cfg(not(feature = "next-builder"))] impl OciCopy for Driver { - fn copy_oci(&self, opts: CopyOciOpts) -> Result<()> { - SkopeoDriver.copy_oci(opts) + fn copy_oci(&self, opts: opts::CopyOciOpts) -> Result<()> { + skopeo_driver::SkopeoDriver.copy_oci(opts) } } +#[cfg(not(feature = "next-builder"))] impl RechunkDriver for Driver { - fn rechunk(opts: RechunkOpts) -> Result> { + fn rechunk(opts: opts::RechunkOpts) -> Result> { PodmanDriver::rechunk(opts) } } @@ -592,7 +738,8 @@ macro_rules! impl_boot_driver { match Self::get_boot_driver() { #[cfg(feature = "bootc")] BootDriverType::Bootc => BootcDriver::$func($($args,)*), - BootDriverType::RpmOstree => RpmOstreeDriver::$func($($args,)*), + #[cfg(not(feature = "next-builder"))] + BootDriverType::RpmOstree => rpm_ostree_driver::RpmOstreeDriver::$func($($args,)*), BootDriverType::None => { ::miette::bail!("Cannot perform boot operation when no boot driver exists."); }, diff --git a/process/drivers/opts.rs b/process/drivers/opts.rs index a17c5ade..3aca9eb5 100644 --- a/process/drivers/opts.rs +++ b/process/drivers/opts.rs @@ -1,25 +1,36 @@ +use bon::Builder; use clap::ValueEnum; pub use boot::*; +#[cfg(not(feature = "next-builder"))] pub use build::*; +#[cfg(not(feature = "next-builder"))] pub use build_chunked_oci::*; pub use ci::*; pub use image_storage::*; pub use inspect::*; +#[cfg(not(feature = "next-builder"))] pub use oci_copy::*; +#[cfg(not(feature = "next-builder"))] pub use post_build::*; +#[cfg(not(feature = "next-builder"))] pub use rechunk::*; pub use run::*; pub use signing::*; mod boot; +#[cfg(not(feature = "next-builder"))] mod build; +#[cfg(not(feature = "next-builder"))] mod build_chunked_oci; mod ci; mod image_storage; mod inspect; +#[cfg(not(feature = "next-builder"))] mod oci_copy; +#[cfg(not(feature = "next-builder"))] mod post_build; +#[cfg(not(feature = "next-builder"))] mod rechunk; mod run; mod signing; @@ -39,3 +50,13 @@ impl std::fmt::Display for CompressionType { }) } } + +#[derive(Debug, Clone, Copy, Builder)] +#[builder(derive(Debug, Clone))] +pub struct PruneOpts { + #[builder(default)] + pub all: bool, + + #[builder(default)] + pub volumes: bool, +} diff --git a/process/drivers/opts/build.rs b/process/drivers/opts/build.rs index ac6a3a90..b35e7876 100644 --- a/process/drivers/opts/build.rs +++ b/process/drivers/opts/build.rs @@ -78,16 +78,6 @@ pub struct PullOpts<'scope> { pub privileged: bool, } -#[derive(Debug, Clone, Copy, Builder)] -#[builder(derive(Debug, Clone))] -pub struct PruneOpts { - #[builder(default)] - pub all: bool, - - #[builder(default)] - pub volumes: bool, -} - #[derive(Debug, Clone, Copy, Builder)] #[builder(derive(Debug, Clone))] pub struct ManifestCreateOpts<'scope> { diff --git a/process/drivers/podman_driver.rs b/process/drivers/podman_driver.rs index b7154b1b..60a5c052 100644 --- a/process/drivers/podman_driver.rs +++ b/process/drivers/podman_driver.rs @@ -3,43 +3,54 @@ use std::{ ops::Not, path::Path, process::{Command, ExitStatus, Stdio}, - time::Duration, }; use blue_build_utils::{ - constants::USER, - container::{ContainerId, ImageRef, MountId}, - credentials::Credentials, - get_env_var, - platform::Platform, - secret::SecretArgs, - semver::Version, - string_vec, sudo_cmd, tempdir, + constants::USER, container::ContainerId, credentials::Credentials, get_env_var, + semver::Version, sudo_cmd, tempdir, }; use colored::Colorize; use comlexr::{cmd, pipe}; -use log::{debug, error, info, trace, warn}; -use miette::{Context, IntoDiagnostic, Result, bail}; +use log::{debug, error, trace}; +use miette::{IntoDiagnostic, Result, bail}; use oci_client::Reference; -use rayon::prelude::*; use serde::Deserialize; use super::{ - BuildChunkedOciDriver, BuildDriver, ContainerMountDriver, DriverVersion, ImageStorageDriver, - PostBuildDriver, RechunkDriver, RunDriver, - opts::{ - BuildOpts, BuildTagPushOpts, ContainerOpts, CreateContainerOpts, InspectImageOpts, - ManifestCreateOpts, ManifestPushOpts, PostBuildDriverOpts, PostBuildOpts, PruneOpts, - PullOpts, PushOpts, RemoveContainerOpts, RemoveImageOpts, RunOpts, RunOptsEnv, - RunOptsVolume, TagOpts, UntagOpts, VolumeOpts, - }, - rpm_ostree_runner::RpmOstreeRunner, + DriverVersion, ImageStorageDriver, RunDriver, + opts::{CreateContainerOpts, RemoveContainerOpts, RunOpts, RunOptsEnv, RunOptsVolume}, }; use crate::{ + drivers::opts::{InspectImageOpts, PruneOpts, RemoveImageOpts}, logging::CommandLogging, signal_handler::{ContainerRuntime, ContainerSignalId, DetachedContainer, add_cid, remove_cid}, }; +#[cfg(not(feature = "next-builder"))] +use crate::drivers::{ + BuildChunkedOciDriver, BuildDriver, ContainerMountDriver, PostBuildDriver, RechunkDriver, + opts::{ + BuildOpts, BuildTagPushOpts, ContainerOpts, ManifestCreateOpts, ManifestPushOpts, + PostBuildDriverOpts, PostBuildOpts, PullOpts, PushOpts, TagOpts, UntagOpts, VolumeOpts, + }, + rpm_ostree_runner::RpmOstreeRunner, +}; +#[cfg(not(feature = "next-builder"))] +use blue_build_utils::{ + container::{ImageRef, MountId}, + platform::Platform, + secret::SecretArgs, + string_vec, +}; +#[cfg(not(feature = "next-builder"))] +use log::{info, warn}; +#[cfg(not(feature = "next-builder"))] +use miette::WrapErr; +#[cfg(not(feature = "next-builder"))] +use rayon::prelude::*; +#[cfg(not(feature = "next-builder"))] +use std::time::Duration; + const SUDO_PROMPT: &str = "Password for %u required to run 'podman' as privileged"; #[derive(Debug, Deserialize)] @@ -92,6 +103,7 @@ impl PodmanDriver { Ok(()) } + #[cfg(not(feature = "next-builder"))] pub(crate) fn get_podman_info(fmt: &str) -> Result { let output = cmd!("podman", "info", format!("--format={fmt}")) .output() @@ -104,6 +116,24 @@ impl PodmanDriver { String::from_utf8(stdout).into_diagnostic() } + /// Runs the login logic for the driver. + /// + /// # Errors + /// Will error if login fails. + #[cfg(feature = "next-builder")] + pub fn login(server: &str) -> Result<()> { + login(server) + } + + /// Runs prune commands for the driver. + /// + /// # Errors + /// Will error if the driver fails to prune. + #[cfg(feature = "next-builder")] + pub fn prune(opts: PruneOpts) -> Result<()> { + prune(opts) + } + /// Push a manifest list to a remote registry, applying workarounds for the following bug: /// https://github.com/containers/podman/issues/27796 /// This ensures that layer annotations are preserved by pushing. @@ -119,6 +149,7 @@ impl PodmanDriver { /// /// # Errors /// Returns an error if any of the container operations fails. + #[cfg(not(feature = "next-builder"))] pub(crate) fn manifest_push_with_layer_annotation_bug_workaround( opts: ManifestPushOpts, podman_in_podman_container: Option<&DetachedContainer>, @@ -188,6 +219,7 @@ impl DriverVersion for PodmanDriver { } } +#[cfg(not(feature = "next-builder"))] impl BuildDriver for PodmanDriver { fn build(opts: BuildOpts) -> Result<()> { trace!("PodmanDriver::build({opts:#?})"); @@ -388,59 +420,11 @@ impl BuildDriver for PodmanDriver { } fn login(server: &str) -> Result<()> { - trace!("PodmanDriver::login()"); - - if let Some(Credentials::Basic { username, password }) = Credentials::get(server) { - let output = pipe!( - stdin = password.value(); - { - let c = cmd!( - "podman", - "login", - "-u", - &username, - "--password-stdin", - server, - ); - trace!("{c:?}"); - c - } - ) - .output() - .into_diagnostic()?; - - if !output.status.success() { - let err_out = String::from_utf8_lossy(&output.stderr); - bail!("Failed to login for podman:\n{}", err_out.trim()); - } - debug!("Logged into {server}"); - } - Ok(()) + login(server) } fn prune(opts: PruneOpts) -> Result<()> { - trace!("PodmanDriver::prune({opts:?})"); - - let status = { - let c = cmd!( - "podman", - "system", - "prune", - "--force", - if opts.all => "--all", - if opts.volumes => "--volumes", - ); - trace!("{c:?}"); - c - } - .message_status("podman system prune", "Pruning Podman System") - .into_diagnostic()?; - - if !status.success() { - bail!("Failed to prune podman"); - } - - Ok(()) + prune(opts) } fn manifest_create(opts: ManifestCreateOpts) -> Result<()> { @@ -512,6 +496,7 @@ impl BuildDriver for PodmanDriver { } } +#[cfg(not(feature = "next-builder"))] impl PostBuildDriver for PodmanDriver { #[expect(clippy::too_many_lines)] fn build_tag_push_with_post_build( @@ -672,6 +657,7 @@ impl PostBuildDriver for PodmanDriver { } } +#[cfg(not(feature = "next-builder"))] impl BuildChunkedOciDriver for PodmanDriver { fn manifest_create_with_runner( runner: &RpmOstreeRunner, @@ -797,6 +783,7 @@ impl BuildChunkedOciDriver for PodmanDriver { } } +#[cfg(not(feature = "next-builder"))] impl ContainerMountDriver for PodmanDriver { fn mount_container(opts: ContainerOpts) -> Result { let output = { @@ -868,6 +855,7 @@ impl ContainerMountDriver for PodmanDriver { } } +#[cfg(not(feature = "next-builder"))] impl RechunkDriver for PodmanDriver {} impl RunDriver for PodmanDriver { @@ -1106,3 +1094,59 @@ fn podman_run(opts: RunOpts, cid_file: &Path, detach: bool) -> Command { command } + +fn login(server: &str) -> Result<()> { + trace!("PodmanDriver::login()"); + + if let Some(Credentials::Basic { username, password }) = Credentials::get(server) { + let output = pipe!( + stdin = password.value(); + { + let c = cmd!( + "podman", + "login", + "-u", + &username, + "--password-stdin", + server, + ); + trace!("{c:?}"); + c + } + ) + .output() + .into_diagnostic()?; + + if !output.status.success() { + let err_out = String::from_utf8_lossy(&output.stderr); + bail!("Failed to login for podman:\n{}", err_out.trim()); + } + debug!("Logged into {server}"); + } + Ok(()) +} + +fn prune(opts: PruneOpts) -> Result<()> { + trace!("PodmanDriver::prune({opts:?})"); + + let status = { + let c = cmd!( + "podman", + "system", + "prune", + "--force", + if opts.all => "--all", + if opts.volumes => "--volumes", + ); + trace!("{c:?}"); + c + } + .message_status("podman system prune", "Pruning Podman System") + .into_diagnostic()?; + + if !status.success() { + bail!("Failed to prune podman"); + } + + Ok(()) +} diff --git a/process/drivers/post_build/chunkah.rs b/process/drivers/post_build/chunkah.rs index 23fc9b21..bdea0708 100644 --- a/process/drivers/post_build/chunkah.rs +++ b/process/drivers/post_build/chunkah.rs @@ -13,9 +13,9 @@ use oci_client::Reference; use crate::{ drivers::{ - BuildDriver, BuildDriverType, Driver, ImageStorageDriver, OciCopy, PodmanDriver, PostBuild, - PostBuildRunner, + BuildDriver, Driver, ImageStorageDriver, OciCopy, PodmanDriver, PostBuild, PostBuildRunner, opts::{CopyOciOpts, InspectImageOpts, PostBuildOpts, PullOpts}, + types::BuildDriverType, }, logging::CommandLogging, signal_handler::{ContainerRuntime, ContainerSignalId, add_cid, remove_cid}, diff --git a/process/drivers/sigstore_driver.rs b/process/drivers/sigstore_driver.rs index fb7900fd..7b9141a8 100644 --- a/process/drivers/sigstore_driver.rs +++ b/process/drivers/sigstore_driver.rs @@ -262,7 +262,6 @@ mod test { use crate::drivers::{ SigningDriver, - cosign_driver::CosignDriver, opts::{CheckKeyPairOpts, GenerateKeyPairOpts}, }; @@ -300,6 +299,7 @@ mod test { } #[test] + #[cfg(not(feature = "next-builder"))] fn compatibility() { let tempdir = tempdir().unwrap(); @@ -317,7 +317,9 @@ mod test { fs::read_to_string(tempdir.path().join(COSIGN_PUB_PATH)).unwrap() ); - CosignDriver::check_signing_files(CheckKeyPairOpts::builder().dir(tempdir.path()).build()) - .unwrap(); + crate::drivers::cosign_driver::CosignDriver::check_signing_files( + CheckKeyPairOpts::builder().dir(tempdir.path()).build(), + ) + .unwrap(); } } diff --git a/process/drivers/traits.rs b/process/drivers/traits.rs index d16cae8f..1c4788ce 100644 --- a/process/drivers/traits.rs +++ b/process/drivers/traits.rs @@ -1,7 +1,5 @@ use std::{ borrow::Borrow, - fmt::Debug, - ops::Not, path::PathBuf, process::{ExitStatus, Output}, time::Duration, @@ -9,42 +7,59 @@ use std::{ use blue_build_utils::{ constants::COSIGN_PUB_PATH, - container::{ContainerId, ImageRef, MountId, OciRef, Tag}, - platform::Platform, + container::{ContainerId, ImageRef, Tag}, retry, semver::Version, - string_vec, tempdir, tempdir_in, }; -use comlexr::cmd; -use log::{debug, info, trace, warn}; +use log::{debug, trace}; use miette::{Context, IntoDiagnostic, Result, bail}; use oci_client::Reference; -use rayon::prelude::*; use semver::VersionReq; use super::{ Driver, opts::{ - BuildChunkedOciOpts, BuildOpts, BuildRechunkTagPushOpts, BuildTagPushOpts, - CheckKeyPairOpts, ContainerOpts, CopyOciOpts, CreateContainerOpts, GenerateImageNameOpts, - GenerateKeyPairOpts, GenerateTagsOpts, GetMetadataOpts, InspectImageOpts, - PostBuildDriverOpts, PostBuildOpts, PruneOpts, PullOpts, PushOpts, RechunkOpts, - RemoveContainerOpts, RemoveImageOpts, RunOpts, SignOpts, SignVerifyOpts, SwitchOpts, - TagOpts, UntagOpts, VerifyOpts, VerifyType, VolumeOpts, + CheckKeyPairOpts, CreateContainerOpts, GenerateImageNameOpts, GenerateKeyPairOpts, + GenerateTagsOpts, GetMetadataOpts, RemoveContainerOpts, RunOpts, SignOpts, SignVerifyOpts, + SwitchOpts, VerifyOpts, VerifyType, }, - opts::{ManifestCreateOpts, ManifestPushOpts}, - rpm_ostree_runner::RpmOstreeRunner, types::CiDriverType, - types::{ - BootDriverType, BuildDriverType, ImageMetadata, InspectDriverType, RunDriverType, - SigningDriverType, - }, + types::{BootDriverType, ImageMetadata, InspectDriverType, RunDriverType, SigningDriverType}, }; use crate::{ - ASYNC_RUNTIME, drivers::opts::PrivateKey, logging::CommandLogging, + ASYNC_RUNTIME, + drivers::opts::{InspectImageOpts, PrivateKey, RemoveImageOpts}, signal_handler::DetachedContainer, }; +#[cfg(not(feature = "next-builder"))] +use crate::{ + drivers::{ + opts::{ + BuildChunkedOciOpts, BuildOpts, BuildRechunkTagPushOpts, BuildTagPushOpts, + ContainerOpts, CopyOciOpts, ManifestCreateOpts, ManifestPushOpts, PostBuildDriverOpts, + PostBuildOpts, PruneOpts, PullOpts, PushOpts, RechunkOpts, TagOpts, UntagOpts, + VolumeOpts, + }, + rpm_ostree_runner::RpmOstreeRunner, + }, + logging::CommandLogging, +}; +#[cfg(not(feature = "next-builder"))] +use blue_build_utils::{ + container::{MountId, OciRef}, + platform::Platform, + string_vec, tempdir, tempdir_in, +}; +#[cfg(not(feature = "next-builder"))] +use comlexr::cmd; +#[cfg(not(feature = "next-builder"))] +use log::{info, warn}; +#[cfg(not(feature = "next-builder"))] +use rayon::prelude::*; +#[cfg(not(feature = "next-builder"))] +use std::{fmt::Debug, ops::Not}; + trait PrivateDriver {} macro_rules! impl_private_driver { @@ -57,21 +72,12 @@ macro_rules! impl_private_driver { impl_private_driver!( super::Driver, - super::docker_driver::DockerDriver, super::podman_driver::PodmanDriver, - super::buildah_driver::BuildahDriver, super::github_driver::GithubDriver, super::gitlab_driver::GitlabDriver, super::local_driver::LocalDriver, - super::cosign_driver::CosignDriver, - super::skopeo_driver::SkopeoDriver, super::sigstore_driver::SigstoreDriver, - super::rpm_ostree_driver::RpmOstreeDriver, - super::rpm_ostree_driver::Status, - super::rpm_ostree_runner::RpmOstreeContainer, - super::rpm_ostree_runner::RpmOstreeRunner, super::oci_client_driver::OciClientDriver, - Option, Option, Option, Option, @@ -79,6 +85,19 @@ impl_private_driver!( Option, ); +#[cfg(not(feature = "next-builder"))] +impl_private_driver!( + super::docker_driver::DockerDriver, + super::buildah_driver::BuildahDriver, + super::skopeo_driver::SkopeoDriver, + super::cosign_driver::CosignDriver, + super::rpm_ostree_driver::RpmOstreeDriver, + super::rpm_ostree_driver::Status, + super::rpm_ostree_runner::RpmOstreeContainer, + super::rpm_ostree_runner::RpmOstreeRunner, + Option, +); + #[cfg(feature = "bootc")] impl_private_driver!( super::bootc_driver::BootcDriver, @@ -112,6 +131,7 @@ pub trait DriverVersion: PrivateDriver { } /// Allows agnostic building, tagging, pushing, and login. +#[cfg(not(feature = "next-builder"))] pub trait BuildDriver: ImageStorageDriver { /// Runs the build logic for the driver. /// @@ -257,6 +277,7 @@ pub trait BuildDriver: ImageStorageDriver { /// Trait for a postprocessing step (such as rechunking) that can be applied to /// images after they're built. +#[cfg(not(feature = "next-builder"))] pub trait PostBuild: Debug { /// Check driver requirements for post-build steps. /// @@ -272,6 +293,7 @@ pub trait PostBuild: Debug { } /// Auxiliary trait that actually runs the postprocessing step. +#[cfg(not(feature = "next-builder"))] pub trait PostBuildRunner { /// Run postprocessing on image. Implementors should write the output image /// to the image reference given by `opts.output_image`. @@ -282,6 +304,7 @@ pub trait PostBuildRunner { } /// A build driver that can run post-build steps. +#[cfg(not(feature = "next-builder"))] pub trait PostBuildDriver: BuildDriver { /// Runs the logic for building, tagging, and pushing an image, with post- /// build processing applied after building but before tagging and pushing. @@ -362,6 +385,7 @@ pub trait ImageStorageDriver: PrivateDriver { fn list_images(privileged: bool) -> Result>; } +#[cfg(not(feature = "next-builder"))] pub trait BuildChunkedOciDriver: BuildDriver + ImageStorageDriver { /// Create a manifest containing all the built images. /// Runs within the same context as rpm-ostree. @@ -644,6 +668,7 @@ pub trait BuildChunkedOciDriver: BuildDriver + ImageStorageDriver { } #[expect(private_bounds)] +#[cfg(not(feature = "next-builder"))] pub(super) trait ContainerMountDriver: PrivateDriver { /// Mounts the container /// @@ -665,6 +690,7 @@ pub(super) trait ContainerMountDriver: PrivateDriver { } #[expect(private_bounds)] +#[cfg(not(feature = "next-builder"))] pub trait OciCopy: PrivateDriver { /// Copy an OCI image. /// @@ -674,6 +700,7 @@ pub trait OciCopy: PrivateDriver { } #[expect(private_bounds)] +#[cfg(not(feature = "next-builder"))] pub trait RechunkDriver: RunDriver + BuildDriver + ContainerMountDriver { // renovate: datasource=github-releases depName=hhd-dev/rechunk const RECHUNK_IMAGE: &str = "ghcr.io/hhd-dev/rechunk:v1.0.1"; diff --git a/process/drivers/types/drivers.rs b/process/drivers/types/drivers.rs index 73602ff8..08922c8c 100644 --- a/process/drivers/types/drivers.rs +++ b/process/drivers/types/drivers.rs @@ -5,8 +5,11 @@ use blue_build_utils::{ use clap::ValueEnum; use log::trace; +use crate::drivers::DetermineDriver; + +#[cfg(not(feature = "next-builder"))] use crate::drivers::{ - DetermineDriver, DriverVersion, buildah_driver::BuildahDriver, docker_driver::DockerDriver, + DriverVersion, buildah_driver::BuildahDriver, docker_driver::DockerDriver, podman_driver::PodmanDriver, }; @@ -25,6 +28,7 @@ impl DetermineDriver for Option { } } +#[cfg(not(feature = "next-builder"))] #[derive(Debug, Clone, Copy, ValueEnum)] pub enum BuildDriverType { Buildah, @@ -32,6 +36,7 @@ pub enum BuildDriverType { Docker, } +#[cfg(not(feature = "next-builder"))] impl DetermineDriver for Option { fn determine_driver(&mut self) -> BuildDriverType { *self.get_or_insert( @@ -89,6 +94,7 @@ impl DetermineDriver for Option { #[derive(Debug, Clone, Copy, ValueEnum)] pub enum RunDriverType { Podman, + #[cfg(not(feature = "next-builder"))] Docker, } @@ -96,6 +102,7 @@ impl From for String { fn from(value: RunDriverType) -> Self { match value { RunDriverType::Podman => "podman".to_string(), + #[cfg(not(feature = "next-builder"))] RunDriverType::Docker => "docker".to_string(), } } @@ -105,25 +112,37 @@ impl DetermineDriver for Option { fn determine_driver(&mut self) -> RunDriverType { trace!("RunDriver::determine_driver()"); - *self.get_or_insert( - match ( - blue_build_utils::check_command_exists("docker"), - blue_build_utils::check_command_exists("podman"), - ) { - (Ok(_docker), _) if DockerDriver::is_supported_version() => RunDriverType::Docker, - (_, Ok(_podman)) if PodmanDriver::is_supported_version() => RunDriverType::Podman, - _ => panic!( - "{}{}{}{}", - "Could not determine strategy, ", - format_args!("need either docker version {}, ", DockerDriver::VERSION_REQ), - format_args!("podman version {}, ", PodmanDriver::VERSION_REQ), - format_args!( - "or buildah version {} to continue", - BuildahDriver::VERSION_REQ + #[cfg(feature = "next-builder")] + { + *self.get_or_insert(RunDriverType::Podman) + } + + #[cfg(not(feature = "next-builder"))] + { + *self.get_or_insert( + match ( + blue_build_utils::check_command_exists("docker"), + blue_build_utils::check_command_exists("podman"), + ) { + (Ok(_docker), _) if DockerDriver::is_supported_version() => { + RunDriverType::Docker + } + (_, Ok(_podman)) if PodmanDriver::is_supported_version() => { + RunDriverType::Podman + } + _ => panic!( + "{}{}{}{}", + "Could not determine strategy, ", + format_args!("need either docker version {}, ", DockerDriver::VERSION_REQ), + format_args!("podman version {}, ", PodmanDriver::VERSION_REQ), + format_args!( + "or buildah version {} to continue", + BuildahDriver::VERSION_REQ + ), ), - ), - }, - ) + }, + ) + } } } @@ -155,6 +174,7 @@ impl DetermineDriver for Option { pub enum BootDriverType { #[cfg(feature = "bootc")] Bootc, + #[cfg(not(feature = "next-builder"))] RpmOstree, None, } @@ -163,16 +183,23 @@ impl DetermineDriver for Option { fn determine_driver(&mut self) -> BootDriverType { trace!("BootDriverType::determine_driver()"); - *self.get_or_insert( - match ( - blue_build_utils::check_command_exists("bootc"), - blue_build_utils::check_command_exists("rpm-ostree"), - ) { - #[cfg(feature = "bootc")] - (Ok(_bootc), _) => BootDriverType::Bootc, - (_, Ok(_rpm_ostree)) => BootDriverType::RpmOstree, - _ => BootDriverType::None, - }, - ) + #[cfg(not(feature = "next-builder"))] + { + *self.get_or_insert( + match ( + blue_build_utils::check_command_exists("bootc"), + blue_build_utils::check_command_exists("rpm-ostree"), + ) { + #[cfg(feature = "bootc")] + (Ok(_bootc), _) => BootDriverType::Bootc, + (_, Ok(_rpm_ostree)) => BootDriverType::RpmOstree, + _ => BootDriverType::None, + }, + ) + } + #[cfg(feature = "next-builder")] + { + *self.get_or_insert(BootDriverType::Bootc) + } } } diff --git a/src/bin/bluebuild.rs b/src/bin/bluebuild.rs index 7b46b7a3..406f6195 100644 --- a/src/bin/bluebuild.rs +++ b/src/bin/bluebuild.rs @@ -48,6 +48,7 @@ fn main() { signal_handler::init(|| match args.command { CommandArgs::Build(mut command) => command.run(), + #[cfg(not(feature = "next-builder"))] CommandArgs::Generate(mut command) => command.run(), CommandArgs::Switch(mut command) => command.run(), CommandArgs::Login(mut command) => command.run(), diff --git a/src/commands.rs b/src/commands.rs index 05ee59d6..d83bb4d1 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -11,6 +11,7 @@ use crate::shadow; pub mod bug_report; pub mod build; pub mod completions; +#[cfg(not(feature = "next-builder"))] pub mod generate; pub mod generate_iso; pub mod init; @@ -74,6 +75,7 @@ pub enum CommandArgs { /// Generate a Containerfile from a recipe #[clap(visible_alias = "template")] + #[cfg(not(feature = "next-builder"))] Generate(generate::GenerateCommand), /// Generate an ISO for an image or recipe. diff --git a/src/commands/build.rs b/src/commands/build.rs index 3bec3e4f..54a6f245 100644 --- a/src/commands/build.rs +++ b/src/commands/build.rs @@ -1,50 +1,71 @@ use std::{ num::NonZeroU32, - ops::Not, path::{Path, PathBuf}, }; use blue_build_process_management::{ ASYNC_RUNTIME, drivers::{ - BuildChunkedOciDriver, BuildDriver, CiDriver, Driver, DriverArgs, InspectDriver, - PostBuildDriver, RechunkDriver, SigningDriver, + Driver, SigningDriver, + opts::{CheckKeyPairOpts, CompressionType}, + }, +}; +use blue_build_recipe::Recipe; +use blue_build_utils::{ + constants::{ + BB_BUILD_ARCHIVE, BB_BUILD_CHUNKAH_VERSION, BB_BUILD_MAX_LAYERS, BB_BUILD_NO_SIGN, + BB_BUILD_PLATFORM, BB_BUILD_PUSH, BB_BUILD_REMOVE_BASE_IMAGE, BB_BUILD_RETRY_COUNT, + BB_BUILD_RETRY_PUSH, BB_BUILD_SQUASH, BB_CACHE_LAYERS, BB_REGISTRY_NAMESPACE, + BB_SKIP_VALIDATION, BB_TEMPDIR, RECIPE_FILE, RECIPE_PATH, + }, + credentials::{Credentials, CredentialsArgs}, + platform::Platform, +}; +use bon::Builder; +use clap::Args; +use log::trace; +use miette::Result; + +use super::BlueBuildCommand; + +#[cfg(not(feature = "next-builder"))] +use super::generate::{GenerateCommand, generate_default_labels}; +#[cfg(not(feature = "next-builder"))] +use blue_build_process_management::{ + drivers::{ + BuildChunkedOciDriver, BuildDriver, CiDriver, DriverArgs, InspectDriver, PostBuildDriver, + RechunkDriver, opts::{ - BuildChunkedOciOpts, BuildRechunkTagPushOpts, BuildTagPushOpts, CheckKeyPairOpts, - CompressionType, GenerateImageNameOpts, GenerateTagsOpts, GetMetadataOpts, - PostBuildDriverOpts, RechunkOpts, SignVerifyOpts, + BuildChunkedOciOpts, BuildRechunkTagPushOpts, BuildTagPushOpts, GenerateImageNameOpts, + GenerateTagsOpts, GetMetadataOpts, PostBuildDriverOpts, RechunkOpts, SignVerifyOpts, }, post_build::Chunkah, types::{BuildDriverType, RunDriverType}, }, logging::color_str, }; -use blue_build_recipe::{Recipe, RecipeGetters}; +#[cfg(not(feature = "next-builder"))] +use blue_build_recipe::RecipeGetters; +#[cfg(not(feature = "next-builder"))] use blue_build_utils::{ colors::gen_random_ansi_color, constants::{ - ARCHIVE_SUFFIX, BB_BUILD_ARCHIVE, BB_BUILD_CHUNKAH, BB_BUILD_CHUNKAH_VERSION, - BB_BUILD_CHUNKED_OCI, BB_BUILD_CHUNKED_OCI_MAX_LAYERS, BB_BUILD_MAX_LAYERS, - BB_BUILD_NO_SIGN, BB_BUILD_PLATFORM, BB_BUILD_PUSH, BB_BUILD_RECHUNK, - BB_BUILD_RECHUNK_CLEAR_PLAN, BB_BUILD_REMOVE_BASE_IMAGE, BB_BUILD_RETRY_COUNT, - BB_BUILD_RETRY_PUSH, BB_BUILD_SQUASH, BB_CACHE_LAYERS, BB_REGISTRY_NAMESPACE, - BB_SKIP_VALIDATION, BB_TEMPDIR, CONFIG_PATH, RECIPE_FILE, RECIPE_PATH, + ARCHIVE_SUFFIX, BB_BUILD_CHUNKAH, BB_BUILD_CHUNKED_OCI, BB_BUILD_CHUNKED_OCI_MAX_LAYERS, + BB_BUILD_RECHUNK, BB_BUILD_RECHUNK_CLEAR_PLAN, CONFIG_PATH, }, container::{ImageRef, Tag}, - credentials::{Credentials, CredentialsArgs}, - platform::Platform, tempdir, tempdir_in, }; -use bon::Builder; -use clap::Args; -use log::{debug, info, trace, warn}; -use miette::{IntoDiagnostic, Result}; +#[cfg(not(feature = "next-builder"))] +use log::{debug, info, warn}; +#[cfg(not(feature = "next-builder"))] +use miette::IntoDiagnostic; +#[cfg(not(feature = "next-builder"))] use oci_client::Reference; +#[cfg(not(feature = "next-builder"))] use rayon::prelude::*; - -use crate::commands::generate::{GenerateCommand, generate_default_labels}; - -use super::BlueBuildCommand; +#[cfg(not(feature = "next-builder"))] +use std::ops::Not; #[expect(clippy::struct_excessive_bools)] #[derive(Debug, Args, Builder)] @@ -120,15 +141,30 @@ pub struct BuildCommand { #[builder(default)] squash: bool, + /// Uses Chunkah to rechunk the image, + /// allowing for smaller images and smaller updates. + #[cfg(feature = "next-builder")] + #[arg( + long, + alias = "chunkah", + alias = "rechunk", + alias = "build-chunked-oci" + )] + #[builder(default)] + chunk: bool, + /// Uses Chunkah (https://github.com/coreos/chunkah) to rechunk the image, /// allowing for smaller images and smaller updates. + #[cfg(not(feature = "next-builder"))] #[arg(long, group = "any_rechunker", env = BB_BUILD_CHUNKAH)] #[builder(default)] chunkah: bool, /// Chunkah tag or digest that should be used to rechunk the image. /// Defaults to "latest" tag. - #[arg(long, requires = "chunkah", env = BB_BUILD_CHUNKAH_VERSION)] + #[arg(long, env = BB_BUILD_CHUNKAH_VERSION)] + #[cfg_attr(feature = "next-builder", arg(requires = "chunk"))] + #[cfg_attr(not(feature = "next-builder"), arg(requires = "chunkah"))] chunkah_version: Option, /// Uses `rpm-ostree compose build-chunked-oci` to rechunk the image, @@ -136,6 +172,7 @@ pub struct BuildCommand { /// /// WARN: This will increase the build-time /// and take up more space during build-time. + #[cfg(not(feature = "next-builder"))] #[arg(long, group = "any_rechunker", env = BB_BUILD_CHUNKED_OCI)] #[builder(default)] build_chunked_oci: bool, @@ -144,15 +181,20 @@ pub struct BuildCommand { #[arg( long, env = BB_BUILD_MAX_LAYERS, - requires = "any_rechunker", - conflicts_with = "rechunk" + )] + #[cfg_attr(feature = "next-builder", arg(requires = "chunk"))] + #[cfg_attr( + not(feature = "next-builder"), + arg(requires = "any_rechunker", conflicts_with = "rechunk") )] max_layers: Option, /// Removes the base image from local storage and prunes unused podman containers /// and volumes after the image is built, but before running a rechunker. /// This frees up additional disk space. - #[arg(long, env = BB_BUILD_REMOVE_BASE_IMAGE, requires = "any_rechunker")] + #[arg(long, env = BB_BUILD_REMOVE_BASE_IMAGE)] + #[cfg_attr(feature = "next-builder", arg(requires = "chunk"))] + #[cfg_attr(not(feature = "next-builder"), arg(requires = "any_rechunker"))] #[builder(default)] remove_base_image: bool, @@ -165,6 +207,7 @@ pub struct BuildCommand { /// and take up more space during build-time. /// /// NOTE: This must be run as root! + #[cfg(not(feature = "next-builder"))] #[arg(long, group = "any_rechunker", group = "archive_rechunk", env = BB_BUILD_RECHUNK)] #[builder(default)] rechunk: bool, @@ -172,6 +215,7 @@ pub struct BuildCommand { /// Use a fresh rechunk plan, regardless of previous ref. /// /// NOTE: Only works with `--build-chunked-oci` or `--rechunk`. + #[cfg(not(feature = "next-builder"))] #[arg(long, env = BB_BUILD_RECHUNK_CLEAR_PLAN)] #[builder(default)] rechunk_clear_plan: bool, @@ -199,6 +243,7 @@ pub struct BuildCommand { #[clap(flatten)] #[builder(default)] + #[cfg(not(feature = "next-builder"))] drivers: DriverArgs, } @@ -207,6 +252,7 @@ impl BlueBuildCommand for BuildCommand { fn try_run(&mut self) -> Result<()> { trace!("BuildCommand::try_run()"); + #[cfg(not(feature = "next-builder"))] Driver::init(if self.chunkah || self.build_chunked_oci || self.rechunk { DriverArgs::builder() .build_driver(BuildDriverType::Podman) @@ -218,9 +264,13 @@ impl BlueBuildCommand for BuildCommand { self.drivers }); + #[cfg(feature = "next-builder")] + Driver::init(); + Credentials::init(self.credentials.clone()); // Read old environment variable name for backwards compatibility + #[cfg(not(feature = "next-builder"))] if self.build_chunked_oci && self.max_layers.is_none() && let Ok(max_layers) = std::env::var(BB_BUILD_CHUNKED_OCI_MAX_LAYERS) @@ -233,11 +283,13 @@ impl BlueBuildCommand for BuildCommand { Driver::check_signing_files(CheckKeyPairOpts::builder().dir(Path::new(".")).build())?; } + #[cfg(not(feature = "next-builder"))] let tempdir = if let Some(ref dir) = self.tempdir { tempdir_in(dir)? } else { tempdir()? }; + #[cfg(not(feature = "next-builder"))] let recipe_paths = self.recipe.clone().map_or_else(|| { let legacy_path = Path::new(CONFIG_PATH); let recipe_path = Path::new(RECIPE_PATH); @@ -253,6 +305,7 @@ impl BlueBuildCommand for BuildCommand { recipes.into_iter().filter(|recipe| same.insert(recipe.clone())).collect() }); + #[cfg(not(feature = "next-builder"))] recipe_paths.par_iter().try_for_each(|recipe| { GenerateCommand::builder() .output( @@ -270,11 +323,68 @@ impl BlueBuildCommand for BuildCommand { .try_run() })?; - self.start(&recipe_paths, tempdir.path()) + #[cfg(not(feature = "next-builder"))] + { + self.start(&recipe_paths, tempdir.path()) + } + #[cfg(feature = "next-builder")] + { + self.start() + } } } impl BuildCommand { + #[cfg(feature = "next-builder")] + fn start(&self) -> Result<()> { + use blue_build_next_builder::{Manifest, build_scripts}; + use miette::IntoDiagnostic; + + let current_dir = &std::env::current_dir().into_diagnostic()?; + let build_scripts = ASYNC_RUNTIME.block_on(build_scripts::build_scripts_layer())?; + let manifests = self + .recipe + .clone() + .map_or_else( + || vec![Path::new(RECIPE_PATH).join(RECIPE_FILE)], + |recipes| { + let mut same = std::collections::HashSet::new(); + + recipes + .into_iter() + .filter(|recipe| same.insert(recipe.clone())) + .collect() + }, + ) + .into_iter() + .map(|recipe| { + Recipe::builder() + .path(recipe) + .platforms(&self.platform) + .build() + }) + .collect::>>()? + .iter() + .flat_map(|recipe| { + ASYNC_RUNTIME.block_on( + Manifest::builder() + .recipe(recipe) + .squash(self.squash) + .context_dir(current_dir) + .build_scripts_layer(&build_scripts) + .build(), + ) + }) + .collect::>(); + + for manifest in manifests { + ASYNC_RUNTIME.block_on(manifest.build())?; + } + + Ok(()) + } + + #[cfg(not(feature = "next-builder"))] fn start(&self, recipe_paths: &[PathBuf], temp_dir: &Path) -> Result<()> { trace!( "BuildCommand::start({recipe_paths:?}, {})", @@ -308,6 +418,7 @@ impl BuildCommand { } #[expect(clippy::too_many_lines)] + #[cfg(not(feature = "next-builder"))] fn build(&self, recipe_path: &Path, containerfile: &Path) -> Result> { trace!( "BuildCommand::build({}, {})", @@ -477,6 +588,7 @@ impl BuildCommand { Ok(images) } + #[cfg(not(feature = "next-builder"))] fn rechunk( &self, containerfile: &Path, diff --git a/src/commands/generate_iso.rs b/src/commands/generate_iso.rs index a4fa1ae8..c0538f67 100644 --- a/src/commands/generate_iso.rs +++ b/src/commands/generate_iso.rs @@ -19,12 +19,15 @@ use miette::{Context, IntoDiagnostic, Result, bail}; use oci_client::Reference; use blue_build_process_management::{ - drivers::{Driver, DriverArgs, RunDriver, opts::RunOpts}, + drivers::{Driver, RunDriver, opts::RunOpts}, run_volumes, }; use super::{BlueBuildCommand, build::BuildCommand}; +#[cfg(not(feature = "next-builder"))] +use blue_build_process_management::drivers::DriverArgs; + #[derive(Clone, Debug, Builder, Args)] pub struct GenerateIsoCommand { #[command(subcommand)] @@ -95,6 +98,7 @@ pub struct GenerateIsoCommand { #[clap(flatten)] #[builder(default)] + #[cfg(not(feature = "next-builder"))] drivers: DriverArgs, } @@ -146,8 +150,12 @@ impl std::fmt::Display for GenIsoVariant { impl BlueBuildCommand for GenerateIsoCommand { fn try_run(&mut self) -> Result<()> { + #[cfg(not(feature = "next-builder"))] Driver::init(self.drivers); + #[cfg(feature = "next-builder")] + Driver::init(); + let image_out_dir = if let Some(ref dir) = self.tempdir { tempdir_in(dir)? } else { diff --git a/src/commands/init.rs b/src/commands/init.rs index fd21f323..9fdafee9 100644 --- a/src/commands/init.rs +++ b/src/commands/init.rs @@ -8,7 +8,7 @@ use std::{ }; use blue_build_process_management::drivers::{ - CiDriver, Driver, DriverArgs, GitlabDriver, SigningDriver, opts::GenerateKeyPairOpts, + CiDriver, Driver, GitlabDriver, SigningDriver, opts::GenerateKeyPairOpts, }; use blue_build_template::{GitlabCiTemplate, InitReadmeTemplate, Template}; use blue_build_utils::constants::{COSIGN_PUB_PATH, RECIPE_FILE, RECIPE_PATH, TEMPLATE_REPO_URL}; @@ -22,6 +22,9 @@ use semver::Version; use crate::commands::BlueBuildCommand; +#[cfg(not(feature = "next-builder"))] +use blue_build_process_management::drivers::DriverArgs; + #[derive(Debug, Default, Clone, Copy, ValueEnum)] pub enum CiProvider { #[default] @@ -133,6 +136,7 @@ pub struct NewInitCommon { #[clap(flatten)] #[builder(default)] + #[cfg(not(feature = "next-builder"))] drivers: DriverArgs, } @@ -167,8 +171,12 @@ pub struct InitCommand { impl BlueBuildCommand for InitCommand { fn try_run(&mut self) -> Result<()> { + #[cfg(not(feature = "next-builder"))] Driver::init(self.common.drivers); + #[cfg(feature = "next-builder")] + Driver::init(); + let base_dir = self .dir .get_or_insert(env::current_dir().into_diagnostic()?); diff --git a/src/commands/login.rs b/src/commands/login.rs index 04ecac0f..64718a2c 100644 --- a/src/commands/login.rs +++ b/src/commands/login.rs @@ -1,6 +1,6 @@ use std::io::{self, Read}; -use blue_build_process_management::drivers::{BuildDriver, Driver, DriverArgs, SigningDriver}; +use blue_build_process_management::drivers::{Driver, SigningDriver}; use blue_build_utils::{ credentials::{Credentials, CredentialsArgs}, secret::SecretValue, @@ -11,6 +11,9 @@ use requestty::questions; use super::BlueBuildCommand; +#[cfg(not(feature = "next-builder"))] +use blue_build_process_management::drivers::{BuildDriver, DriverArgs}; + #[derive(Debug, Clone, Args)] pub struct LoginCommand { /// The server to login to. @@ -33,13 +36,18 @@ pub struct LoginCommand { username: Option, #[clap(flatten)] + #[cfg(not(feature = "next-builder"))] drivers: DriverArgs, } impl BlueBuildCommand for LoginCommand { fn try_run(&mut self) -> miette::Result<()> { + #[cfg(not(feature = "next-builder"))] Driver::init(self.drivers); + #[cfg(feature = "next-builder")] + Driver::init(); + Credentials::init( CredentialsArgs::builder() .registry(&self.server) diff --git a/src/commands/prune.rs b/src/commands/prune.rs index 01d60de0..6367e086 100644 --- a/src/commands/prune.rs +++ b/src/commands/prune.rs @@ -1,4 +1,4 @@ -use blue_build_process_management::drivers::{BuildDriver, Driver, DriverArgs, opts::PruneOpts}; +use blue_build_process_management::drivers::{Driver, opts::PruneOpts}; use bon::Builder; use clap::Args; use colored::Colorize; @@ -6,6 +6,9 @@ use miette::bail; use super::BlueBuildCommand; +#[cfg(not(feature = "next-builder"))] +use blue_build_process_management::drivers::{BuildDriver, DriverArgs}; + #[derive(Debug, Args, Builder)] pub struct PruneCommand { /// Remove all unused images @@ -23,6 +26,7 @@ pub struct PruneCommand { #[arg(long)] volumes: bool, + #[cfg(not(feature = "next-builder"))] #[clap(flatten)] #[builder(default)] drivers: DriverArgs, @@ -30,8 +34,12 @@ pub struct PruneCommand { impl BlueBuildCommand for PruneCommand { fn try_run(&mut self) -> miette::Result<()> { + #[cfg(not(feature = "next-builder"))] Driver::init(self.drivers); + #[cfg(feature = "next-builder")] + Driver::init(); + if !self.force { eprintln!( "{} This will remove:{default}{images}{build_cache}{volumes}", diff --git a/src/commands/switch.rs b/src/commands/switch.rs index 53074548..262edb1a 100644 --- a/src/commands/switch.rs +++ b/src/commands/switch.rs @@ -1,21 +1,29 @@ use std::path::PathBuf; use blue_build_process_management::drivers::{ - BootDriver, BuildDriver, CiDriver, Driver, DriverArgs, ImageStorageDriver, PodmanDriver, - opts::{BuildOpts, GenerateImageNameOpts, RemoveImageOpts, SwitchOpts}, - types::{BuildDriverType, RunDriverType}, + BootDriver, CiDriver, Driver, ImageStorageDriver, PodmanDriver, + opts::{GenerateImageNameOpts, RemoveImageOpts, SwitchOpts}, }; use blue_build_recipe::{Recipe, RecipeGetters}; -use blue_build_utils::{constants::BB_SKIP_VALIDATION, container::ImageRef, tempdir, tempdir_in}; +use blue_build_utils::constants::BB_SKIP_VALIDATION; use bon::Builder; use clap::Args; use log::trace; use miette::{Result, bail}; -use crate::commands::generate::GenerateCommand; - use super::BlueBuildCommand; +#[cfg(not(feature = "next-builder"))] +use super::generate::GenerateCommand; +#[cfg(not(feature = "next-builder"))] +use blue_build_process_management::drivers::{ + BuildDriver, DriverArgs, + opts::BuildOpts, + types::{BuildDriverType, RunDriverType}, +}; +#[cfg(not(feature = "next-builder"))] +use blue_build_utils::{container::ImageRef, tempdir, tempdir_in}; + #[derive(Default, Clone, Debug, Builder, Args)] pub struct SwitchCommand { /// The recipe file to build an image. @@ -40,6 +48,7 @@ pub struct SwitchCommand { #[clap(flatten)] #[builder(default)] + #[cfg(not(feature = "next-builder"))] drivers: DriverArgs, } @@ -47,6 +56,7 @@ impl BlueBuildCommand for SwitchCommand { fn try_run(&mut self) -> Result<()> { trace!("SwitchCommand::try_run()"); + #[cfg(not(feature = "next-builder"))] Driver::init( DriverArgs::builder() .build_driver(BuildDriverType::Podman) @@ -56,6 +66,9 @@ impl BlueBuildCommand for SwitchCommand { .build(), ); + #[cfg(feature = "next-builder")] + Driver::init(); + let status = Driver::status()?; if status.transaction_in_progress() { @@ -68,20 +81,24 @@ impl BlueBuildCommand for SwitchCommand { .name(recipe.get_name().trim()) .build(), )?; + #[cfg(not(feature = "next-builder"))] let tempdir = if let Some(ref dir) = self.tempdir { tempdir_in(dir)? } else { tempdir()? }; + #[cfg(not(feature = "next-builder"))] let containerfile = tempdir .path() .join(blue_build_utils::generate_containerfile_path(&self.recipe)?); + #[cfg(not(feature = "next-builder"))] GenerateCommand::builder() .output(&containerfile) .recipe(&self.recipe) .build() .try_run()?; + #[cfg(not(feature = "next-builder"))] Driver::build( BuildOpts::builder() .image(&ImageRef::from(&image_name)) diff --git a/src/lib.rs b/src/lib.rs index 21619fce..456fdad0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,9 @@ //! The root library for blue-build. #![doc = include_str!("../README.md")] +#[cfg(not(feature = "next-builder"))] use blue_build_process_management::drivers::types::BuildDriverType; +#[cfg(not(feature = "next-builder"))] use blue_build_template::BuildEngine; mod build_scripts; @@ -11,10 +13,12 @@ pub use build_scripts::*; shadow_rs::shadow!(shadow); +#[cfg(not(feature = "next-builder"))] pub(crate) trait DriverTemplate { fn build_engine(&self) -> BuildEngine; } +#[cfg(not(feature = "next-builder"))] impl DriverTemplate for BuildDriverType { fn build_engine(&self) -> BuildEngine { match self { diff --git a/utils/src/macros.rs b/utils/src/macros.rs index 94eccd89..9b7229b8 100644 --- a/utils/src/macros.rs +++ b/utils/src/macros.rs @@ -286,7 +286,6 @@ macro_rules! cmd_out { { let mut _c = ::comlexr::cmd!($($cmd)*); ::log::trace!("{_c:#?}"); - dbg!(&_c); _c.stderr(::std::process::Stdio::inherit()); _c }