pub struct OverlayConfig {
pub lower: PathBuf,
pub upper: PathBuf,
pub work: PathBuf,
pub merged: PathBuf,
}Expand description
Overlay filesystem configuration
Fields§
§lower: PathBufLower layer (read-only base)
upper: PathBufUpper layer (read-write changes)
work: PathBufWork directory (required by overlayfs)
merged: PathBufMerged mount point
Implementations§
Source§impl OverlayConfig
impl OverlayConfig
Sourcepub fn new(lower: impl AsRef<Path>, upper: impl AsRef<Path>) -> Self
pub fn new(lower: impl AsRef<Path>, upper: impl AsRef<Path>) -> Self
Create new overlay configuration
Examples found in repository?
examples/overlay_filesystem.rs (line 55)
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}Sourcepub fn setup_directories(&self) -> Result<()>
pub fn setup_directories(&self) -> Result<()>
Create necessary directories
Sourcepub fn get_mount_options(&self) -> String
pub fn get_mount_options(&self) -> String
Get overlay mount string for mount command
Trait Implementations§
Source§impl Clone for OverlayConfig
impl Clone for OverlayConfig
Source§fn clone(&self) -> OverlayConfig
fn clone(&self) -> OverlayConfig
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreAuto Trait Implementations§
impl Freeze for OverlayConfig
impl RefUnwindSafe for OverlayConfig
impl Send for OverlayConfig
impl Sync for OverlayConfig
impl Unpin for OverlayConfig
impl UnwindSafe for OverlayConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more