diff --git a/cincinnati/src/lib.rs b/cincinnati/src/lib.rs index 905c8f987..034378034 100644 --- a/cincinnati/src/lib.rs +++ b/cincinnati/src/lib.rs @@ -87,20 +87,6 @@ impl Release { _ => bail!("could not get manifest reference"), } } - - /// return the arch identifier set in metadata or returns `none` - pub fn metadata_arch_id(&mut self) -> String { - let metadata_arch_key = "release.openshift.io/architecture"; - let no_arch = String::from("none"); - let arch = self - .get_metadata_mut() - .map(|metadata| metadata.get(metadata_arch_key)) - .unwrap_or(None); - match arch { - Some(arch) => arch.to_string(), - _ => no_arch, - } - } } /// Type to represent a Release with all its information. @@ -219,7 +205,7 @@ impl Graph { R: Into, { let missing_manifest_ref = String::from("none"); - let mut release = release.into(); + let release = release.into(); match self.find_by_version(release.version()) { Some(id) => { let node = self.dag.node_weight_mut(id.0).expect(EXPECT_NODE_WEIGHT); @@ -228,18 +214,12 @@ impl Graph { if release.manifestref().unwrap_or(&missing_manifest_ref) != node.manifestref().unwrap_or(&missing_manifest_ref) { - let release_arch = release.metadata_arch_id(); - if release_arch == node.metadata_arch_id() { - bail!( - "mismatched manifest ref for concrete release {}: {}, {}", - release.version(), - release.manifestref().unwrap_or(&missing_manifest_ref), - node.manifestref().unwrap_or(&missing_manifest_ref) - ) - } - if release_arch == "multi" { - return Ok(id); - } + bail!( + "mismatched manifest ref for concrete release {}: {}, {}", + release.version(), + release.manifestref().unwrap_or(&missing_manifest_ref), + node.manifestref().unwrap_or(&missing_manifest_ref) + ) } } *node = release; diff --git a/cincinnati/src/plugins/internal/graph_builder/release.rs b/cincinnati/src/plugins/internal/graph_builder/release.rs index 5800b0d8a..56cd3826f 100644 --- a/cincinnati/src/plugins/internal/graph_builder/release.rs +++ b/cincinnati/src/plugins/internal/graph_builder/release.rs @@ -52,6 +52,24 @@ pub struct Metadata { pub metadata: MapImpl, } +impl Metadata { + /// return the arch identifier set in metadata or returns `none` + pub fn metadata_arch_id(&mut self) -> (String, String) { + let layer_metadata_arch_key = "release.openshift.io/architecture"; + let registry_manifest_arch_key = "io.openshift.upgrades.graph.release.arch"; + let no_arch = "none".to_string(); + let layer_metadata_arch = self + .metadata + .get(layer_metadata_arch_key) + .map_or(no_arch.clone(), |s| s.clone()); + let registry_manifest_arch = self + .metadata + .get(registry_manifest_arch_key) + .map_or(no_arch, |s| s.clone()); + return (layer_metadata_arch, registry_manifest_arch); + } +} + impl fmt::Display for Metadata { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( diff --git a/cincinnati/src/plugins/internal/graph_builder/release_scrape_dockerv2/registry/mod.rs b/cincinnati/src/plugins/internal/graph_builder/release_scrape_dockerv2/registry/mod.rs index e9cca440d..fdff99c34 100644 --- a/cincinnati/src/plugins/internal/graph_builder/release_scrape_dockerv2/registry/mod.rs +++ b/cincinnati/src/plugins/internal/graph_builder/release_scrape_dockerv2/registry/mod.rs @@ -386,7 +386,16 @@ pub async fn fetch_releases( ) .await? { - Some(release) => release, + Some(mut release) => { + let (layer_metadata_arch, registry_manifest_arch) = + release.metadata.metadata_arch_id(); + if layer_metadata_arch == "multi" && registry_manifest_arch != "multi" { + // single arch shard of multiarch release. dont want it + return Ok(()); + } else { + release + } + } None => { // Reminder: this means the layer_digests point to layers // without any release and we've cached this before @@ -469,42 +478,43 @@ async fn lookup_or_fetch( } None => { cache_misses.fetch_add(1, Ordering::SeqCst); - let placeholder = Option::from(Metadata { - kind: MetadataKind::V0, - version: Version::new(0, 0, 0), - previous: vec![], - next: vec![], - metadata: Default::default(), - }); - cache.write().await.insert(manifestref.clone(), placeholder); + cache.write().await.insert(manifestref.clone(), None); - let metadata = find_first_release_metadata( + let metadata = match find_first_release_metadata( layer_digests, registry_client, repo.clone(), tag.clone(), ) .await - .context("failed to find first release")? - .map(|mut metadata| { - // Attach the manifestref this release was found in for further processing - metadata - .metadata - .insert(manifestref_key, manifestref.clone()); - - // Process the manifest architecture if given - if let Some(arch) = arch { - // Encode the architecture as SemVer information - metadata.version.build = vec![semver::Identifier::AlphaNumeric(arch.clone())]; - - // Attach the architecture for later processing + { + Ok(Some(mut metadata)) => { + // Attach the manifestref this release was found in for further processing metadata .metadata - .insert("io.openshift.upgrades.graph.release.arch".to_owned(), arch); - }; + .insert(manifestref_key, manifestref.clone()); - metadata - }); + // Process the manifest architecture if given + if let Some(arch) = arch { + // Encode the architecture as SemVer information + metadata.version.build = + vec![semver::Identifier::AlphaNumeric(arch.clone())]; + + // Attach the architecture for later processing + metadata + .metadata + .insert("io.openshift.upgrades.graph.release.arch".to_owned(), arch); + }; + + Some(metadata) + } + Ok(None) => None, + Err(e) => { + cache.write().await.remove(&manifestref); + error!("Failed to find release metadata for {}: {}", &tag, e); + return Err(e); + } + }; trace!("[{}] Caching release metadata", &tag); cache @@ -651,16 +661,21 @@ async fn find_first_release_metadata( ); match tokio::task::spawn_blocking(move || assemble_metadata(&blob, metadata_filename)) - .await? - { + .await + .context(format!( + "[{}] Could not assemble metadata from layer ({})", + &tag, &layer_digest + ))? { Ok(metadata) => { return Ok(Some(metadata)); } Err(e) => { - debug!( + return Err(format_err!( "[{}] Could not assemble metadata from layer ({}): {}", - &tag, &layer_digest, e, - ); + &tag, + &layer_digest, + e + )) } } }