MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / stage

Method stage

atomic-repository/src/repository/sandbox.rs:233–299  ·  view source on GitHub ↗

Produce a two-layer OCI image: a base layer (the `base_view` materialized) plus a thin delta layer (files that differ on `view` versus `base_view`, with whiteouts for files removed on `view`). Built for the inner loop: the base is content-addressed by its `diff_id` and can be pulled once and cached, so each iteration ships only the small delta. Provenance (view names and Merkle states) is recorde

(&self, opts: StageOptions)

Source from the content-addressed store, hash-verified

231 /// delta. Provenance (view names and Merkle states) is recorded in the
232 /// manifest annotations. Returns the manifest digest and base `diff_id`.
233 pub fn stage(&self, opts: StageOptions) -> Result<StageResult, RepositoryError> {
234 // 1. Base layer: materialize the shared base view to a temp dir.
235 let base_dir = tempfile::tempdir()?;
236 self.materialize_view_to(&opts.base_view, base_dir.path())?;
237 let base_layer = oci::layer_from_dir(base_dir.path())?;
238 let base_diff_id = base_layer.diff_id.clone();
239
240 // 2. Delta: files new or changed on `view` vs. `base_view`, plus
241 // whiteouts for files present on the base but gone on `view`.
242 let view_paths = self.visible_file_paths(&opts.view)?;
243 let base_paths = self.visible_file_paths(&opts.base_view)?;
244
245 let mut changed: Vec<(String, Vec<u8>)> = Vec::new();
246 for path in &view_paths {
247 let view_bytes = match self.get_file_content_on_view(path, &opts.view)? {
248 Some(bytes) => bytes,
249 None => continue,
250 };
251 let base_bytes = self.get_file_content_on_view(path, &opts.base_view)?;
252 if base_bytes.as_deref() != Some(view_bytes.as_slice()) {
253 changed.push((path.clone(), view_bytes));
254 }
255 }
256
257 let mut whiteouts: Vec<String> = Vec::new();
258 for path in &base_paths {
259 if !view_paths.contains(path) {
260 whiteouts.push(path.clone());
261 }
262 }
263
264 let delta_files = changed.len();
265 let delta_layer = oci::layer_from_entries(&changed, &whiteouts)?;
266
267 // 3. Assemble the layout with provenance annotations.
268 let view_info = self.get_view_info(&opts.view)?;
269 let base_info = self.get_view_info(&opts.base_view)?;
270 let mut annotations = BTreeMap::new();
271 annotations.insert("org.atomic.view".to_string(), opts.view.clone());
272 annotations.insert("org.atomic.base-view".to_string(), opts.base_view.clone());
273 annotations.insert(
274 "org.atomic.view-merkle".to_string(),
275 view_info.state_base32(),
276 );
277 annotations.insert(
278 "org.atomic.base-merkle".to_string(),
279 base_info.state_base32(),
280 );
281
282 let config = OciImageConfig {
283 architecture: oci::host_arch(),
284 os: "linux".to_string(),
285 env: Vec::new(),
286 entrypoint: Vec::new(),
287 annotations,
288 };
289
290 let manifest_digest =

Callers 1

runMethod · 0.80

Calls 15

layer_from_dirFunction · 0.85
layer_from_entriesFunction · 0.85
host_archFunction · 0.85
write_image_layoutFunction · 0.85
materialize_view_toMethod · 0.80
visible_file_pathsMethod · 0.80
get_view_infoMethod · 0.80
state_base32Method · 0.80
pathMethod · 0.45
cloneMethod · 0.45
as_sliceMethod · 0.45

Tested by

no test coverage detected