From 52d67fd9db433c46da7a4c3e27f8440097382270 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 7 Mar 2022 11:39:08 -0500 Subject: [PATCH] Add new `objectsource` module In ostree we aim to provide generic mechanisms that can be consumed by any package or build system. Hence we often use the term "component" instead of "package". This new `objectsource` module is an abstraction over basic metadata for a component/package, currently name, identifier, and last change time. This will be used for splitting up a single ostree commit back into "chunks" or container image layers, grouping objects that come from the same component together. https://github.com/ostreedev/ostree-rs-ext/issues/69 --- lib/src/lib.rs | 2 + lib/src/objectsource.rs | 87 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 lib/src/objectsource.rs diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 032bf040..38d4e822 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -37,7 +37,9 @@ pub mod tar; pub mod tokio_util; pub(crate) mod commit; +pub mod objectsource; pub(crate) mod objgv; + /// Prelude, intended for glob import. pub mod prelude { #[doc(hidden)] diff --git a/lib/src/objectsource.rs b/lib/src/objectsource.rs new file mode 100644 index 00000000..9faa26b9 --- /dev/null +++ b/lib/src/objectsource.rs @@ -0,0 +1,87 @@ +//! Metadata about the source of an object: a component or package. +//! +//! This is used to help split up containers into distinct layers. + +use std::borrow::Borrow; +use std::collections::{BTreeMap, HashSet}; +use std::hash::Hash; +use std::rc::Rc; + +use serde::{Deserialize, Serialize, Serializer}; + +mod rcstr_serialize { + use serde::Deserializer; + + use super::*; + + pub(crate) fn serialize(v: &Rc, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&*v) + } + + pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let v = String::deserialize(deserializer)?; + Ok(Rc::from(v.into_boxed_str())) + } +} + +/// Identifier for content (e.g. package/layer). Not necessarily human readable. +pub type ContentID = Rc; + +/// Metadata about a component/package. +#[derive(Debug, Eq, Deserialize, Serialize)] +pub struct ObjectSourceMeta { + /// Unique identifier, does not need to be human readable, but can be. + #[serde(with = "rcstr_serialize")] + pub identifier: ContentID, + /// Identifier for this source (e.g. package name-version, git repo). + /// Unlike the [`ContentID`], this should be human readable. + #[serde(with = "rcstr_serialize")] + pub name: Rc, + /// Identifier for the *source* of this content; for example, if multiple binary + /// packages derive from a single git repository or source package. + #[serde(with = "rcstr_serialize")] + pub srcid: Rc, + /// Unitless, relative offset of last change time. + /// One suggested way to generate this number is to have it be in units of hours or days + /// since the earliest changed item. + pub change_time_offset: u32, +} + +impl PartialEq for ObjectSourceMeta { + fn eq(&self, other: &Self) -> bool { + *self.identifier == *other.identifier + } +} + +impl Hash for ObjectSourceMeta { + fn hash(&self, state: &mut H) { + self.identifier.hash(state); + } +} + +impl Borrow for ObjectSourceMeta { + fn borrow(&self) -> &str { + &*self.identifier + } +} + +/// Maps from e.g. "bash" or "kernel" to metadata about that content +pub type ObjectMetaSet = HashSet; + +/// Maps from an ostree content object digest to the `ContentSet` key. +pub type ObjectMetaMap = BTreeMap; + +/// Grouping of metadata about an object. +#[derive(Debug, Default)] +pub struct ObjectMeta { + /// The set of object sources with their metadata. + pub set: ObjectMetaSet, + /// Mapping from content object to source. + pub map: ObjectMetaMap, +}