From cd8d178aeb1e3055146737f05c17be7ac9b3ae4e Mon Sep 17 00:00:00 2001 From: Ayush Jha Date: Wed, 3 Apr 2024 00:58:27 +0545 Subject: [PATCH] Maek webc hash required if a package does not have name, it falls back to it's webc hash. This does mean that you need a webc hash to actually generate the PackageId. --- lib/wasix/src/bin_factory/binary_package.rs | 8 +++++++- .../runtime/package_loader/load_package_tree.rs | 12 ++++++++---- lib/wasix/src/runtime/resolver/inputs.rs | 9 +++++++-- lib/wasix/src/runtime/resolver/outputs.rs | 15 ++++++++++++--- lib/wasix/src/runtime/resolver/resolve.rs | 5 +++-- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/lib/wasix/src/bin_factory/binary_package.rs b/lib/wasix/src/bin_factory/binary_package.rs index 28e5627108f..dc411ca427a 100644 --- a/lib/wasix/src/bin_factory/binary_package.rs +++ b/lib/wasix/src/bin_factory/binary_package.rs @@ -10,7 +10,7 @@ use webc::{compat::SharedBytes, Container}; use crate::{ runtime::{ module_cache::ModuleHash, - resolver::{PackageId, PackageInfo, PackageSpecifier, ResolveError}, + resolver::{PackageId, PackageInfo, PackageSpecifier, ResolveError, WebcHash}, }, Runtime, }; @@ -83,9 +83,15 @@ impl BinaryPackage { ) -> Result { let source = rt.source(); let root = PackageInfo::from_manifest(container.manifest())?; + let hash = if let Some(hash) = container.webc_hash() { + WebcHash::from_bytes(hash) + } else { + return Err(anyhow::anyhow!("No hash found in the container")); + }; let root_id = PackageId { package_name: root.name.clone(), version: root.version.clone(), + hash, }; let resolution = crate::runtime::resolver::resolve(&root_id, &root, &*source).await?; diff --git a/lib/wasix/src/runtime/package_loader/load_package_tree.rs b/lib/wasix/src/runtime/package_loader/load_package_tree.rs index 022a99c7c7c..3c21642cedb 100644 --- a/lib/wasix/src/runtime/package_loader/load_package_tree.rs +++ b/lib/wasix/src/runtime/package_loader/load_package_tree.rs @@ -46,11 +46,15 @@ pub async fn load_package_tree( let file_system_memory_footprint = count_file_system(&fs, Path::new("/")); + let package_name = if let Some(name) = &root.package_name { + name.clone() + } else { + tracing::warn!("The root package doesn't have a name. Falling back to the package ID"); + root.hash.as_hex() + }; + let loaded = BinaryPackage { - package_name: root - .package_name - .clone() - .context("Unnamed packages are not supported yet.")?, + package_name, version: root.version.clone(), when_cached: crate::syscalls::platform_clock_time_get( wasmer_wasix_types::wasi::Snapshot0Clockid::Monotonic, diff --git a/lib/wasix/src/runtime/resolver/inputs.rs b/lib/wasix/src/runtime/resolver/inputs.rs index 6c11f0f4b9f..d0d87aaea6b 100644 --- a/lib/wasix/src/runtime/resolver/inputs.rs +++ b/lib/wasix/src/runtime/resolver/inputs.rs @@ -155,7 +155,7 @@ pub struct PackageSummary { impl PackageSummary { pub fn package_id(&self) -> PackageId { - self.pkg.id() + self.pkg.id(self.dist.webc_sha256) } pub fn from_webc_file(path: impl AsRef) -> Result { @@ -242,10 +242,11 @@ impl PackageInfo { }) } - pub fn id(&self) -> PackageId { + pub fn id(&self, hash: WebcHash) -> PackageId { PackageId { package_name: self.name.clone(), version: self.version.clone(), + hash, } } } @@ -403,6 +404,10 @@ impl WebcHash { pub fn as_bytes(self) -> [u8; 32] { self.0 } + + pub fn as_hex(&self) -> String { + hex::encode(&self.0) + } } impl From<[u8; 32]> for WebcHash { diff --git a/lib/wasix/src/runtime/resolver/outputs.rs b/lib/wasix/src/runtime/resolver/outputs.rs index d33f82d2bfb..8c2d99dafc6 100644 --- a/lib/wasix/src/runtime/resolver/outputs.rs +++ b/lib/wasix/src/runtime/resolver/outputs.rs @@ -13,6 +13,8 @@ use semver::Version; use crate::runtime::resolver::{DistributionInfo, PackageInfo}; +use super::WebcHash; + #[derive(Debug, Clone)] pub struct Resolution { pub package: ResolvedPackage, @@ -32,6 +34,7 @@ pub struct ItemLocation { pub struct PackageId { pub package_name: Option, pub version: Version, + pub hash: WebcHash, } impl Display for PackageId { @@ -39,11 +42,12 @@ impl Display for PackageId { let PackageId { package_name, version, + hash, } = self; - if let Some(package_name) = &self.package_name { - write!(f, "{package_name}@{version}")?; + if let Some(package_name) = &package_name { + return write!(f, "{package_name}@{version}"); } - write!(f, "@{version}") + write!(f, "{hash}") } } @@ -86,6 +90,11 @@ impl DependencyGraph { pkg } + pub fn id(&self) -> &PackageId { + let Node { id, .. } = &self.graph[self.root]; + id + } + pub fn root(&self) -> NodeIndex { self.root } diff --git a/lib/wasix/src/runtime/resolver/resolve.rs b/lib/wasix/src/runtime/resolver/resolve.rs index e627e0ef250..192a75cba3d 100644 --- a/lib/wasix/src/runtime/resolver/resolve.rs +++ b/lib/wasix/src/runtime/resolver/resolve.rs @@ -215,7 +215,7 @@ fn cycle_error(graph: &petgraph::Graph) -> ResolveError { // Don't forget to make the cycle start and end with the same node cycle.push(lowest_index_node); - let package_ids = cycle.into_iter().map(|ix| graph[ix].pkg.id()).collect(); + let package_ids = cycle.into_iter().map(|ix| graph[ix].id.clone()).collect(); ResolveError::Cycle(package_ids) } @@ -264,6 +264,7 @@ where for PackageId { package_name, version, + .. } in package_ids { if let Some(package_name) = package_name { @@ -390,7 +391,7 @@ fn resolve_package(dependency_graph: &DependencyGraph) -> Result