wasmer_cli/commands/run/capabilities/
mod.rs1use crate::config::WasmerEnv;
2
3use super::PackageSource;
4use anyhow::anyhow;
5use sha2::{Digest, Sha256};
6use std::{
7 path::{Path, PathBuf},
8 time::UNIX_EPOCH,
9};
10
11use wasmer_config::package::PackageSource as PackageSpecifier;
12
13pub(crate) mod net;
16
17const DEFAULT_WASMER_PKG_CAPABILITY_CACHE_DIR: &str = "pkg_capabilities";
19
20#[derive(Debug, serde::Serialize, serde::Deserialize)]
22pub(crate) struct PkgCapabilityCache {
23 pub enable_networking: bool,
24}
25
26pub(crate) fn get_capability_cache_path(
27 env: &WasmerEnv,
28 input: &PackageSource,
29) -> anyhow::Result<PathBuf> {
30 let registry_name = env
31 .registry_public_url()?
32 .host_str()
33 .unwrap_or("unknown_registry")
34 .replace('.', "_");
35
36 let package_cache_path = match &input {
39 PackageSource::File(f) => {
40 let full_path = f.canonicalize()?.to_path_buf();
41 let metadata = full_path
42 .parent()
43 .ok_or(anyhow!("No parent!"))?
44 .metadata()?
45 .modified()?;
46
47 let mut hash = Sha256::new();
48 hash.update(
49 full_path
50 .into_os_string()
51 .into_string()
52 .map_err(|e| anyhow!("{e:?}"))?
53 .as_bytes(),
54 );
55 hash.update(
56 metadata
57 .duration_since(UNIX_EPOCH)?
58 .as_millis()
59 .to_be_bytes(),
60 );
61
62 format!("path_{}.json", hex::encode(hash.finalize()))
63 }
64 PackageSource::Dir(f) => {
65 let full_path = f.canonicalize()?.to_path_buf();
66 let metadata = full_path.metadata()?.modified()?;
67
68 let mut hash = Sha256::new();
69 hash.update(
70 full_path
71 .into_os_string()
72 .into_string()
73 .map_err(|e| anyhow!("{e:?}"))?
74 .as_bytes(),
75 );
76 hash.update(
77 metadata
78 .duration_since(UNIX_EPOCH)?
79 .as_millis()
80 .to_be_bytes(),
81 );
82
83 format!("path_{}.json", hex::encode(hash.finalize()))
84 }
85 PackageSource::Package(p) => match p {
86 PackageSpecifier::Ident(id) => match id {
87 wasmer_config::package::PackageIdent::Named(n) => format!(
88 "ident_{}_{}",
89 n.namespace.clone().unwrap_or("unknown_namespace".into()),
90 n.name
91 ),
92 wasmer_config::package::PackageIdent::Hash(h) => {
93 format!("hash_{h}")
94 }
95 },
96 PackageSpecifier::Path(f) => {
97 let full_path = PathBuf::from(f).canonicalize()?.to_path_buf();
98
99 let mut hasher = Sha256::new();
100 hasher.update(
101 full_path
102 .clone()
103 .into_os_string()
104 .into_string()
105 .map_err(|e| anyhow!("{e:?}"))?
106 .as_bytes(),
107 );
108
109 if full_path.is_dir() {
110 hasher.update(
111 full_path
112 .metadata()?
113 .modified()?
114 .duration_since(UNIX_EPOCH)?
115 .as_millis()
116 .to_be_bytes(),
117 );
118 } else if full_path.is_file() {
119 hasher.update(
120 full_path
121 .parent()
122 .ok_or(anyhow!("No parent!"))?
123 .metadata()?
124 .modified()?
125 .duration_since(UNIX_EPOCH)?
126 .as_millis()
127 .to_be_bytes(),
128 );
129 }
130 format!("path_{}.json", hex::encode(hasher.finalize()))
131 }
132 PackageSpecifier::Url(u) => {
133 let mut hasher = Sha256::new();
134 hasher.update(u.to_string().as_bytes());
135 format!("path_{}.json", hex::encode(hasher.finalize()))
136 }
137 },
138 };
139 Ok(env
140 .cache_dir()
141 .join(DEFAULT_WASMER_PKG_CAPABILITY_CACHE_DIR)
142 .join(registry_name)
143 .join(package_cache_path))
144}
145
146pub(crate) fn get_cached_capability(path: &Path) -> anyhow::Result<PkgCapabilityCache> {
147 let raw = std::fs::read_to_string(path)?;
148 tracing::debug!("cache hit for package capability at {}", path.display());
149 serde_json::from_str::<PkgCapabilityCache>(&raw)
150 .map_err(|e| anyhow!("while deserializing package capability cache: {e:?}"))
151}