pub struct OverlayFS { /* private fields */ }Expand description
Overlay filesystem manager
Implementations§
Source§impl OverlayFS
impl OverlayFS
Sourcepub fn new(config: OverlayConfig) -> Self
pub fn new(config: OverlayConfig) -> Self
Create new overlay filesystem
Examples found in repository?
examples/overlay_filesystem.rs (line 70)
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(&mut self) -> Result<()>
pub fn setup(&mut self) -> Result<()>
Setup overlay filesystem
Examples found in repository?
examples/overlay_filesystem.rs (line 71)
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 is_mounted(&self) -> bool
pub fn is_mounted(&self) -> bool
Check if filesystem is mounted
Examples found in repository?
examples/overlay_filesystem.rs (line 74)
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 merged_path(&self) -> &Path
pub fn merged_path(&self) -> &Path
Get merged (visible) directory
Examples found in repository?
examples/overlay_filesystem.rs (line 126)
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 upper_path(&self) -> &Path
pub fn upper_path(&self) -> &Path
Get upper (writable) directory
Examples found in repository?
examples/overlay_filesystem.rs (line 80)
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 lower_path(&self) -> &Path
pub fn lower_path(&self) -> &Path
Get lower (read-only) directory
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}Sourcepub fn cleanup(&mut self) -> Result<()>
pub fn cleanup(&mut self) -> Result<()>
Cleanup overlay filesystem
Examples found in repository?
examples/overlay_filesystem.rs (line 150)
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 get_changes_size(&self) -> Result<u64>
pub fn get_changes_size(&self) -> Result<u64>
Get total size of changes in upper layer
Examples found in repository?
examples/overlay_filesystem.rs (line 119)
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}Auto Trait Implementations§
impl Freeze for OverlayFS
impl RefUnwindSafe for OverlayFS
impl Send for OverlayFS
impl Sync for OverlayFS
impl Unpin for OverlayFS
impl UnwindSafe for OverlayFS
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