tsk/assets/
utils.rs

1//! Utilities for working with embedded assets
2//!
3//! This module provides helper functions for extracting embedded assets
4//! to the filesystem, particularly for Docker builds that require
5//! dockerfile directories to be available on disk.
6
7use super::AssetManager;
8use anyhow::{Context, Result};
9use std::fs;
10use std::path::PathBuf;
11
12/// Extract a dockerfile and its associated files to a temporary directory
13///
14/// This function extracts all files for a given dockerfile to a temporary directory
15/// and returns the path to the extracted directory. The caller is responsible for
16/// cleaning up the directory when done.
17///
18/// # Arguments
19///
20/// * `asset_manager` - The asset manager to use for retrieving dockerfile files
21/// * `dockerfile_name` - The name of the dockerfile (e.g., "tsk-base", "tsk-proxy")
22///
23/// # Returns
24///
25/// The path to the temporary directory containing the extracted dockerfile files
26pub fn extract_dockerfile_to_temp(
27    asset_manager: &dyn AssetManager,
28    dockerfile_name: &str,
29) -> Result<PathBuf> {
30    // Create a temporary directory
31    let temp_dir = tempfile::TempDir::new().context("Failed to create temporary directory")?;
32    let temp_path = temp_dir.path().to_owned();
33
34    // Extract the main Dockerfile
35    let dockerfile_content = asset_manager.get_dockerfile(dockerfile_name)?;
36    let dockerfile_path = temp_path.join("Dockerfile");
37    fs::write(&dockerfile_path, dockerfile_content).context("Failed to write Dockerfile")?;
38
39    // Try to extract additional files (like squid.conf for tsk-proxy)
40    // We'll try common files and ignore errors if they don't exist
41    let additional_files = ["squid.conf", "entrypoint.sh", "requirements.txt"];
42
43    for file_name in &additional_files {
44        match asset_manager.get_dockerfile_file(dockerfile_name, file_name) {
45            Ok(content) => {
46                let file_path = temp_path.join(file_name);
47                fs::write(&file_path, content)
48                    .with_context(|| format!("Failed to write {file_name}"))?;
49            }
50            Err(_) => {
51                // File doesn't exist, which is fine
52                continue;
53            }
54        }
55    }
56
57    // Keep the directory from being deleted
58    std::mem::forget(temp_dir);
59
60    Ok(temp_path)
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66    use crate::assets::embedded::EmbeddedAssetManager;
67
68    #[test]
69    fn test_asset_extraction() {
70        let manager = EmbeddedAssetManager::new();
71
72        // Test extracting tsk-base dockerfile
73        let result = extract_dockerfile_to_temp(&manager, "tsk-base");
74        assert!(result.is_ok());
75
76        let temp_dir = result.unwrap();
77        assert!(temp_dir.exists());
78        assert!(temp_dir.join("Dockerfile").exists());
79
80        // Clean up
81        let _ = std::fs::remove_dir_all(&temp_dir);
82    }
83
84    #[test]
85    fn test_asset_extraction_with_additional_files() {
86        let manager = EmbeddedAssetManager::new();
87
88        // Test extracting tsk-proxy dockerfile (which has squid.conf)
89        let result = extract_dockerfile_to_temp(&manager, "tsk-proxy");
90        assert!(result.is_ok());
91
92        let temp_dir = result.unwrap();
93        assert!(temp_dir.exists());
94        assert!(temp_dir.join("Dockerfile").exists());
95        assert!(temp_dir.join("squid.conf").exists());
96
97        // Clean up
98        let _ = std::fs::remove_dir_all(&temp_dir);
99    }
100}