LayerInfo

Struct LayerInfo 

Source
pub struct LayerInfo {
    pub name: String,
    pub size: u64,
    pub file_count: usize,
    pub writable: bool,
}
Expand description

File layer information

Fields§

§name: String

Layer name

§size: u64

Layer size in bytes

§file_count: usize

Number of files

§writable: bool

Whether layer is writable

Implementations§

Source§

impl LayerInfo

Source

pub fn from_path(name: &str, path: &Path, writable: bool) -> Result<Self>

Get layer info from path

Examples found in repository?
examples/overlay_filesystem.rs (line 104)
31fn main() -> Result<(), Box<dyn std::error::Error>> {
32    println!("=== Sandbox-rs: Overlay Filesystem Example ===\n");
33
34    // Create temporary directories for demonstration
35    let temp_base = TempDir::new()?;
36    let base_dir = temp_base.path().join("base");
37    let upper_dir = temp_base.path().join("upper");
38
39    println!("[1] Setting up overlay filesystem layers\n");
40
41    // Create base directory with initial content
42    fs::create_dir_all(&base_dir)?;
43    fs::write(
44        base_dir.join("original.txt"),
45        "This is the original immutable file\n",
46    )?;
47    fs::write(base_dir.join("readme.txt"), "Base layer - read-only\n")?;
48
49    println!("  Created base layer at: {}", base_dir.display());
50    println!("    - original.txt");
51    println!("    - readme.txt\n");
52
53    // Create overlay configuration
54    println!("[2] Creating overlay configuration\n");
55    let overlay_config = OverlayConfig::new(&base_dir, &upper_dir);
56
57    println!(
58        "  Lower layer (read-only): {}",
59        overlay_config.lower.display()
60    );
61    println!(
62        "  Upper layer (read-write): {}",
63        overlay_config.upper.display()
64    );
65    println!("  Work directory: {}", overlay_config.work.display());
66    println!("  Merged view: {}\n", overlay_config.merged.display());
67
68    // Initialize overlay filesystem
69    println!("[3] Initializing overlay filesystem\n");
70    let mut overlay = OverlayFS::new(overlay_config);
71    overlay.setup()?;
72
73    println!("  Overlay filesystem initialized");
74    println!("  Mounted: {}\n", overlay.is_mounted());
75
76    // Simulate operations in the sandbox
77    println!("[4] Simulating sandbox operations\n");
78
79    // Create new file in upper layer (simulating sandbox write)
80    let upper_path = overlay.upper_path();
81    fs::create_dir_all(upper_path)?;
82
83    let new_file_path = upper_path.join("sandbox-output.txt");
84    fs::write(
85        &new_file_path,
86        "This file was created in the sandbox\nModified during execution\n",
87    )?;
88    println!("  Created new file: {}", new_file_path.display());
89
90    let modified_file_path = upper_path.join("modified.txt");
91    fs::write(
92        &modified_file_path,
93        "This original file was modified in the sandbox\n",
94    )?;
95    println!(
96        "  Created modified file: {}\n",
97        modified_file_path.display()
98    );
99
100    // Query layer information
101    println!("[5] Layer Information\n");
102
103    let lower_info =
104        sandbox_rs::storage::LayerInfo::from_path("lower", overlay.lower_path(), false)?;
105    println!("  Lower Layer (Read-only):");
106    println!("    Files: {}", lower_info.file_count);
107    println!("    Total size: {} bytes", lower_info.size);
108    println!("    Writable: {}\n", lower_info.writable);
109
110    let upper_info =
111        sandbox_rs::storage::LayerInfo::from_path("upper", overlay.upper_path(), true)?;
112    println!("  Upper Layer (Read-write changes):");
113    println!("    Files: {}", upper_info.file_count);
114    println!("    Total size: {} bytes", upper_info.size);
115    println!("    Writable: {}\n", upper_info.writable);
116
117    // Get total changes size
118    println!("[6] Sandbox Modifications Summary\n");
119    let changes_size = overlay.get_changes_size()?;
120    println!("  Total changes in upper layer: {} bytes", changes_size);
121    println!("  Files modified/created: {}\n", upper_info.file_count);
122
123    // Show how to use the merged view
124    println!("[7] Accessing Merged View\n");
125    println!("  In a real mount, you would access both layers transparently:");
126    println!("    - {} (combined view)", overlay.merged_path().display());
127    println!("    - Files from lower layer are visible");
128    println!("    - Files from upper layer override lower layer");
129    println!("    - New files only appear in upper layer\n");
130
131    // Demonstrate cleanup and recovery
132    println!("[8] Cleanup and Recovery Options\n");
133    println!("  Option A: Keep upper layer for audit trail");
134    println!(
135        "    - Preserve {} for reviewing changes",
136        upper_path.display()
137    );
138    println!("    - Original base layer remains untouched\n");
139
140    println!("  Option B: Discard changes (reset to base)");
141    println!("    - Delete upper layer: {}", upper_path.display());
142    println!("    - Next execution gets fresh base\n");
143
144    println!("  Option C: Commit changes to new base");
145    println!("    - Copy merged view to new base layer");
146    println!("    - Create fresh upper layer for next sandbox\n");
147
148    // Cleanup
149    println!("[9] Cleaning up\n");
150    overlay.cleanup()?;
151    println!("  Overlay filesystem cleaned up\n");
152
153    // Practical use case demonstration
154    println!("=== Practical Use Case ===\n");
155    println!("Scenario: Run Python data processing pipeline with multiple stages\n");
156
157    println!("Stage 1: Initial execution");
158    println!("  Base layer:  /data/pipeline-v1.0 (read-only)");
159    println!("  Upper layer: /sandbox-run-1/changes");
160    println!("  Output:      preprocessing complete, 1.2GB changes\n");
161
162    println!("Stage 2: Different parameters");
163    println!("  Base layer:  /data/pipeline-v1.0 (same - shared!)");
164    println!("  Upper layer: /sandbox-run-2/changes (fresh)");
165    println!("  Output:      processing complete, 2.1GB changes\n");
166
167    println!("Benefits:");
168    println!("  - Disk efficient: Base shared across runs");
169    println!("  - Isolation: Each run has independent changes");
170    println!("  - Auditability: See exactly what each run produced");
171    println!("  - Recoverability: Can revert to base state\n");
172
173    // Volume mount for persistent storage
174    println!("=== Combined with Volume Mounts ===\n");
175    println!("For persistent storage across sandbox runs:");
176    println!("  - Overlay FS: For temporary isolation per execution");
177    println!("  - Volume mounts: For data that needs to survive");
178    println!("  - Example setup:");
179    println!("    - Mount /home/user/data as /data (read-write)");
180    println!("    - Overlay base /usr/lib as /lib (read-only with changes)");
181    println!("    - Any writes to /data persist beyond sandbox");
182    println!("    - Any writes to /lib are isolated per run\n");
183
184    println!("=== Example completed successfully ===");
185    Ok(())
186}

Trait Implementations§

Source§

impl Clone for LayerInfo

Source§

fn clone(&self) -> LayerInfo

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for LayerInfo

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.