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

Function layer_from_dir

atomic-repository/src/oci.rs:82–131  ·  view source on GitHub ↗

Build a gzipped tar layer from a directory's contents (recursive). Paths inside the tar are relative to `dir`. Regular files and symlinks are included; directory entries themselves are omitted (their paths are implied by the files within). Entries are emitted in a deterministic (sorted) order. Computes `diff_id` (sha256 of the uncompressed tar stream) and `digest` (sha256 of the gzipped bytes).

(dir: &Path)

Source from the content-addressed store, hash-verified

80/// Computes `diff_id` (sha256 of the uncompressed tar stream) and `digest`
81/// (sha256 of the gzipped bytes).
82pub fn layer_from_dir(dir: &Path) -> std::io::Result<OciLayer> {
83 let mut entries: Vec<(String, PathBuf, bool)> = Vec::new();
84 for entry in WalkDir::new(dir) {
85 let entry = entry.map_err(std::io::Error::from)?;
86 let file_type = entry.file_type();
87 if file_type.is_dir() {
88 continue;
89 }
90 let rel = match entry.path().strip_prefix(dir) {
91 Ok(r) => r,
92 Err(_) => continue,
93 };
94 if rel.as_os_str().is_empty() {
95 continue;
96 }
97 entries.push((
98 rel.to_string_lossy().into_owned(),
99 entry.path().to_path_buf(),
100 file_type.is_symlink(),
101 ));
102 }
103 entries.sort_by(|a, b| a.0.cmp(&b.0));
104
105 let mut tar_buf = Vec::new();
106 {
107 let mut builder = Builder::new(&mut tar_buf);
108 for (rel, full, is_symlink) in &entries {
109 if *is_symlink {
110 let target = std::fs::read_link(full)?;
111 let mut header = Header::new_gnu();
112 header.set_entry_type(EntryType::Symlink);
113 header.set_size(0);
114 header.set_mode(0o777);
115 header.set_mtime(0);
116 builder.append_link(&mut header, rel, &target)?;
117 } else {
118 let data = std::fs::read(full)?;
119 let mut header = Header::new_gnu();
120 header.set_entry_type(EntryType::Regular);
121 header.set_size(data.len() as u64);
122 header.set_mode(0o644);
123 header.set_mtime(0);
124 builder.append_data(&mut header, rel, data.as_slice())?;
125 }
126 }
127 builder.finish()?;
128 }
129
130 finish_layer(tar_buf)
131}
132
133/// Build a single layer from an in-memory set of `(relative_path, bytes)` files
134/// plus optional whiteouts.

Callers 4

stageMethod · 0.85
sealMethod · 0.85

Calls 9

finish_layerFunction · 0.85
is_dirMethod · 0.80
cmpMethod · 0.80
pathMethod · 0.45
is_emptyMethod · 0.45
pushMethod · 0.45
lenMethod · 0.45
as_sliceMethod · 0.45
finishMethod · 0.45