Runs a software stack from a stack bundle. # Arguments `bundle` - A string slice that holds the path to the stack bundle file. `callback` - A callback function that receives output lines.
(bundle: &str, callback: impl Fn(String))
| 220 | /// * `bundle` - A string slice that holds the path to the stack bundle file. |
| 221 | /// * `callback` - A callback function that receives output lines. |
| 222 | pub async fn run_with_callback(bundle: &str, callback: impl Fn(String)) { |
| 223 | callback("Initializing stack…".to_string()); |
| 224 | |
| 225 | let bundle_path = if bundle.starts_with("http://") |
| 226 | || bundle.starts_with("https://") |
| 227 | || bundle.starts_with("file://") |
| 228 | { |
| 229 | debug!("Downloading bundle: {}", bundle); |
| 230 | callback("Downloading…".to_string()); |
| 231 | |
| 232 | download_file(bundle) |
| 233 | .await |
| 234 | .expect("Failed to download bundle file") |
| 235 | } else { |
| 236 | PathBuf::from(bundle) |
| 237 | }; |
| 238 | |
| 239 | debug!("bundle_path: {:?}", bundle_path); |
| 240 | |
| 241 | // Check if file exists before proceeding |
| 242 | if !bundle_path.exists() { |
| 243 | error!("Bundle file not found: {:?}", bundle_path); |
| 244 | return; |
| 245 | } |
| 246 | |
| 247 | let file = match File::open(&bundle_path) { |
| 248 | Ok(f) => f, |
| 249 | Err(e) => { |
| 250 | error!("Failed to open bundle file: {}", e); |
| 251 | return; |
| 252 | } |
| 253 | }; |
| 254 | |
| 255 | debug!("Reading stack file: {:?}", file); |
| 256 | let gz = MultiGzDecoder::new(file); |
| 257 | let temp_dir = tempdir().expect("Failed to create temp dir").into_path(); |
| 258 | |
| 259 | // Use a subdirectory to keep things cleaner |
| 260 | let extract_dir = temp_dir.join("bundle_extract"); |
| 261 | debug!("Extracting to: {:?}", extract_dir); |
| 262 | callback("Extracting…".to_string()); |
| 263 | if let Err(e) = fs::create_dir_all(&extract_dir) { |
| 264 | error!("Failed to create extract directory: {:?}", e); |
| 265 | return; |
| 266 | } |
| 267 | |
| 268 | let mut archive = Archive::new(gz); |
| 269 | if let Err(e) = archive.unpack(&extract_dir) { |
| 270 | error!("Failed to unpack bundle: {:?}", e); |
| 271 | return; |
| 272 | } |
| 273 | debug!("Extraction complete: {:?}", extract_dir); |
| 274 | callback("Extraction complete".to_string()); |
| 275 | |
| 276 | // Now we can access the metadata file |
| 277 | let config_path = extract_dir.join("stack.yaml"); |
| 278 | debug!("Loading stack metadata from: {:?}", config_path); |
| 279 | let config = load_stack_manifest(config_path.as_path()); |
no test coverage detected