Skip to content

Commit 1752fef

Browse files
committed
ostree-ext/store: make ostree commit reproducible
Use BtreeMap and JsonOrderedSerialize to ensure ordering Signed-off-by: Etienne Champetier <[email protected]>
1 parent c4fcd14 commit 1752fef

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

ostree-ext/src/container/store.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use super::*;
99
use crate::chunking::{self, Chunk};
1010
use crate::container::Decompressor;
11+
use crate::json::JsonOrderedSerialize;
1112
use crate::logging::system_repo_journal_print;
1213
use crate::refescape;
1314
use crate::sysroot::SysrootLock;
@@ -28,7 +29,7 @@ use oci_spec::image::{
2829
};
2930
use ostree::prelude::{Cast, FileEnumeratorExt, FileExt, ToVariant};
3031
use ostree::{gio, glib};
31-
use std::collections::{BTreeMap, BTreeSet, HashMap};
32+
use std::collections::{BTreeMap, BTreeSet};
3233
use std::fmt::Write as _;
3334
use std::iter::FromIterator;
3435
use std::num::NonZeroUsize;
@@ -59,7 +60,7 @@ const META_CONFIG: &str = "ostree.container.image-config";
5960
/// Value of type `a{sa{su}}` containing number of filtered out files
6061
pub const META_FILTERED: &str = "ostree.tar-filtered";
6162
/// The type used to store content filtering information with `META_FILTERED`.
62-
pub type MetaFilteredData = HashMap<String, HashMap<String, u32>>;
63+
pub type MetaFilteredData = BTreeMap<String, BTreeMap<String, u32>>;
6364

6465
/// The ref prefixes which point to ostree deployments. (TODO: Add an official API for this)
6566
const OSTREE_BASE_DEPLOYMENT_REFS: &[&str] = &["ostree/0", "ostree/1"];
@@ -595,9 +596,13 @@ impl ImageImporter {
595596
Self::CACHED_KEY_MANIFEST_DIGEST,
596597
manifest_digest.to_string(),
597598
);
598-
let cached_manifest = serde_json::to_string(manifest).context("Serializing manifest")?;
599+
let cached_manifest = manifest
600+
.to_json_canonical_string()
601+
.context("Serializing manifest")?;
599602
commitmeta.insert(Self::CACHED_KEY_MANIFEST, cached_manifest);
600-
let cached_config = serde_json::to_string(config).context("Serializing config")?;
603+
let cached_config = config
604+
.to_json_canonical_string()
605+
.context("Serializing config")?;
601606
commitmeta.insert(Self::CACHED_KEY_CONFIG, cached_config);
602607
let commitmeta = commitmeta.to_variant();
603608
// Clone these to move into blocking method
@@ -921,7 +926,7 @@ impl ImageImporter {
921926
let ostree_ref = ref_for_image(&target_imgref.imgref)?;
922927

923928
let mut layer_commits = Vec::new();
924-
let mut layer_filtered_content: MetaFilteredData = HashMap::new();
929+
let mut layer_filtered_content: MetaFilteredData = BTreeMap::new();
925930
let have_derived_layers = !import.layers.is_empty();
926931
tracing::debug!("Processing layers: {}", import.layers.len());
927932
for layer in import.layers {
@@ -963,7 +968,7 @@ impl ImageImporter {
963968
.with_context(|| format!("Parsing layer blob {}", layer.layer.digest()))?;
964969
tracing::debug!("Imported layer: {}", r.commit.as_str());
965970
layer_commits.push(r.commit);
966-
let filtered_owned = HashMap::from_iter(r.filtered.clone());
971+
let filtered_owned = BTreeMap::from_iter(r.filtered.clone());
967972
if let Some((filtered, n_rest)) = bootc_utils::collect_until(
968973
r.filtered.iter(),
969974
const { NonZeroUsize::new(5).unwrap() },
@@ -999,9 +1004,10 @@ impl ImageImporter {
9991004
let _ = self.layer_byte_progress.take();
10001005
let _ = self.layer_progress.take();
10011006

1002-
let serialized_manifest = serde_json::to_string(&import.manifest)?;
1003-
let serialized_config = serde_json::to_string(&import.config)?;
1004-
let mut metadata = HashMap::new();
1007+
// Use serde_json::Value to make output reproducible
1008+
let serialized_manifest = import.manifest.to_json_canonical_string()?;
1009+
let serialized_config = import.config.to_json_canonical_string()?;
1010+
let mut metadata = BTreeMap::new();
10051011
metadata.insert(
10061012
META_MANIFEST_DIGEST,
10071013
import.manifest_digest.to_string().to_variant(),

0 commit comments

Comments
 (0)