extract_and_cache_demo/
extract_and_cache_demo.rs1use docker_image_pusher::{
7 cli::operation_mode::OperationMode, error::Result, image::image_manager::ImageManager,
8};
9use std::path::Path;
10
11#[tokio::main]
12async fn main() -> Result<()> {
13 println!("📦 Docker Image Pusher - Extract and Cache Demo");
14 println!("===================================================");
15
16 let tar_file = get_tar_file_path();
18 let cache_dir = ".cache_extract_demo";
19
20 let file_stem = Path::new(&tar_file)
22 .file_stem()
23 .and_then(|s| s.to_str())
24 .unwrap_or("extracted-image");
25 let repository = format!("local/{}", file_stem);
26 let reference = "latest";
27
28 println!("📥 Configuration:");
29 println!(" Tar File: {}", tar_file);
30 println!(" Repository: {}", repository);
31 println!(" Reference: {}", reference);
32 println!(" Cache Directory: {}", cache_dir);
33 println!();
34
35 if !Path::new(&tar_file).exists() {
37 eprintln!("❌ Tar file not found: {}", tar_file);
38 eprintln!("💡 Please ensure the dufs.tar file exists in the examples/ directory");
39 return Err(docker_image_pusher::error::RegistryError::Validation(
40 format!("Tar file does not exist: {}", tar_file),
41 ));
42 }
43
44 println!("🔧 Creating ImageManager...");
46 let mut image_manager = ImageManager::new(Some(cache_dir), true)?;
47 println!("✅ ImageManager created successfully");
48
49 let mode = OperationMode::ExtractAndCache {
51 tar_file: tar_file.clone(),
52 repository: repository.clone(),
53 reference: reference.to_string(),
54 };
55
56 println!("📋 Operation Mode: {}", mode.description());
57 println!();
58
59 println!("🔄 Starting extract and cache operation...");
61 match image_manager.execute_operation(&mode, None, None).await {
62 Ok(()) => {
63 println!("✅ Extract and cache operation completed successfully!");
64 println!();
65 println!("📂 Image extracted and cached to: {}", cache_dir);
66 println!("🔍 You can now inspect the cache contents:");
67 println!(
68 " - Manifests: {}/manifests/{}/{}",
69 cache_dir, repository, reference
70 );
71 println!(" - Blobs: {}/blobs/sha256/", cache_dir);
72 println!(" - Index: {}/index.json", cache_dir);
73 }
74 Err(e) => {
75 eprintln!("❌ Extract and cache operation failed: {}", e);
76 std::process::exit(1);
77 }
78 }
79
80 show_extraction_stats(&tar_file, cache_dir).await;
82
83 Ok(())
84}
85
86fn get_tar_file_path() -> String {
87 let args: Vec<String> = std::env::args().collect();
89 if args.len() > 1 {
90 return args[1].clone();
91 }
92
93 "examples/dufs.tar".to_string()
95}
96
97async fn show_extraction_stats(tar_file: &str, cache_dir: &str) {
98 println!();
99 println!("📊 Extraction Statistics:");
100
101 if let Ok(metadata) = std::fs::metadata(tar_file) {
103 println!(" 📁 Original tar size: {} bytes", metadata.len());
104 }
105
106 if let Ok(entries) = std::fs::read_dir(format!("{}/blobs/sha256", cache_dir)) {
108 let blob_count = entries.count();
109 println!(" 📦 Extracted blobs: {}", blob_count);
110 }
111
112 if std::path::Path::new(&format!("{}/index.json", cache_dir)).exists() {
114 println!(" 📋 Index file created successfully");
115 }
116
117 if let Ok(entries) = std::fs::read_dir(cache_dir) {
119 let mut total_size = 0u64;
120 for entry in entries.flatten() {
121 if let Ok(metadata) = entry.metadata() {
122 total_size += metadata.len();
123 }
124 }
125 println!(" 💾 Total cache size: {} bytes", total_size);
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[tokio::test]
134 async fn test_extract_and_cache_creation() {
135 let result = ImageManager::new(Some(".test_extract_cache"), false);
137 assert!(result.is_ok());
138
139 let _ = std::fs::remove_dir_all(".test_extract_cache");
141 }
142
143 #[test]
144 fn test_tar_file_path_parsing() {
145 let tar_file = "test-image.tar";
146 let file_stem = Path::new(tar_file)
147 .file_stem()
148 .and_then(|s| s.to_str())
149 .unwrap_or("extracted-image");
150 assert_eq!(file_stem, "test-image");
151 }
152
153 #[test]
154 fn test_operation_mode_description() {
155 let mode = OperationMode::ExtractAndCache {
156 tar_file: "test.tar".to_string(),
157 repository: "local/test".to_string(),
158 reference: "latest".to_string(),
159 };
160 assert_eq!(
161 mode.description(),
162 "Extract from tar file and cache locally"
163 );
164 }
165}