diff --git a/Cargo.toml b/Cargo.toml index a7560fe9..03e65397 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,7 +102,24 @@ users.workspace = true [features] # Top level features -default = [] +default = [ + "v0_9_0" +] + +# v0.9.0 features +v0_9_0 = [ + "init", + "stages", + "copy", + "iso", + "switch", + "login", + "validate", + "sigstore", + "multi-recipe", + "prune", + "rechunk", +] init = [] stages = ["blue-build-recipe/stages"] copy = ["blue-build-recipe/copy"] diff --git a/integration-tests/Earthfile b/integration-tests/Earthfile index 16ff5a03..fcb6c692 100644 --- a/integration-tests/Earthfile +++ b/integration-tests/Earthfile @@ -62,18 +62,6 @@ build-full: RUN --secret BB_PASSWORD=github/registry bluebuild build --push -S sigstore -vv recipes/recipe.yml END - -rebase: - FROM +legacy-base - - RUN --no-cache bluebuild -v rebase config/recipe.yml - -upgrade: - FROM +legacy-base - - RUN mkdir -p /etc/bluebuild && touch $BB_TEST_LOCAL_IMAGE - RUN --no-cache bluebuild -v upgrade config/recipe.yml - switch: FROM +test-base diff --git a/scripts/exports.sh b/scripts/exports.sh index b15ed697..3cae0768 100644 --- a/scripts/exports.sh +++ b/scripts/exports.sh @@ -1,23 +1,5 @@ #!/usr/bin/env bash -# Function to retrieve module configs and populate an array -# Arguments: -# 1. Variable name to store result -# 2. jq query -# 3. Module config content -get_yaml_array() { - local -n arr="${1}" - local jq_query="${2}" - local module_config="${3}" - - if [[ -z "${jq_query}" || -z "${module_config}" ]]; then - echo "Usage: get_yaml_array VARIABLE_TO_STORE_RESULTS JQ_QUERY MODULE_CONFIG" >&2 - return 1 - fi - - readarray -t arr < <(echo "${module_config}" | yq -I=0 "${jq_query}") -} - # Function to retrieve module configs and populate an array # Arguments: # 1. Variable name to store result @@ -67,7 +49,6 @@ export OS_VERSION="$(grep -Po "(?<=VERSION_ID=)\d+" /usr/lib/os-release)" export OS_ARCH="$(uname -m)" # Export functions for use in sub-shells or sourced scripts -export -f get_yaml_array export -f get_json_array mkdir -p /var/roothome /var/opt /var/lib/alternatives /var/opt /var/usrlocal diff --git a/scripts/setup.sh b/scripts/setup.sh index b8d7563e..cc0d6316 100644 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -18,4 +18,3 @@ if [ -f /etc/os-release ]; then echo "OS not detected, proceeding without setup" fi fi -cp /tmp/bins/yq /usr/bin/ diff --git a/src/bin/bluebuild.rs b/src/bin/bluebuild.rs index 8a205c31..31d05e5d 100644 --- a/src/bin/bluebuild.rs +++ b/src/bin/bluebuild.rs @@ -31,12 +31,6 @@ fn main() { #[cfg(feature = "switch")] CommandArgs::Switch(mut command) => command.run(), - #[cfg(not(feature = "switch"))] - CommandArgs::Rebase(mut command) => command.run(), - - #[cfg(not(feature = "switch"))] - CommandArgs::Upgrade(mut command) => command.run(), - #[cfg(feature = "login")] CommandArgs::Login(mut command) => command.run(), diff --git a/src/commands.rs b/src/commands.rs index 14850829..1b5ff7ec 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -15,8 +15,6 @@ pub mod generate; pub mod generate_iso; #[cfg(feature = "init")] pub mod init; -#[cfg(not(feature = "switch"))] -pub mod local; #[cfg(feature = "login")] pub mod login; #[cfg(feature = "prune")] @@ -78,31 +76,6 @@ pub enum CommandArgs { #[cfg(feature = "iso")] GenerateIso(generate_iso::GenerateIsoCommand), - /// Upgrade your current OS with the - /// local image saved at `/etc/bluebuild/`. - /// - /// This requires having rebased already onto - /// a local archive already by using the `rebase` - /// subcommand. - /// - /// NOTE: This can only be used if you have `rpm-ostree` - /// installed. This image will not be signed. - #[command(visible_alias("update"))] - #[cfg(not(feature = "switch"))] - Upgrade(local::UpgradeCommand), - - /// Rebase your current OS onto the image - /// being built. - /// - /// This will create a tarball of your image at - /// `/etc/bluebuild/` and invoke `rpm-ostree` to - /// rebase onto the image using `oci-archive`. - /// - /// NOTE: This can only be used if you have `rpm-ostree` - /// installed. This image will not be signed. - #[cfg(not(feature = "switch"))] - Rebase(local::RebaseCommand), - /// Switch your current OS onto the image /// being built. /// @@ -113,6 +86,11 @@ pub enum CommandArgs { /// NOTE: This can only be used if you have `rpm-ostree` /// installed. This image will not be signed. #[cfg(feature = "switch")] + #[command( + visible_alias("update"), + visible_alias("upgrade"), + visible_alias("rebase") + )] Switch(switch::SwitchCommand), /// Login to all services used for building. diff --git a/src/commands/local.rs b/src/commands/local.rs deleted file mode 100644 index 42f57249..00000000 --- a/src/commands/local.rs +++ /dev/null @@ -1,223 +0,0 @@ -use std::{ - fs, - path::{Path, PathBuf}, -}; - -use blue_build_process_management::drivers::DriverArgs; -use blue_build_recipe::Recipe; -use blue_build_utils::{ - cmd, - constants::{ARCHIVE_SUFFIX, LOCAL_BUILD}, -}; -use bon::Builder; -use clap::Args; -use log::{debug, info, trace}; -use miette::{bail, IntoDiagnostic, Result}; -use users::{Users, UsersCache}; - -use crate::commands::build::BuildCommand; - -use super::BlueBuildCommand; - -#[derive(Default, Clone, Debug, Builder, Args)] -pub struct LocalCommonArgs { - /// The recipe file to build an image. - #[arg()] - recipe: PathBuf, - - /// Reboot your system after - /// the update is complete. - #[arg(short, long)] - #[builder(default)] - reboot: bool, - - /// Allow `bluebuild` to overwrite an existing - /// Containerfile without confirmation. - /// - /// This is not needed if the Containerfile is in - /// .gitignore or has already been built by `bluebuild`. - #[arg(short, long)] - #[builder(default)] - force: bool, - - #[clap(flatten)] - #[builder(default)] - drivers: DriverArgs, -} - -#[derive(Default, Clone, Debug, Builder, Args)] -pub struct UpgradeCommand { - #[clap(flatten)] - common: LocalCommonArgs, -} - -impl BlueBuildCommand for UpgradeCommand { - fn try_run(&mut self) -> Result<()> { - trace!("UpgradeCommand::try_run()"); - - check_can_run()?; - - let recipe = Recipe::parse(&self.common.recipe)?; - - let build = BuildCommand::builder(); - - #[cfg(feature = "multi-recipe")] - let build = build.recipe(vec![self.common.recipe.clone()]); - - #[cfg(not(feature = "multi-recipe"))] - let build = build.recipe(self.common.recipe.clone()); - - let mut build = build - .archive(LOCAL_BUILD) - .drivers(self.common.drivers) - .build(); - - let image_name = recipe.name.to_lowercase().replace('/', "_"); - - clean_local_build_dir(&image_name, false)?; - debug!("Image name is {image_name}"); - - build.try_run()?; - - let status = if self.common.reboot { - info!("Upgrading image {image_name} and rebooting"); - - trace!("rpm-ostree upgrade --reboot"); - cmd!("rpm-ostree", "upgrade", "--reboot") - .status() - .into_diagnostic()? - } else { - info!("Upgrading image {image_name}"); - - trace!("rpm-ostree upgrade"); - cmd!("rpm-ostree", "upgrade").status().into_diagnostic()? - }; - - if status.success() { - info!("Successfully upgraded image {image_name}"); - } else { - bail!("Failed to upgrade image {image_name}"); - } - Ok(()) - } -} - -#[derive(Default, Clone, Debug, Builder, Args)] -pub struct RebaseCommand { - #[clap(flatten)] - common: LocalCommonArgs, -} - -impl BlueBuildCommand for RebaseCommand { - fn try_run(&mut self) -> Result<()> { - trace!("RebaseCommand::try_run()"); - - check_can_run()?; - - let recipe = Recipe::parse(&self.common.recipe)?; - - let build = BuildCommand::builder(); - - #[cfg(feature = "multi-recipe")] - let build = build.recipe(vec![self.common.recipe.clone()]); - - #[cfg(not(feature = "multi-recipe"))] - let build = build.recipe(self.common.recipe.clone()); - - let mut build = build - .archive(LOCAL_BUILD) - .drivers(self.common.drivers) - .build(); - - let image_name = recipe.name.to_lowercase().replace('/', "_"); - clean_local_build_dir(&image_name, true)?; - debug!("Image name is {image_name}"); - - build.try_run()?; - let rebase_url = format!( - "ostree-unverified-image:oci-archive:{LOCAL_BUILD}/{image_name}.{ARCHIVE_SUFFIX}" - ); - - let status = if self.common.reboot { - info!("Rebasing image {image_name} and rebooting"); - - trace!("rpm-ostree rebase --reboot {rebase_url}"); - cmd!("rpm-ostree", "rebase", "--reboot", rebase_url) - .status() - .into_diagnostic()? - } else { - info!("Rebasing image {image_name}"); - - trace!("rpm-ostree rebase {rebase_url}"); - cmd!("rpm-ostree", "rebase", rebase_url) - .status() - .into_diagnostic()? - }; - - if status.success() { - info!("Successfully rebased to {image_name}"); - } else { - bail!("Failed to rebase to {image_name}"); - } - Ok(()) - } -} - -// ======================================================== // -// ========================= Helpers ====================== // -// ======================================================== // - -fn check_can_run() -> Result<()> { - trace!("check_can_run()"); - - blue_build_utils::check_command_exists("rpm-ostree")?; - - let cache = UsersCache::new(); - if cache.get_current_uid() != 0 { - bail!("You need to be root to rebase a local image! Try using 'sudo'."); - } - Ok(()) -} - -fn clean_local_build_dir(image_name: &str, rebase: bool) -> Result<()> { - trace!("clean_local_build_dir()"); - - let local_build_path = Path::new(LOCAL_BUILD); - let image_file_path = local_build_path.join(format!("{image_name}.{ARCHIVE_SUFFIX}")); - - if !image_file_path.exists() && !rebase { - bail!( - "Cannot upgrade {} as the image doesn't exist", - image_file_path.display() - ); - } - - if local_build_path.exists() { - debug!("Cleaning out build dir {LOCAL_BUILD}"); - - let entries = fs::read_dir(LOCAL_BUILD).into_diagnostic()?; - - for entry in entries { - let entry = entry.into_diagnostic()?; - let path = entry.path(); - trace!("Found {}", path.display()); - - if path.is_file() && path.ends_with(ARCHIVE_SUFFIX) { - if !rebase && path == image_file_path { - debug!("Not rebasing, keeping {}", image_file_path.display()); - continue; - } - trace!("Removing {}", path.display()); - fs::remove_file(path).into_diagnostic()?; - } - } - } else { - debug!( - "Creating build output dir at {}", - local_build_path.display() - ); - fs::create_dir_all(local_build_path).into_diagnostic()?; - } - - Ok(()) -} diff --git a/template/templates/modules/copy/README.md b/template/templates/modules/copy/README.md index a35ba9b6..b5aa19ca 100644 --- a/template/templates/modules/copy/README.md +++ b/template/templates/modules/copy/README.md @@ -4,10 +4,6 @@ Only compiler-based builds can use this module as it is built-in to the BlueBuild CLI tool. ::: -:::note -**NOTE:** This module is currently only available with the `use_unstable_cli` option on the GHA or using the `main` image. -::: - The `copy` module is a short-hand method of adding a [`COPY`](https://docs.docker.com/reference/dockerfile/#copy) instruction into the image. This can be used to copy files from images, other stages, or even from the build context. ## Usage diff --git a/template/templates/stages.j2 b/template/templates/stages.j2 index bbcddaf4..3fa08b69 100644 --- a/template/templates/stages.j2 +++ b/template/templates/stages.j2 @@ -25,7 +25,6 @@ COPY ./modules /modules # can be added to the ostree commits. FROM scratch AS stage-bins COPY --from=gcr.io/projectsigstore/cosign /ko-app/cosign /bins/cosign -COPY --from=docker.io/mikefarah/yq /usr/bin/yq /bins/yq COPY --from=ghcr.io/blue-build/cli: {%- if let Some(tag) = recipe.blue_build_tag -%} {{ tag }}