Skip to main content

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§size: u64§file_count: usize§writable: bool

Implementations§

Source§

impl LayerInfo

Source

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

Examples found in repository?
examples/overlay_filesystem.rs (line 103)
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 = sandbox_rs::LayerInfo::from_path("lower", overlay.lower_path(), false)?;
104    println!("  Lower Layer (Read-only):");
105    println!("    Files: {}", lower_info.file_count);
106    println!("    Total size: {} bytes", lower_info.size);
107    println!("    Writable: {}\n", lower_info.writable);
108
109    let upper_info = sandbox_rs::LayerInfo::from_path("upper", overlay.upper_path(), true)?;
110    println!("  Upper Layer (Read-write changes):");
111    println!("    Files: {}", upper_info.file_count);
112    println!("    Total size: {} bytes", upper_info.size);
113    println!("    Writable: {}\n", upper_info.writable);
114
115    // Get total changes size
116    println!("[6] Sandbox Modifications Summary\n");
117    let changes_size = overlay.get_changes_size()?;
118    println!("  Total changes in upper layer: {} bytes", changes_size);
119    println!("  Files modified/created: {}\n", upper_info.file_count);
120
121    // Show how to use the merged view
122    println!("[7] Accessing Merged View\n");
123    println!("  In a real mount, you would access both layers transparently:");
124    println!("    - {} (combined view)", overlay.merged_path().display());
125    println!("    - Files from lower layer are visible");
126    println!("    - Files from upper layer override lower layer");
127    println!("    - New files only appear in upper layer\n");
128
129    // Demonstrate cleanup and recovery
130    println!("[8] Cleanup and Recovery Options\n");
131    println!("  Option A: Keep upper layer for audit trail");
132    println!(
133        "    - Preserve {} for reviewing changes",
134        upper_path.display()
135    );
136    println!("    - Original base layer remains untouched\n");
137
138    println!("  Option B: Discard changes (reset to base)");
139    println!("    - Delete upper layer: {}", upper_path.display());
140    println!("    - Next execution gets fresh base\n");
141
142    println!("  Option C: Commit changes to new base");
143    println!("    - Copy merged view to new base layer");
144    println!("    - Create fresh upper layer for next sandbox\n");
145
146    // Cleanup
147    println!("[9] Cleaning up\n");
148    overlay.cleanup()?;
149    println!("  Overlay filesystem cleaned up\n");
150
151    // Practical use case demonstration
152    println!("=== Practical Use Case ===\n");
153    println!("Scenario: Run Python data processing pipeline with multiple stages\n");
154
155    println!("Stage 1: Initial execution");
156    println!("  Base layer:  /data/pipeline-v1.0 (read-only)");
157    println!("  Upper layer: /sandbox-run-1/changes");
158    println!("  Output:      preprocessing complete, 1.2GB changes\n");
159
160    println!("Stage 2: Different parameters");
161    println!("  Base layer:  /data/pipeline-v1.0 (same - shared!)");
162    println!("  Upper layer: /sandbox-run-2/changes (fresh)");
163    println!("  Output:      processing complete, 2.1GB changes\n");
164
165    println!("Benefits:");
166    println!("  - Disk efficient: Base shared across runs");
167    println!("  - Isolation: Each run has independent changes");
168    println!("  - Auditability: See exactly what each run produced");
169    println!("  - Recoverability: Can revert to base state\n");
170
171    // Volume mount for persistent storage
172    println!("=== Combined with Volume Mounts ===\n");
173    println!("For persistent storage across sandbox runs:");
174    println!("  - Overlay FS: For temporary isolation per execution");
175    println!("  - Volume mounts: For data that needs to survive");
176    println!("  - Example setup:");
177    println!("    - Mount /home/user/data as /data (read-write)");
178    println!("    - Overlay base /usr/lib as /lib (read-only with changes)");
179    println!("    - Any writes to /data persist beyond sandbox");
180    println!("    - Any writes to /lib are isolated per run\n");
181
182    println!("=== Example completed successfully ===");
183    Ok(())
184}

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<(), Error>

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.