feat: Squash builds (#155)
### Buildah/Podman support Buildah and podman can make heavy use of the squash feature. Something that I've noticed when trying to build from inside of a container, requiring intermediate layers with mounts causes build times to skyrocket. Build times are much faster when using the `--squash` functionality (seen as `--layers=false`). Here are the following results from my personal build using both squash and non-squash functionality. #### Squash upgrade: ``` $> rpm-ostree upgrade Pulling manifest: ostree-image-signed:docker://registry.gitlab.com/wunker-bunker/wunker-os/jp-laptop Importing: ostree-image-signed:docker://registry.gitlab.com/wunker-bunker/wunker-os/jp-laptop (digest: sha256:60f743ba322041918d302e7e7f10438c59502e19343c294064bacb676c8eb7b7) ostree chunk layers already present: 65 custom layers already present: 3 custom layers needed: 1 (814.0 MB) ``` All changes appear to show as a single custom layer. Any small change even at the end of the build appears to require completely downloading the new layer (squash only squashes additional layers on top of the base layer). This makes sense as layers cannot currently be downloaded by diff. #### Non-squash upgrade: ``` $> rpm-ostree upgrade Pulling manifest: ostree-image-signed:docker://registry.gitlab.com/wunker-bunker/wunker-os/jp-desktop-gaming:latest Importing: ostree-image-signed:docker://registry.gitlab.com/wunker-bunker/wunker-os/jp-desktop-gaming:latest (digest: sha256:0658b51febfcbaa1722961b7a6d2b197d3823a6228e330f45dd1e1aaefd145c5) ostree chunk layers already present: 65 custom layers already present: 4 custom layers needed: 15 (942.4 MB) ``` As expected, there are more layers when not squashing and the size is slightly bigger. Most likely due to there being extra information stored in the layers that is subsequently removed. ### Docker support Docker is apparently [no longer supporting](https://github.com/docker/buildx/issues/1287) the use of the `--squash` arg. The use of squash will not be available for the docker driver in this case.
This commit is contained in:
parent
e9c96e204d
commit
6e3a193e92
11 changed files with 269 additions and 101 deletions
|
|
@ -22,13 +22,14 @@ use crate::{
|
|||
commands::template::TemplateCommand,
|
||||
credentials,
|
||||
drivers::{
|
||||
opts::{BuildTagPushOpts, CompressionType},
|
||||
opts::{BuildTagPushOpts, CompressionType, GetMetadataOpts},
|
||||
Driver,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{BlueBuildCommand, DriverArgs};
|
||||
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
#[derive(Debug, Clone, Args, TypedBuilder)]
|
||||
pub struct BuildCommand {
|
||||
/// The recipe file to build an image
|
||||
|
|
@ -181,6 +182,7 @@ impl BlueBuildCommand for BuildCommand {
|
|||
TemplateCommand::builder()
|
||||
.recipe(&recipe_path)
|
||||
.output(PathBuf::from("Containerfile"))
|
||||
.drivers(DriverArgs::builder().squash(self.drivers.squash).build())
|
||||
.build()
|
||||
.try_run()?;
|
||||
|
||||
|
|
@ -215,6 +217,7 @@ impl BuildCommand {
|
|||
archive_dir.to_string_lossy().trim_end_matches('/'),
|
||||
recipe.name.to_lowercase().replace('/', "_"),
|
||||
))
|
||||
.squash(self.drivers.squash)
|
||||
.build()
|
||||
} else {
|
||||
BuildTagPushOpts::builder()
|
||||
|
|
@ -224,6 +227,7 @@ impl BuildCommand {
|
|||
.no_retry_push(self.no_retry_push)
|
||||
.retry_count(self.retry_count)
|
||||
.compression(self.compression_format)
|
||||
.squash(self.drivers.squash)
|
||||
.build()
|
||||
};
|
||||
|
||||
|
|
@ -339,14 +343,23 @@ impl BuildCommand {
|
|||
// ========================= Helpers ====================== //
|
||||
// ======================================================== //
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn sign_images(image_name: &str, tag: Option<&str>) -> Result<()> {
|
||||
trace!("BuildCommand::sign_images({image_name}, {tag:?})");
|
||||
|
||||
env::set_var("COSIGN_PASSWORD", "");
|
||||
env::set_var("COSIGN_YES", "true");
|
||||
|
||||
let inspect_opts = GetMetadataOpts::builder().image(image_name);
|
||||
|
||||
let inspect_opts = if let Some(tag) = tag {
|
||||
inspect_opts.tag(tag).build()
|
||||
} else {
|
||||
inspect_opts.build()
|
||||
};
|
||||
|
||||
let image_digest = Driver::get_inspection_driver()
|
||||
.get_metadata(image_name, tag.map_or_else(|| "latest", |t| t))?
|
||||
.get_metadata(&inspect_opts)?
|
||||
.digest;
|
||||
let image_name_digest = format!("{image_name}@{image_digest}");
|
||||
let image_name_tag = tag.map_or_else(|| image_name.to_owned(), |t| format!("{image_name}:{t}"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue