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

Method stage

atomic-repository/src/repository/sandbox.rs:234–300  ·  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

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