From 6e60d2194164b40fdb1593bab5e1d1b420c01a64 Mon Sep 17 00:00:00 2001 From: Radu Matei Date: Tue, 5 Mar 2024 14:01:14 +0100 Subject: [PATCH] fix(oci/config): ensure unique OCI image config This commit ensures that applications pushed to OCI have unique image config fields for unique Spin application content and metadata by adding a label in the OCI image config to the content digest (SHA256) of the Spin locked application file. This is to address the issue of the Containerd Spin shim serving outdated content, because all images of Spin apps on a node would have the same image ID (the content digest of the OCI config object, which was identical for all Spin apps). ref https://github.com/spinkube/spin-operator/issues/40 Signed-off-by: Radu Matei Co-authored-by: Rajat Jindal Co-authored-by: Danielle Lancashire Co-authored-by: Michelle Dhanani (cherry picked from commit 14cdc4224c549ea9aab0353844ac8088c7b8d2a9) --- crates/oci/src/client.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/oci/src/client.rs b/crates/oci/src/client.rs index 2aad53fa39..1b896bd5ae 100644 --- a/crates/oci/src/client.rs +++ b/crates/oci/src/client.rs @@ -1,5 +1,6 @@ //! Spin's client for distributing applications via OCI registries +use std::collections::HashMap; use std::path::{Path, PathBuf}; use anyhow::{bail, Context, Result}; @@ -174,8 +175,19 @@ impl Client { SPIN_APPLICATION_MEDIA_TYPE.to_string(), None, ); + let config_layer_digest = locked_config_layer.sha256_digest().clone(); layers.push(locked_config_layer); + let mut labels = HashMap::new(); + labels.insert( + "com.fermyon.spin.lockedAppDigest".to_string(), + config_layer_digest, + ); + let cfg = oci_distribution::config::Config { + labels: Some(labels), + ..Default::default() + }; + // Construct empty/default OCI config file. Data may be parsed according to // the expected config structure per the image spec, so we want to ensure it conforms. // (See https://github.com/opencontainers/image-spec/blob/main/config.md) @@ -183,6 +195,11 @@ impl Client { let oci_config_file = ConfigFile { architecture: oci_distribution::config::Architecture::Wasm, os: oci_distribution::config::Os::Wasip1, + // We need to ensure that the image config for different content is updated. + // Without referencing the digest of the locked application in the OCI image config, + // all Spin applications would get the same image config digest, resulting in the same + // image ID in container runtimes. + config: Some(cfg), ..Default::default() }; let oci_config =