Skip to main content

sal_virt/buildah/
content.rs

1use crate::buildah::{execute_buildah_command, BuildahError};
2use sal_process::CommandResult;
3use std::fs::File;
4use std::io::{Read, Write};
5use tempfile::NamedTempFile;
6
7/// Functions for working with file content in buildah containers
8pub struct ContentOperations;
9
10impl ContentOperations {
11    /// Write content to a file in the container
12    ///
13    /// # Arguments
14    ///
15    /// * `container_id` - The container ID
16    /// * `content` - The content to write
17    /// * `dest_path` - Destination path in the container
18    ///
19    /// # Returns
20    ///
21    /// * `Result<CommandResult, BuildahError>` - Command result or error
22    pub fn write_content(
23        container_id: &str,
24        content: &str,
25        dest_path: &str,
26    ) -> Result<CommandResult, BuildahError> {
27        // Create a temporary file
28        let mut temp_file = NamedTempFile::new()
29            .map_err(|e| BuildahError::Other(format!("Failed to create temporary file: {}", e)))?;
30
31        // Write content to the temporary file
32        temp_file.write_all(content.as_bytes()).map_err(|e| {
33            BuildahError::Other(format!("Failed to write to temporary file: {}", e))
34        })?;
35
36        // Flush the file to ensure content is written
37        temp_file
38            .flush()
39            .map_err(|e| BuildahError::Other(format!("Failed to flush temporary file: {}", e)))?;
40
41        // Copy the temporary file to the container
42        let temp_path = temp_file.path().to_string_lossy().to_string();
43        // Use add instead of copy for better handling of paths
44        execute_buildah_command(&["add", container_id, &temp_path, dest_path])
45    }
46
47    /// Read content from a file in the container
48    ///
49    /// # Arguments
50    ///
51    /// * `container_id` - The container ID
52    /// * `source_path` - Source path in the container
53    ///
54    /// # Returns
55    ///
56    /// * `Result<String, BuildahError>` - File content or error
57    pub fn read_content(container_id: &str, source_path: &str) -> Result<String, BuildahError> {
58        // Create a temporary file
59        let temp_file = NamedTempFile::new()
60            .map_err(|e| BuildahError::Other(format!("Failed to create temporary file: {}", e)))?;
61
62        let temp_path = temp_file.path().to_string_lossy().to_string();
63
64        // Copy the file from the container to the temporary file
65        // Use mount to access the container's filesystem
66        let mount_result = execute_buildah_command(&["mount", container_id])?;
67        let mount_point = mount_result.stdout.trim();
68
69        // Construct the full path to the file in the container
70        let full_source_path = format!("{}{}", mount_point, source_path);
71
72        // Copy the file from the mounted container to the temporary file
73        execute_buildah_command(&["copy", container_id, &full_source_path, &temp_path])?;
74
75        // Unmount the container
76        execute_buildah_command(&["umount", container_id])?;
77
78        // Read the content from the temporary file
79        let mut file = File::open(temp_file.path())
80            .map_err(|e| BuildahError::Other(format!("Failed to open temporary file: {}", e)))?;
81
82        let mut content = String::new();
83        file.read_to_string(&mut content).map_err(|e| {
84            BuildahError::Other(format!("Failed to read from temporary file: {}", e))
85        })?;
86
87        Ok(content)
88    }
89}