From 6fc79fe2554f7726c03e207570145ca48dc1f07f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 24 Oct 2024 07:58:26 -0400 Subject: [PATCH 1/2] tar: Don't filter out toplevel /run, /proc etc Otherwise we break things when using this code to process a "non-ostree" image. Signed-off-by: Colin Walters --- lib/src/tar/write.rs | 11 ++++++++++- lib/tests/it/main.rs | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/src/tar/write.rs b/lib/src/tar/write.rs index b87249fe..29221e9b 100644 --- a/lib/src/tar/write.rs +++ b/lib/src/tar/write.rs @@ -182,8 +182,12 @@ fn normalize_validate_path<'a>( ret.push(camino::Utf8Component::CurDir); } let mut found_first = false; + let mut excluded = false; for part in components { let part = part?; + if excluded { + return Ok(NormalizedPathResult::Filtered(part.as_str())); + } if !found_first { if let Utf8Component::Normal(part) = part { found_first = true; @@ -203,7 +207,10 @@ fn normalize_validate_path<'a>( } } o if EXCLUDED_TOPLEVEL_PATHS.contains(&o) => { - return Ok(NormalizedPathResult::Filtered(part)); + // We don't want to actually drop the toplevel, but mark + // *children* of it as excluded. + excluded = true; + ret.push(part) } _ if config.allow_nonusr => ret.push(part), _ => { @@ -516,6 +523,8 @@ mod tests { ("usr///share/.//blah", "./usr/share/blah"), ("var/lib/blah", "./usr/share/factory/var/lib/blah"), ("./var/lib/blah", "./usr/share/factory/var/lib/blah"), + ("dev", "./dev"), + ("/proc", "./proc"), ("./", "."), ]; let valid_nonusr = &[("boot", "./boot"), ("opt/puppet/blah", "./opt/puppet/blah")]; diff --git a/lib/tests/it/main.rs b/lib/tests/it/main.rs index d2bd27f6..97f3efff 100644 --- a/lib/tests/it/main.rs +++ b/lib/tests/it/main.rs @@ -395,7 +395,9 @@ async fn test_tar_write() -> Result<()> { .run()?; assert_eq!(r.filtered.len(), 1); assert!(r.filtered.get("var").is_none()); - assert_eq!(*r.filtered.get("run").unwrap(), 2); + // TODO: change filter_tar to properly make this run/somefile, but eh...we're + // just going to accept this stuff in the future but ignore it anyways. + assert_eq!(*r.filtered.get("somefile").unwrap(), 1); Ok(()) } From 8e19d6e848239cb6793bfd24c04414337d84f6a4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 24 Oct 2024 07:59:35 -0400 Subject: [PATCH 2/2] store: Accept just containers.bootc for as bootable This allows us to accept images to that don't have any metadata keys starting with `ostree`. Signed-off-by: Colin Walters --- lib/src/container/encapsulate.rs | 4 +++- lib/src/container/store.rs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/src/container/encapsulate.rs b/lib/src/container/encapsulate.rs index d411f5e1..5345151f 100644 --- a/lib/src/container/encapsulate.rs +++ b/lib/src/container/encapsulate.rs @@ -27,6 +27,8 @@ pub const LEGACY_VERSION_LABEL: &str = "version"; /// The label which indicates where the ostree layers stop, and the /// derived ones start. pub const DIFFID_LABEL: &str = "ostree.final-diffid"; +/// The label for bootc. +pub const BOOTC_LABEL: &str = "containers.bootc"; /// Annotation injected into the layer to say that this is an ostree commit. /// However, because this gets lost when converted to D2S2 https://docs.docker.com/registry/spec/manifest-v2-2/ @@ -68,7 +70,7 @@ fn commit_meta_to_labels<'a>( #[allow(clippy::explicit_auto_deref)] if let Some(v) = meta.lookup::(*ostree::METADATA_KEY_BOOTABLE)? { labels.insert(ostree::METADATA_KEY_BOOTABLE.to_string(), v.to_string()); - labels.insert("containers.bootc".into(), "1".into()); + labels.insert(BOOTC_LABEL.into(), "1".into()); } // Handle any other string-typed values here. for k in &[&ostree::METADATA_KEY_LINUX] { diff --git a/lib/src/container/store.rs b/lib/src/container/store.rs index a275c0af..6563d341 100644 --- a/lib/src/container/store.rs +++ b/lib/src/container/store.rs @@ -584,7 +584,9 @@ impl ImageImporter { let config_labels = super::labels_of(&config); if self.require_bootable { let bootable_key = *ostree::METADATA_KEY_BOOTABLE; - let bootable = config_labels.map_or(false, |l| l.contains_key(bootable_key)); + let bootable = config_labels.map_or(false, |l| { + l.contains_key(bootable_key) || l.contains_key(BOOTC_LABEL) + }); if !bootable { anyhow::bail!("Target image does not have {bootable_key} label"); }