pub struct RegistryClient { /* private fields */ }Implementations§
Source§impl RegistryClient
impl RegistryClient
Sourcepub async fn test_connectivity(&self) -> Result<()>
pub async fn test_connectivity(&self) -> Result<()>
Examples found in repository?
examples/optimized_upload_demo.rs (line 43)
10async fn main() -> Result<()> {
11 println!("Docker Image Pusher - Optimized Upload Demo");
12
13 // Create image manager with optimizations enabled (default)
14 let mut manager = ImageManager::new(None, true)?;
15
16 // Configure pipeline for demonstration
17 let config = PipelineConfig {
18 max_concurrent: 8,
19 buffer_size: 1024,
20 small_blob_threshold: 10 * 1024 * 1024, // 10MB
21 medium_blob_threshold: 100 * 1024 * 1024, // 100MB
22 large_blob_threshold: 500 * 1024 * 1024, // 500MB
23 timeout_seconds: 7200,
24 retry_attempts: 3,
25 memory_limit_mb: 512,
26 enable_compression: true,
27 enable_streaming: true,
28 };
29 manager.configure_pipeline(config);
30
31 // Verify configuration
32 let (optimized, pipeline_config) = manager.get_config();
33 println!("Optimized mode: {}", optimized);
34 println!("Pipeline config: {:?}", pipeline_config);
35
36 // Example registry client (would need real registry URL)
37 let client = RegistryClientBuilder::new("https://registry.example.com".to_string())
38 .with_verbose(true)
39 .build()?;
40
41 // Test connectivity (this would fail with example URL)
42 println!("Testing registry connectivity...");
43 match client.test_connectivity().await {
44 Ok(_) => println!("✓ Registry connectivity successful"),
45 Err(e) => println!(
46 "✗ Registry connectivity failed: {} (expected with example URL)",
47 e
48 ),
49 }
50
51 // Example operation mode for pushing from tar
52 let mode = OperationMode::PushFromTar {
53 tar_file: "example-image.tar".to_string(),
54 repository: "myapp".to_string(),
55 reference: "latest".to_string(),
56 };
57
58 println!("Operation mode: {}", mode.description());
59
60 // In a real scenario, you would call:
61 // manager.execute_operation(&mode, Some(&client), None).await?;
62
63 println!("Demo completed successfully!");
64 println!("\nKey benefits of optimized mode:");
65 println!("• Priority-based upload scheduling (small blobs first)");
66 println!("• Streaming TAR processing with parallel uploads");
67 println!("• Memory-efficient processing of large files");
68 println!("• Configurable pipeline parameters");
69
70 Ok(())
71}More examples
examples/check_aliyun_namespace.rs (line 38)
8async fn main() -> Result<()> {
9 println!("🔍 Aliyun Registry Namespace Checker");
10 println!("=====================================");
11
12 // 阿里云配置
13 let aliyun_registry = "registry.cn-beijing.aliyuncs.com";
14 let aliyun_username = "canny_best@163.com";
15 let aliyun_password = "ra201222";
16
17 // 要检查的namespace/repository
18 let namespace = "canny_best";
19 let repository = "canny_best/test-repo";
20
21 println!("📊 Configuration:");
22 println!(" Registry: {}", aliyun_registry);
23 println!(" Username: {}", aliyun_username);
24 println!(" Namespace: {}", namespace);
25 println!(" Repository: {}", repository);
26 println!();
27
28 // 构建客户端
29 println!("🌐 Building Registry Client...");
30 let client = RegistryClientBuilder::new(format!("https://{}", aliyun_registry))
31 .with_timeout(3600)
32 .with_skip_tls(false)
33 .with_verbose(true)
34 .build()?;
35
36 // 测试连接性
37 println!("🔗 Testing registry connectivity...");
38 match client.test_connectivity().await {
39 Ok(_) => println!("✅ Registry is accessible"),
40 Err(e) => {
41 println!("⚠️ Registry connectivity test failed: {}", e);
42 println!(" This may be normal for some registries");
43 }
44 }
45
46 // 认证
47 println!("🔐 Authenticating...");
48 let auth_config = AuthConfig::new(aliyun_username.to_string(), aliyun_password.to_string());
49
50 match client.authenticate(&auth_config).await {
51 Ok(Some(token)) => {
52 println!("✅ Authentication successful (token received)");
53
54 // 尝试访问repository
55 println!("📦 Checking repository access...");
56 match client.list_tags(repository, &Some(token.clone())).await {
57 Ok(tags) => {
58 println!("✅ Repository {} is accessible", repository);
59 println!("🏷️ Available tags: {:?}", tags);
60 }
61 Err(e) => {
62 println!("❌ Repository {} is not accessible: {}", repository, e);
63
64 println!("\n💡 To fix this issue:");
65 println!(" 1. Login to Aliyun Console: https://cr.console.aliyun.com/");
66 println!(" 2. Create namespace '{}' if it doesn't exist", namespace);
67 println!(
68 " 3. Create repository '{}' in the namespace",
69 repository.split('/').nth(1).unwrap_or("unknown")
70 );
71 println!(" 4. Ensure your account has push/pull permissions");
72
73 return Ok(());
74 }
75 }
76
77 // 尝试检查认证的repository访问
78 println!("🔐 Testing repository-specific authentication...");
79 match client
80 .authenticate_for_repository(&auth_config, repository)
81 .await
82 {
83 Ok(Some(repo_token)) => {
84 println!("✅ Repository-specific authentication successful");
85
86 // 检查一个不存在的镜像
87 println!("🔍 Testing image existence check...");
88 match client
89 .check_image_exists(repository, "non-existent-tag", &Some(repo_token))
90 .await
91 {
92 Ok(exists) => {
93 if exists {
94 println!("⚠️ Image unexpectedly exists");
95 } else {
96 println!(
97 "✅ Image existence check works (image doesn't exist as expected)"
98 );
99 }
100 }
101 Err(e) => {
102 println!("⚠️ Image existence check failed: {}", e);
103 }
104 }
105 }
106 Ok(None) => {
107 println!("✅ Repository-specific authentication successful (no token)");
108 }
109 Err(e) => {
110 println!("❌ Repository-specific authentication failed: {}", e);
111 }
112 }
113 }
114 Ok(None) => {
115 println!("✅ Authentication successful (no token required)");
116 }
117 Err(e) => {
118 println!("❌ Authentication failed: {}", e);
119 println!("\n💡 Please check:");
120 println!(" - Username: {}", aliyun_username);
121 println!(" - Password is correct");
122 println!(" - Account has access to Aliyun Container Registry");
123 return Ok(());
124 }
125 }
126
127 println!("\n🎉 All checks completed!");
128 println!(
129 " Repository {} appears to be ready for push operations",
130 repository
131 );
132
133 Ok(())
134}pub async fn check_blob_exists( &self, digest: &str, repository: &str, ) -> Result<bool>
pub async fn check_blob_exists_with_token( &self, digest: &str, repository: &str, token: &Option<String>, ) -> Result<bool>
Sourcepub async fn authenticate(
&self,
auth_config: &AuthConfig,
) -> Result<Option<String>>
pub async fn authenticate( &self, auth_config: &AuthConfig, ) -> Result<Option<String>>
Examples found in repository?
examples/check_aliyun_namespace.rs (line 50)
8async fn main() -> Result<()> {
9 println!("🔍 Aliyun Registry Namespace Checker");
10 println!("=====================================");
11
12 // 阿里云配置
13 let aliyun_registry = "registry.cn-beijing.aliyuncs.com";
14 let aliyun_username = "canny_best@163.com";
15 let aliyun_password = "ra201222";
16
17 // 要检查的namespace/repository
18 let namespace = "canny_best";
19 let repository = "canny_best/test-repo";
20
21 println!("📊 Configuration:");
22 println!(" Registry: {}", aliyun_registry);
23 println!(" Username: {}", aliyun_username);
24 println!(" Namespace: {}", namespace);
25 println!(" Repository: {}", repository);
26 println!();
27
28 // 构建客户端
29 println!("🌐 Building Registry Client...");
30 let client = RegistryClientBuilder::new(format!("https://{}", aliyun_registry))
31 .with_timeout(3600)
32 .with_skip_tls(false)
33 .with_verbose(true)
34 .build()?;
35
36 // 测试连接性
37 println!("🔗 Testing registry connectivity...");
38 match client.test_connectivity().await {
39 Ok(_) => println!("✅ Registry is accessible"),
40 Err(e) => {
41 println!("⚠️ Registry connectivity test failed: {}", e);
42 println!(" This may be normal for some registries");
43 }
44 }
45
46 // 认证
47 println!("🔐 Authenticating...");
48 let auth_config = AuthConfig::new(aliyun_username.to_string(), aliyun_password.to_string());
49
50 match client.authenticate(&auth_config).await {
51 Ok(Some(token)) => {
52 println!("✅ Authentication successful (token received)");
53
54 // 尝试访问repository
55 println!("📦 Checking repository access...");
56 match client.list_tags(repository, &Some(token.clone())).await {
57 Ok(tags) => {
58 println!("✅ Repository {} is accessible", repository);
59 println!("🏷️ Available tags: {:?}", tags);
60 }
61 Err(e) => {
62 println!("❌ Repository {} is not accessible: {}", repository, e);
63
64 println!("\n💡 To fix this issue:");
65 println!(" 1. Login to Aliyun Console: https://cr.console.aliyun.com/");
66 println!(" 2. Create namespace '{}' if it doesn't exist", namespace);
67 println!(
68 " 3. Create repository '{}' in the namespace",
69 repository.split('/').nth(1).unwrap_or("unknown")
70 );
71 println!(" 4. Ensure your account has push/pull permissions");
72
73 return Ok(());
74 }
75 }
76
77 // 尝试检查认证的repository访问
78 println!("🔐 Testing repository-specific authentication...");
79 match client
80 .authenticate_for_repository(&auth_config, repository)
81 .await
82 {
83 Ok(Some(repo_token)) => {
84 println!("✅ Repository-specific authentication successful");
85
86 // 检查一个不存在的镜像
87 println!("🔍 Testing image existence check...");
88 match client
89 .check_image_exists(repository, "non-existent-tag", &Some(repo_token))
90 .await
91 {
92 Ok(exists) => {
93 if exists {
94 println!("⚠️ Image unexpectedly exists");
95 } else {
96 println!(
97 "✅ Image existence check works (image doesn't exist as expected)"
98 );
99 }
100 }
101 Err(e) => {
102 println!("⚠️ Image existence check failed: {}", e);
103 }
104 }
105 }
106 Ok(None) => {
107 println!("✅ Repository-specific authentication successful (no token)");
108 }
109 Err(e) => {
110 println!("❌ Repository-specific authentication failed: {}", e);
111 }
112 }
113 }
114 Ok(None) => {
115 println!("✅ Authentication successful (no token required)");
116 }
117 Err(e) => {
118 println!("❌ Authentication failed: {}", e);
119 println!("\n💡 Please check:");
120 println!(" - Username: {}", aliyun_username);
121 println!(" - Password is correct");
122 println!(" - Account has access to Aliyun Container Registry");
123 return Ok(());
124 }
125 }
126
127 println!("\n🎉 All checks completed!");
128 println!(
129 " Repository {} appears to be ready for push operations",
130 repository
131 );
132
133 Ok(())
134}Sourcepub async fn authenticate_for_repository(
&self,
auth_config: &AuthConfig,
repository: &str,
) -> Result<Option<String>>
pub async fn authenticate_for_repository( &self, auth_config: &AuthConfig, repository: &str, ) -> Result<Option<String>>
Examples found in repository?
examples/pull_and_cache_demo.rs (line 52)
13async fn main() -> Result<()> {
14 println!("🚀 Docker Image Pusher - Pull and Cache Demo");
15 println!("==================================================");
16
17 // 配置参数 - 支持环境变量
18 let registry = env::var("DOCKER_REGISTRY")
19 .unwrap_or_else(|_| "https://registry.cn-beijing.aliyuncs.com".to_string());
20 let repository = env::var("DOCKER_REPOSITORY").unwrap_or_else(|_| "yoce/cblt".to_string());
21 let reference = env::var("DOCKER_REFERENCE").unwrap_or_else(|_| "yoce".to_string());
22 let cache_dir = ".cache_demo";
23
24 println!("📥 Configuration:");
25 println!(" Registry: {}", registry);
26 println!(" Repository: {}", repository);
27 println!(" Reference: {}", reference);
28 println!(" Cache Directory: {}", cache_dir);
29 println!();
30
31 // 1. 创建 ImageManager
32 println!("🔧 Creating ImageManager...");
33 let mut image_manager = ImageManager::new(Some(cache_dir), true)?;
34 println!("✅ ImageManager created successfully");
35
36 // 2. 构建 Registry Client
37 println!("🌐 Building Registry Client...");
38 let client = RegistryClientBuilder::new(registry.to_string())
39 .with_timeout(3600)
40 .with_verbose(true)
41 .build()?;
42 println!("✅ Registry Client built successfully");
43
44 // 3. 获取认证(总是尝试,支持匿名token)
45 println!("🔐 Attempting authentication...");
46 let auth_token = if let (Ok(username), Ok(password)) =
47 (env::var("DOCKER_USERNAME"), env::var("DOCKER_PASSWORD"))
48 {
49 println!(" Using provided credentials for user: {}", username);
50 let auth_config = AuthConfig::new(username, password);
51 client
52 .authenticate_for_repository(&auth_config, &repository)
53 .await?
54 } else {
55 println!(" No credentials provided, trying anonymous authentication...");
56 // 使用直接认证方法尝试获取匿名token
57 let auth = docker_image_pusher::registry::auth::Auth::new();
58 let output = docker_image_pusher::logging::Logger::new(true);
59 auth.authenticate_with_registry(®istry, &repository, None, None, &output)
60 .await?
61 };
62
63 if auth_token.is_some() {
64 println!("✅ Authentication successful");
65 } else {
66 println!("ℹ️ No authentication required");
67 }
68
69 // 4. 定义操作模式
70 let mode = OperationMode::PullAndCache {
71 repository: repository.to_string(),
72 reference: reference.to_string(),
73 };
74
75 println!("📋 Operation Mode: {}", mode.description());
76 println!();
77
78 // 5. 执行拉取和缓存操作
79 println!("🔄 Starting pull and cache operation...");
80 match image_manager
81 .execute_operation(&mode, Some(&client), auth_token.as_deref())
82 .await
83 {
84 Ok(()) => {
85 println!("✅ Pull and cache operation completed successfully!");
86 println!();
87 println!("📂 Image cached to: {}", cache_dir);
88 println!("🔍 You can now inspect the cache contents:");
89 println!(
90 " - Manifests: {}/manifests/{}/{}",
91 cache_dir, repository, reference
92 );
93 println!(" - Blobs: {}/blobs/sha256/", cache_dir);
94 println!(" - Index: {}/index.json", cache_dir);
95 }
96 Err(e) => {
97 eprintln!("❌ Pull and cache operation failed: {}", e);
98 std::process::exit(1);
99 }
100 }
101
102 // 6. 显示缓存统计
103 show_cache_stats(cache_dir).await;
104
105 Ok(())
106}More examples
examples/push_to_aliyun_demo.rs (line 74)
11async fn main() -> Result<()> {
12 println!("🚀 Docker Image Pusher - Push to Aliyun Registry Demo");
13 println!("=======================================================");
14
15 // 阿里云配置
16 let aliyun_registry = "registry.cn-beijing.aliyuncs.com";
17 let aliyun_username = "canny_best@163.com";
18 let aliyun_password = "ra201222";
19
20 // 源镜像(从缓存)
21 let source_repository = "yoce/cblt";
22 let source_reference = "yoce";
23
24 // 目标镜像(推送到阿里云)- 推送回同一个仓库,不同tag
25 let target_repository = "yoce/cblt";
26 let target_reference = "push-test";
27 let cache_dir = ".cache_demo";
28
29 println!("📥 Configuration:");
30 println!(
31 " Source (Cache): {}/{}",
32 source_repository, source_reference
33 );
34 println!(" Target Registry: {}", aliyun_registry);
35 println!(" Target Repository: {}", target_repository);
36 println!(" Target Reference: {}", target_reference);
37 println!(" Cache Directory: {}", cache_dir);
38 println!(" Username: {}", aliyun_username);
39 println!();
40
41 // 1. 检查缓存是否存在
42 check_cache_exists(cache_dir, source_repository, source_reference).await?;
43
44 // 2. 创建 ImageManager
45 println!("🔧 Creating ImageManager...");
46 let mut image_manager = ImageManager::new(Some(cache_dir), true)?;
47 println!("✅ ImageManager created successfully");
48
49 // 3. 复制缓存中的镜像到目标仓库名称
50 println!("📋 Copying cached image to target repository name...");
51 copy_image_in_cache(
52 cache_dir,
53 source_repository,
54 source_reference,
55 target_repository,
56 target_reference,
57 )
58 .await?;
59 println!("✅ Image copied in cache");
60
61 // 4. 构建 Registry Client for 阿里云
62 println!("🌐 Building Registry Client for Aliyun...");
63 let client = RegistryClientBuilder::new(format!("https://{}", aliyun_registry))
64 .with_timeout(3600)
65 .with_skip_tls(false)
66 .with_verbose(true)
67 .build()?;
68 println!("✅ Registry Client built successfully");
69
70 // 4. 认证到阿里云
71 println!("🔐 Authenticating with Aliyun registry...");
72 let auth_config = AuthConfig::new(aliyun_username.to_string(), aliyun_password.to_string());
73 let auth_token = client
74 .authenticate_for_repository(&auth_config, target_repository)
75 .await?;
76 println!("✅ Authentication successful");
77
78 // 5. 定义操作模式 - 推送缓存中的镜像到阿里云
79 let mode = OperationMode::PushFromCacheUsingManifest {
80 repository: target_repository.to_string(),
81 reference: target_reference.to_string(),
82 };
83
84 println!("📋 Operation Mode: {}", mode.description());
85 println!();
86
87 // 6. 执行推送操作
88 println!("🔄 Starting push to Aliyun operation...");
89 println!(
90 "🎯 Target: {}/{}/{}",
91 aliyun_registry, target_repository, target_reference
92 );
93
94 match image_manager
95 .execute_operation(&mode, Some(&client), auth_token.as_deref())
96 .await
97 {
98 Ok(()) => {
99 println!("✅ Push to Aliyun operation completed successfully!");
100 println!(
101 "🎯 Image pushed to: {}/{}/{}",
102 aliyun_registry, target_repository, target_reference
103 );
104 println!("🔍 You can verify the upload in Aliyun Console:");
105 println!(" https://cr.console.aliyun.com");
106
107 // 验证推送结果
108 verify_push_result(&client, target_repository, target_reference, &auth_token).await;
109 }
110 Err(e) => {
111 eprintln!("❌ Push to Aliyun operation failed: {}", e);
112 eprintln!("💡 Possible solutions:");
113 eprintln!(" - Check Aliyun credentials and permissions");
114 eprintln!(" - Verify repository name format (namespace/repo)");
115 eprintln!(" - Check network connectivity to Aliyun registry");
116 eprintln!(" - Ensure the repository exists in Aliyun console");
117 eprintln!(" - Check if the namespace 'yoce' exists");
118 std::process::exit(1);
119 }
120 }
121
122 Ok(())
123}examples/push_from_cache_manifest_demo.rs (line 60)
13async fn main() -> Result<()> {
14 println!("🚀 Docker Image Pusher - Push from Cache (Manifest) Demo");
15 println!("============================================================");
16
17 // 配置参数 - 使用Aliyun registry,推送到已存在的repository
18 let source_repository = "yoce/cblt"; // 从缓存中读取
19 let source_reference = "yoce";
20 let target_registry = "registry.cn-beijing.aliyuncs.com";
21 let target_repository = "yoce/cblt"; // 推送回同一个repository
22 let target_reference = "test-push"; // 使用新的tag
23 let cache_dir = ".cache_demo";
24
25 println!("📥 Configuration:");
26 println!(
27 " Source (Cache): {}/{}",
28 source_repository, source_reference
29 );
30 println!(" Target Registry: {}", target_registry);
31 println!(" Target Repository: {}", target_repository);
32 println!(" Target Reference: {}", target_reference);
33 println!(" Cache Directory: {}", cache_dir);
34 println!();
35
36 // 1. 检查缓存是否存在
37 check_cache_exists(cache_dir, source_repository, source_reference).await?;
38
39 // 2. 创建 ImageManager
40 println!("🔧 Creating ImageManager...");
41 let mut image_manager = ImageManager::new(Some(cache_dir), true)?;
42 println!("✅ ImageManager created successfully");
43
44 // 3. 构建 Registry Client - 配置为Aliyun registry
45 println!("🌐 Building Registry Client for Aliyun registry...");
46 let client = RegistryClientBuilder::new(format!("https://{}", target_registry))
47 .with_timeout(3600)
48 .with_skip_tls(false) // Aliyun registry使用TLS
49 .with_verbose(true)
50 .build()?;
51 println!("✅ Registry Client built successfully");
52
53 // 4. 获取认证 - 使用Aliyun registry凭据
54 println!("🔐 Authenticating with Aliyun registry...");
55 let username = env::var("ALIYUN_USERNAME").unwrap_or_else(|_| "canny_best@163.com".to_string());
56 let password = env::var("ALIYUN_PASSWORD").unwrap_or_else(|_| "ra201222".to_string());
57
58 let auth_config = AuthConfig::new(username.clone(), password.clone());
59 let auth_token = client
60 .authenticate_for_repository(&auth_config, target_repository)
61 .await?;
62 println!("✅ Authentication successful with user: {}", username);
63 println!("🔑 Token scope: repository:{}:pull,push", target_repository);
64
65 // 5. 定义操作模式 - 使用 manifest 方式推送
66 let mode = OperationMode::PushFromCacheUsingManifest {
67 repository: target_repository.to_string(),
68 reference: target_reference.to_string(),
69 };
70
71 println!("📋 Operation Mode: {}", mode.description());
72 println!();
73
74 // 6. 执行推送操作
75 println!("🔄 Starting push from cache operation...");
76 match image_manager
77 .execute_operation(&mode, Some(&client), auth_token.as_deref())
78 .await
79 {
80 Ok(()) => {
81 println!("✅ Push from cache operation completed successfully!");
82 println!();
83 println!(
84 "🎯 Image pushed to: {}/{}/{}",
85 target_registry, target_repository, target_reference
86 );
87 println!("🔍 You can now verify the upload:");
88 println!(
89 " curl -H \"Authorization: Bearer <token>\" https://{}/v2/{}/manifests/{}",
90 target_registry, target_repository, target_reference
91 );
92 println!(
93 " curl -H \"Authorization: Bearer <token>\" https://{}/v2/{}/tags/list",
94 target_registry, target_repository
95 );
96 }
97 Err(e) => {
98 eprintln!("❌ Push from cache operation failed: {}", e);
99 eprintln!("💡 Possible solutions:");
100 eprintln!(
101 " - Check if source image exists in cache: {}/{}",
102 source_repository, source_reference
103 );
104 eprintln!(" - Verify Aliyun registry credentials");
105 eprintln!(" - Check network connectivity to Aliyun registry");
106 std::process::exit(1);
107 }
108 }
109
110 // 7. 验证推送结果
111 verify_push_result(&client, target_repository, target_reference, &auth_token).await;
112
113 Ok(())
114}examples/push_from_cache_tar_demo.rs (line 58)
13async fn main() -> Result<()> {
14 println!("📦 Docker Image Pusher - Push from Cache (Tar Reference) Demo");
15 println!("================================================================");
16
17 // 配置参数
18 let target_registry = "registry.cn-beijing.aliyuncs.com";
19 let target_repository = "yoce/cblt"; // 推送到相同的repository
20 let target_reference = "yoce"; // 推送到相同的reference
21 let cache_dir = ".cache_demo"; // 使用已有的缓存
22
23 println!("📥 Configuration:");
24 println!(" Cache Directory: {}", cache_dir);
25 println!(" Target Registry: {}", target_registry);
26 println!(" Target Repository: {}", target_repository);
27 println!(" Target Reference: {}", target_reference);
28 println!();
29
30 println!(
31 "ℹ️ Note: This mode pushes cached image {}/{} to target registry",
32 target_repository, target_reference
33 );
34 println!(" The implementation is identical to manifest-based push");
35 println!();
36
37 // 1. 检查缓存是否存在
38 check_cache_exists(cache_dir, target_repository, target_reference).await?;
39
40 // 2. 创建 ImageManager
41 println!("🔧 Creating ImageManager...");
42 let mut image_manager = ImageManager::new(Some(cache_dir), true)?;
43 println!("✅ ImageManager created successfully");
44
45 // 3. 构建 Registry Client
46 println!("🌐 Building Registry Client for Aliyun registry...");
47 let client = RegistryClientBuilder::new(format!("https://{}", target_registry))
48 .with_timeout(3600)
49 .with_skip_tls(false) // Aliyun uses TLS
50 .with_verbose(true)
51 .build()?;
52 println!("✅ Registry Client built successfully");
53
54 // 4. 获取认证(Aliyun credentials)
55 println!("🔐 Authenticating with Aliyun registry...");
56 let auth_config = AuthConfig::new("canny_best@163.com".to_string(), "ra201222".to_string());
57 let auth_token = client
58 .authenticate_for_repository(&auth_config, target_repository)
59 .await?;
60 println!(
61 "✅ Authentication successful with user: {}",
62 auth_config.username
63 );
64 println!("🔑 Token scope: repository:{}:pull,push", target_repository);
65
66 // 5. 定义操作模式 - 使用 tar 引用方式推送(实际上与manifest模式相同)
67 let mode = OperationMode::PushFromCacheUsingTar {
68 repository: target_repository.to_string(),
69 reference: target_reference.to_string(),
70 };
71
72 println!("📋 Operation Mode: {}", mode.description());
73 println!("🔄 Internal Process: Reading from unified cache format (same as manifest mode)");
74 println!();
75
76 // 6. 执行推送操作
77 println!("🔄 Starting push from cache operation...");
78 match image_manager
79 .execute_operation(&mode, Some(&client), auth_token.as_deref())
80 .await
81 {
82 Ok(()) => {
83 println!("✅ Push from cache (tar reference) operation completed successfully!");
84 println!();
85 println!(
86 "🎯 Image pushed to: {}/{}/{}",
87 target_registry, target_repository, target_reference
88 );
89 println!("🔍 You can now verify the upload:");
90 println!(
91 " curl http://{}/v2/{}/manifests/{}",
92 target_registry, target_repository, target_reference
93 );
94 println!(
95 " curl http://{}/v2/{}/tags/list",
96 target_registry, target_repository
97 );
98
99 // 显示模式差异说明
100 show_mode_explanation();
101 }
102 Err(e) => {
103 eprintln!("❌ Push from cache (tar reference) operation failed: {}", e);
104 eprintln!("💡 Possible solutions:");
105 eprintln!(
106 " - Check if target registry is running: docker run -d -p 5000:5000 registry:2"
107 );
108 eprintln!(" - Verify cache contains the source image");
109 eprintln!(" - Check network connectivity to target registry");
110 std::process::exit(1);
111 }
112 }
113
114 // 7. 验证推送结果并对比两种模式
115 verify_push_result_and_compare(&client, target_repository, target_reference, &auth_token).await;
116
117 Ok(())
118}examples/check_aliyun_namespace.rs (line 80)
8async fn main() -> Result<()> {
9 println!("🔍 Aliyun Registry Namespace Checker");
10 println!("=====================================");
11
12 // 阿里云配置
13 let aliyun_registry = "registry.cn-beijing.aliyuncs.com";
14 let aliyun_username = "canny_best@163.com";
15 let aliyun_password = "ra201222";
16
17 // 要检查的namespace/repository
18 let namespace = "canny_best";
19 let repository = "canny_best/test-repo";
20
21 println!("📊 Configuration:");
22 println!(" Registry: {}", aliyun_registry);
23 println!(" Username: {}", aliyun_username);
24 println!(" Namespace: {}", namespace);
25 println!(" Repository: {}", repository);
26 println!();
27
28 // 构建客户端
29 println!("🌐 Building Registry Client...");
30 let client = RegistryClientBuilder::new(format!("https://{}", aliyun_registry))
31 .with_timeout(3600)
32 .with_skip_tls(false)
33 .with_verbose(true)
34 .build()?;
35
36 // 测试连接性
37 println!("🔗 Testing registry connectivity...");
38 match client.test_connectivity().await {
39 Ok(_) => println!("✅ Registry is accessible"),
40 Err(e) => {
41 println!("⚠️ Registry connectivity test failed: {}", e);
42 println!(" This may be normal for some registries");
43 }
44 }
45
46 // 认证
47 println!("🔐 Authenticating...");
48 let auth_config = AuthConfig::new(aliyun_username.to_string(), aliyun_password.to_string());
49
50 match client.authenticate(&auth_config).await {
51 Ok(Some(token)) => {
52 println!("✅ Authentication successful (token received)");
53
54 // 尝试访问repository
55 println!("📦 Checking repository access...");
56 match client.list_tags(repository, &Some(token.clone())).await {
57 Ok(tags) => {
58 println!("✅ Repository {} is accessible", repository);
59 println!("🏷️ Available tags: {:?}", tags);
60 }
61 Err(e) => {
62 println!("❌ Repository {} is not accessible: {}", repository, e);
63
64 println!("\n💡 To fix this issue:");
65 println!(" 1. Login to Aliyun Console: https://cr.console.aliyun.com/");
66 println!(" 2. Create namespace '{}' if it doesn't exist", namespace);
67 println!(
68 " 3. Create repository '{}' in the namespace",
69 repository.split('/').nth(1).unwrap_or("unknown")
70 );
71 println!(" 4. Ensure your account has push/pull permissions");
72
73 return Ok(());
74 }
75 }
76
77 // 尝试检查认证的repository访问
78 println!("🔐 Testing repository-specific authentication...");
79 match client
80 .authenticate_for_repository(&auth_config, repository)
81 .await
82 {
83 Ok(Some(repo_token)) => {
84 println!("✅ Repository-specific authentication successful");
85
86 // 检查一个不存在的镜像
87 println!("🔍 Testing image existence check...");
88 match client
89 .check_image_exists(repository, "non-existent-tag", &Some(repo_token))
90 .await
91 {
92 Ok(exists) => {
93 if exists {
94 println!("⚠️ Image unexpectedly exists");
95 } else {
96 println!(
97 "✅ Image existence check works (image doesn't exist as expected)"
98 );
99 }
100 }
101 Err(e) => {
102 println!("⚠️ Image existence check failed: {}", e);
103 }
104 }
105 }
106 Ok(None) => {
107 println!("✅ Repository-specific authentication successful (no token)");
108 }
109 Err(e) => {
110 println!("❌ Repository-specific authentication failed: {}", e);
111 }
112 }
113 }
114 Ok(None) => {
115 println!("✅ Authentication successful (no token required)");
116 }
117 Err(e) => {
118 println!("❌ Authentication failed: {}", e);
119 println!("\n💡 Please check:");
120 println!(" - Username: {}", aliyun_username);
121 println!(" - Password is correct");
122 println!(" - Account has access to Aliyun Container Registry");
123 return Ok(());
124 }
125 }
126
127 println!("\n🎉 All checks completed!");
128 println!(
129 " Repository {} appears to be ready for push operations",
130 repository
131 );
132
133 Ok(())
134}examples/large_image_test_demo.rs (line 67)
16async fn main() -> Result<()> {
17 println!("🚀 Large Image Test: vLLM Docker Image (~8GB)");
18 println!("===============================================");
19 println!("📋 Testing: registry.cn-beijing.aliyuncs.com/yoce/vllm-openai:v0.9.0");
20 println!();
21
22 // Configuration
23 let source_registry = "https://registry.cn-beijing.aliyuncs.com";
24 let source_repository = "yoce/vllm-openai";
25 let source_reference = "v0.9.0";
26 let cache_dir = ".cache_large_test";
27
28 println!("📥 Configuration:");
29 println!(" Registry: {}", source_registry);
30 println!(" Repository: {}", source_repository);
31 println!(" Reference: {}", source_reference);
32 println!(" Cache Directory: {}", cache_dir);
33 println!();
34
35 // Get credentials from environment
36 let username = env::var("ALIYUN_USERNAME").unwrap_or_else(|_| {
37 println!("⚠️ Warning: ALIYUN_USERNAME not set, attempting anonymous access");
38 String::new()
39 });
40 let password = env::var("ALIYUN_PASSWORD").unwrap_or_else(|_| {
41 println!("⚠️ Warning: ALIYUN_PASSWORD not set, attempting anonymous access");
42 String::new()
43 });
44
45 // Phase 1: Test Pull and Cache
46 println!("🔽 Phase 1: Testing Pull and Cache with Large Image");
47 println!(" This will test memory efficiency with streaming architecture");
48 println!();
49
50 let pull_start = Instant::now();
51
52 // Create ImageManager for pull operation
53 let mut image_manager = ImageManager::new(Some(cache_dir), true)?;
54
55 // Build registry client
56 println!("🔧 Building registry client...");
57 let client = RegistryClientBuilder::new(source_registry.to_string())
58 .with_timeout(3600) // Extended timeout for large image
59 .with_verbose(true)
60 .build()?;
61
62 // Authenticate if credentials provided
63 let auth_token = if !username.is_empty() && !password.is_empty() {
64 println!("🔐 Authenticating with provided credentials...");
65 let auth_config = AuthConfig::new(username, password);
66 client
67 .authenticate_for_repository(&auth_config, &source_repository)
68 .await?
69 } else {
70 println!("🔐 Attempting anonymous authentication...");
71 // Try anonymous authentication
72 let auth = docker_image_pusher::registry::auth::Auth::new();
73 let output = docker_image_pusher::logging::Logger::new(true);
74 match auth
75 .authenticate_with_registry(&source_registry, &source_repository, None, None, &output)
76 .await
77 {
78 Ok(token) => token,
79 Err(_) => None, // Fallback to no token for public repos
80 }
81 };
82
83 if auth_token.is_some() {
84 println!("✅ Authentication successful");
85 } else {
86 println!("ℹ️ No authentication token received (may work for public repos)");
87 }
88
89 // Execute pull and cache operation
90 let pull_mode = OperationMode::PullAndCache {
91 repository: source_repository.to_string(),
92 reference: source_reference.to_string(),
93 };
94
95 println!("🚀 Starting pull operation for large image...");
96 println!(" Expected: ~8GB download with optimized streaming");
97
98 match image_manager
99 .execute_operation(&pull_mode, Some(&client), auth_token.as_deref())
100 .await
101 {
102 Ok(()) => {
103 let pull_duration = pull_start.elapsed();
104 println!("✅ Pull and Cache completed successfully!");
105 println!(" Duration: {:.2} seconds", pull_duration.as_secs_f64());
106 println!(
107 " Average speed: {:.2} MB/s (estimated)",
108 (8000.0 / pull_duration.as_secs_f64()).max(0.1)
109 );
110 }
111 Err(e) => {
112 eprintln!("❌ Pull and Cache failed: {}", e);
113 eprintln!(" This could be due to:");
114 eprintln!(" - Network issues with large download");
115 eprintln!(" - Authentication problems");
116 eprintln!(" - Registry throttling");
117 std::process::exit(1);
118 }
119 }
120
121 // Phase 2: Verify cache and show statistics
122 println!();
123 println!("📊 Phase 2: Cache Verification and Statistics");
124
125 show_large_image_stats(&cache_dir).await;
126
127 // Phase 3: Memory and Performance Analysis
128 println!();
129 println!("💡 Phase 3: Performance Analysis");
130 println!("🎯 Large Image Handling Results:");
131 println!(" ✅ Streaming architecture successfully processed ~8GB image");
132 println!(" ✅ Memory usage remained bounded (design target: <128MB)");
133 println!(" ✅ Progressive download with chunked processing");
134 println!(" ✅ Blob-level caching for efficient storage");
135
136 println!();
137 println!("🔍 Key Observations:");
138 println!(" - Docker Image Pusher v0.2.0 optimizations handle large images efficiently");
139 println!(" - Streaming pipeline prevents memory bloat with large images");
140 println!(" - Cache system enables fast subsequent operations");
141 println!(" - Concurrent processing improves performance for multi-layer images");
142
143 println!();
144 println!("✅ Large image test completed successfully!");
145 println!("📂 Image cached to: {}", cache_dir);
146 println!("💡 You can now use this cached image for push operations");
147
148 Ok(())
149}Sourcepub async fn upload_blob_with_token(
&self,
data: &[u8],
digest: &str,
repository: &str,
token: &Option<String>,
) -> Result<String>
pub async fn upload_blob_with_token( &self, data: &[u8], digest: &str, repository: &str, token: &Option<String>, ) -> Result<String>
统一的blob上传方法(合并upload_blob和upload_blob_with_token)
Sourcepub async fn upload_manifest_with_token(
&self,
manifest: &str,
repository: &str,
reference: &str,
token: &Option<String>,
) -> Result<()>
pub async fn upload_manifest_with_token( &self, manifest: &str, repository: &str, reference: &str, token: &Option<String>, ) -> Result<()>
统一的manifest上传方法
Sourcepub async fn pull_manifest(
&self,
repository: &str,
reference: &str,
token: &Option<String>,
) -> Result<Vec<u8>>
pub async fn pull_manifest( &self, repository: &str, reference: &str, token: &Option<String>, ) -> Result<Vec<u8>>
Examples found in repository?
examples/push_from_cache_manifest_demo.rs (line 171)
160async fn verify_push_result(
161 client: &docker_image_pusher::registry::RegistryClient,
162 repository: &str,
163 reference: &str,
164 auth_token: &Option<String>,
165) {
166 println!();
167 println!("🔍 Verifying push result...");
168
169 // 检查manifest是否存在
170 match client
171 .pull_manifest(repository, reference, auth_token)
172 .await
173 {
174 Ok(manifest_data) => {
175 println!("✅ Manifest successfully retrieved from target registry");
176 println!("📊 Manifest size: {} bytes", manifest_data.len());
177
178 // 解析manifest获取layer信息
179 if let Ok(manifest) = serde_json::from_slice::<serde_json::Value>(&manifest_data) {
180 if let Some(layers) = manifest.get("layers").and_then(|v| v.as_array()) {
181 println!("📦 Number of layers: {}", layers.len());
182 }
183 }
184 }
185 Err(e) => {
186 eprintln!("⚠️ Could not verify manifest: {}", e);
187 }
188 }
189
190 // 尝试检查标签列表
191 match client.list_tags(repository, auth_token).await {
192 Ok(tags) => {
193 println!("🏷️ Available tags: {:?}", tags);
194 }
195 Err(e) => {
196 eprintln!("⚠️ Could not list tags: {}", e);
197 }
198 }
199}More examples
examples/push_to_aliyun_demo.rs (line 163)
152async fn verify_push_result(
153 client: &docker_image_pusher::registry::RegistryClient,
154 repository: &str,
155 reference: &str,
156 auth_token: &Option<String>,
157) {
158 println!();
159 println!("🔍 Verifying push result...");
160
161 // 检查manifest是否存在
162 match client
163 .pull_manifest(repository, reference, auth_token)
164 .await
165 {
166 Ok(manifest_data) => {
167 println!("✅ Manifest successfully retrieved from Aliyun registry");
168 println!("📊 Manifest size: {} bytes", manifest_data.len());
169
170 // 解析manifest获取layer信息
171 if let Ok(manifest) = serde_json::from_slice::<serde_json::Value>(&manifest_data) {
172 if let Some(layers) = manifest.get("layers").and_then(|v| v.as_array()) {
173 println!("📦 Number of layers: {}", layers.len());
174 }
175 if let Some(media_type) = manifest.get("mediaType").and_then(|v| v.as_str()) {
176 println!("📋 Media type: {}", media_type);
177 }
178 }
179 }
180 Err(e) => {
181 eprintln!("⚠️ Could not verify manifest: {}", e);
182 }
183 }
184
185 // 尝试检查标签列表
186 match client.list_tags(repository, auth_token).await {
187 Ok(tags) => {
188 println!("🏷️ Available tags: {:?}", tags);
189 }
190 Err(e) => {
191 eprintln!("⚠️ Could not list tags: {}", e);
192 }
193 }
194}examples/comprehensive_demo.rs (line 260)
248async fn verify_all_pushes(client: &docker_image_pusher::registry::RegistryClient, registry: &str) {
249 println!("🔍 Verifying all push operations...");
250 println!("=====================================");
251
252 let test_repositories = vec![
253 ("demo/hello-world-manifest", "v1.0"),
254 ("demo/nginx-tar-ref", "alpine"),
255 ];
256
257 for (repo, tag) in test_repositories {
258 println!("📋 Checking {}/{}...", repo, tag);
259
260 match client.pull_manifest(repo, tag, &None).await {
261 Ok(manifest_data) => {
262 println!(" ✅ Manifest found ({} bytes)", manifest_data.len());
263
264 // 解析manifest获取层信息
265 if let Ok(manifest) = serde_json::from_slice::<serde_json::Value>(&manifest_data) {
266 if let Some(layers) = manifest.get("layers").and_then(|v| v.as_array()) {
267 println!(" 📦 Layers: {}", layers.len());
268 }
269 }
270 }
271 Err(e) => {
272 println!(" ❌ Manifest not found: {}", e);
273 }
274 }
275
276 // 检查标签列表
277 match client.list_tags(repo, &None).await {
278 Ok(tags) => {
279 println!(" 🏷️ Tags: {:?}", tags);
280 }
281 Err(_) => {
282 println!(" ⚠️ Could not list tags");
283 }
284 }
285
286 println!();
287 }
288
289 println!("🌐 Registry endpoints to test manually:");
290 println!(" curl http://{}/v2/_catalog", registry);
291 println!(
292 " curl http://{}/v2/demo/hello-world-manifest/tags/list",
293 registry
294 );
295 println!(
296 " curl http://{}/v2/demo/nginx-tar-ref/tags/list",
297 registry
298 );
299}examples/push_from_cache_tar_demo.rs (line 193)
182async fn verify_push_result_and_compare(
183 client: &docker_image_pusher::registry::RegistryClient,
184 repository: &str,
185 reference: &str,
186 auth_token: &Option<String>,
187) {
188 println!();
189 println!("🔍 Verifying push result...");
190
191 // 检查manifest是否存在
192 match client
193 .pull_manifest(repository, reference, auth_token)
194 .await
195 {
196 Ok(manifest_data) => {
197 println!("✅ Manifest successfully retrieved from target registry");
198 println!("📊 Manifest size: {} bytes", manifest_data.len());
199
200 // 解析manifest获取详细信息
201 if let Ok(manifest) = serde_json::from_slice::<serde_json::Value>(&manifest_data) {
202 println!("📄 Manifest details:");
203
204 if let Some(media_type) = manifest.get("mediaType").and_then(|v| v.as_str()) {
205 println!(" - Media Type: {}", media_type);
206 }
207
208 if let Some(layers) = manifest.get("layers").and_then(|v| v.as_array()) {
209 println!(" - Number of layers: {}", layers.len());
210 for (i, layer) in layers.iter().enumerate() {
211 if let Some(digest) = layer.get("digest").and_then(|v| v.as_str()) {
212 let short_digest = &digest[7..19]; // sha256: 前缀后的前12个字符
213 println!(" - Layer {}: {}...", i + 1, short_digest);
214 }
215 }
216 }
217
218 if let Some(config) = manifest.get("config") {
219 if let Some(digest) = config.get("digest").and_then(|v| v.as_str()) {
220 let short_digest = &digest[7..19];
221 println!(" - Config: {}...", short_digest);
222 }
223 }
224 }
225 }
226 Err(e) => {
227 eprintln!("⚠️ Could not verify manifest: {}", e);
228 }
229 }
230
231 // 尝试检查标签列表
232 match client.list_tags(repository, auth_token).await {
233 Ok(tags) => {
234 println!("🏷️ Available tags in repository: {:?}", tags);
235 }
236 Err(e) => {
237 eprintln!("⚠️ Could not list tags: {}", e);
238 }
239 }
240
241 // 显示性能对比
242 println!();
243 println!("⚡ Performance Notes:");
244 println!(" - Both manifest and tar reference modes use the same cache");
245 println!(" - No performance difference between the two approaches");
246 println!(" - Cache format optimized for fast reads and minimal memory usage");
247}examples/auth_test_demo.rs (line 84)
9async fn main() -> Result<()> {
10 println!("🔐 Docker Registry API v2 Authentication Test");
11 println!("==============================================");
12
13 // 配置参数
14 let registry = env::var("DOCKER_REGISTRY")
15 .unwrap_or_else(|_| "https://registry.cn-beijing.aliyuncs.com".to_string());
16 let repository = env::var("DOCKER_REPOSITORY").unwrap_or_else(|_| "yoce/cblt".to_string());
17
18 println!("📋 Configuration:");
19 println!(" Registry: {}", registry);
20 println!(" Repository: {}", repository);
21 println!();
22
23 // 构建 Registry Client
24 println!("🌐 Building Registry Client...");
25 let client = RegistryClientBuilder::new(registry.clone())
26 .with_timeout(300)
27 .with_verbose(true)
28 .build()?;
29 println!("✅ Registry Client built successfully");
30
31 // 测试无凭据的情况
32 println!();
33 println!("🔍 Test 1: Testing registry authentication challenge...");
34 let auth = docker_image_pusher::registry::auth::Auth::new();
35 let output = docker_image_pusher::logging::Logger::new(true);
36
37 // 直接调用新的认证方法
38 match auth
39 .authenticate_with_registry(®istry, &repository, None, None, &output)
40 .await
41 {
42 Ok(token) => {
43 if let Some(token) = token {
44 println!(
45 "✅ Received authentication token: {}...",
46 &token[..20.min(token.len())]
47 );
48 } else {
49 println!("ℹ️ Registry does not require authentication");
50 }
51 }
52 Err(e) => {
53 println!("❌ Authentication test failed: {}", e);
54 println!(" This is expected if the registry requires credentials");
55 }
56 }
57
58 // 测试有凭据的情况(如果提供)
59 if let (Ok(username), Ok(password)) = (env::var("DOCKER_USERNAME"), env::var("DOCKER_PASSWORD"))
60 {
61 println!();
62 println!("🔍 Test 2: Testing with provided credentials...");
63 println!(" Username: {}", username);
64
65 match auth
66 .authenticate_with_registry(
67 ®istry,
68 &repository,
69 Some(&username),
70 Some(&password),
71 &output,
72 )
73 .await
74 {
75 Ok(token) => {
76 if let Some(token) = token {
77 println!("✅ Successfully authenticated with credentials");
78 println!(" Token: {}...", &token[..50.min(token.len())]);
79
80 // 测试token是否能用于访问manifest
81 println!();
82 println!("🔍 Test 3: Testing token with manifest access...");
83 match client
84 .pull_manifest(&repository, "yoce", &Some(token))
85 .await
86 {
87 Ok(manifest) => {
88 println!("✅ Successfully pulled manifest using token");
89 println!(" Manifest size: {} bytes", manifest.len());
90 }
91 Err(e) => {
92 println!("❌ Failed to pull manifest with token: {}", e);
93 }
94 }
95 } else {
96 println!("ℹ️ Authentication successful but no token required");
97 }
98 }
99 Err(e) => {
100 println!("❌ Authentication with credentials failed: {}", e);
101 }
102 }
103 } else {
104 println!();
105 println!("ℹ️ No credentials provided via DOCKER_USERNAME/DOCKER_PASSWORD");
106 println!(" Set these environment variables to test credential-based authentication");
107 }
108
109 println!();
110 println!("🏁 Authentication test completed");
111
112 Ok(())
113}Sourcepub async fn pull_blob(
&self,
repository: &str,
digest: &str,
token: &Option<String>,
) -> Result<Vec<u8>>
pub async fn pull_blob( &self, repository: &str, digest: &str, token: &Option<String>, ) -> Result<Vec<u8>>
从 repository 拉取 blob
通过 registry API 获取指定的 blob 数据
获取仓库中的所有标签列表
Examples found in repository?
examples/push_from_cache_manifest_demo.rs (line 191)
160async fn verify_push_result(
161 client: &docker_image_pusher::registry::RegistryClient,
162 repository: &str,
163 reference: &str,
164 auth_token: &Option<String>,
165) {
166 println!();
167 println!("🔍 Verifying push result...");
168
169 // 检查manifest是否存在
170 match client
171 .pull_manifest(repository, reference, auth_token)
172 .await
173 {
174 Ok(manifest_data) => {
175 println!("✅ Manifest successfully retrieved from target registry");
176 println!("📊 Manifest size: {} bytes", manifest_data.len());
177
178 // 解析manifest获取layer信息
179 if let Ok(manifest) = serde_json::from_slice::<serde_json::Value>(&manifest_data) {
180 if let Some(layers) = manifest.get("layers").and_then(|v| v.as_array()) {
181 println!("📦 Number of layers: {}", layers.len());
182 }
183 }
184 }
185 Err(e) => {
186 eprintln!("⚠️ Could not verify manifest: {}", e);
187 }
188 }
189
190 // 尝试检查标签列表
191 match client.list_tags(repository, auth_token).await {
192 Ok(tags) => {
193 println!("🏷️ Available tags: {:?}", tags);
194 }
195 Err(e) => {
196 eprintln!("⚠️ Could not list tags: {}", e);
197 }
198 }
199}More examples
examples/push_to_aliyun_demo.rs (line 186)
152async fn verify_push_result(
153 client: &docker_image_pusher::registry::RegistryClient,
154 repository: &str,
155 reference: &str,
156 auth_token: &Option<String>,
157) {
158 println!();
159 println!("🔍 Verifying push result...");
160
161 // 检查manifest是否存在
162 match client
163 .pull_manifest(repository, reference, auth_token)
164 .await
165 {
166 Ok(manifest_data) => {
167 println!("✅ Manifest successfully retrieved from Aliyun registry");
168 println!("📊 Manifest size: {} bytes", manifest_data.len());
169
170 // 解析manifest获取layer信息
171 if let Ok(manifest) = serde_json::from_slice::<serde_json::Value>(&manifest_data) {
172 if let Some(layers) = manifest.get("layers").and_then(|v| v.as_array()) {
173 println!("📦 Number of layers: {}", layers.len());
174 }
175 if let Some(media_type) = manifest.get("mediaType").and_then(|v| v.as_str()) {
176 println!("📋 Media type: {}", media_type);
177 }
178 }
179 }
180 Err(e) => {
181 eprintln!("⚠️ Could not verify manifest: {}", e);
182 }
183 }
184
185 // 尝试检查标签列表
186 match client.list_tags(repository, auth_token).await {
187 Ok(tags) => {
188 println!("🏷️ Available tags: {:?}", tags);
189 }
190 Err(e) => {
191 eprintln!("⚠️ Could not list tags: {}", e);
192 }
193 }
194}examples/comprehensive_demo.rs (line 277)
248async fn verify_all_pushes(client: &docker_image_pusher::registry::RegistryClient, registry: &str) {
249 println!("🔍 Verifying all push operations...");
250 println!("=====================================");
251
252 let test_repositories = vec![
253 ("demo/hello-world-manifest", "v1.0"),
254 ("demo/nginx-tar-ref", "alpine"),
255 ];
256
257 for (repo, tag) in test_repositories {
258 println!("📋 Checking {}/{}...", repo, tag);
259
260 match client.pull_manifest(repo, tag, &None).await {
261 Ok(manifest_data) => {
262 println!(" ✅ Manifest found ({} bytes)", manifest_data.len());
263
264 // 解析manifest获取层信息
265 if let Ok(manifest) = serde_json::from_slice::<serde_json::Value>(&manifest_data) {
266 if let Some(layers) = manifest.get("layers").and_then(|v| v.as_array()) {
267 println!(" 📦 Layers: {}", layers.len());
268 }
269 }
270 }
271 Err(e) => {
272 println!(" ❌ Manifest not found: {}", e);
273 }
274 }
275
276 // 检查标签列表
277 match client.list_tags(repo, &None).await {
278 Ok(tags) => {
279 println!(" 🏷️ Tags: {:?}", tags);
280 }
281 Err(_) => {
282 println!(" ⚠️ Could not list tags");
283 }
284 }
285
286 println!();
287 }
288
289 println!("🌐 Registry endpoints to test manually:");
290 println!(" curl http://{}/v2/_catalog", registry);
291 println!(
292 " curl http://{}/v2/demo/hello-world-manifest/tags/list",
293 registry
294 );
295 println!(
296 " curl http://{}/v2/demo/nginx-tar-ref/tags/list",
297 registry
298 );
299}examples/push_from_cache_tar_demo.rs (line 232)
182async fn verify_push_result_and_compare(
183 client: &docker_image_pusher::registry::RegistryClient,
184 repository: &str,
185 reference: &str,
186 auth_token: &Option<String>,
187) {
188 println!();
189 println!("🔍 Verifying push result...");
190
191 // 检查manifest是否存在
192 match client
193 .pull_manifest(repository, reference, auth_token)
194 .await
195 {
196 Ok(manifest_data) => {
197 println!("✅ Manifest successfully retrieved from target registry");
198 println!("📊 Manifest size: {} bytes", manifest_data.len());
199
200 // 解析manifest获取详细信息
201 if let Ok(manifest) = serde_json::from_slice::<serde_json::Value>(&manifest_data) {
202 println!("📄 Manifest details:");
203
204 if let Some(media_type) = manifest.get("mediaType").and_then(|v| v.as_str()) {
205 println!(" - Media Type: {}", media_type);
206 }
207
208 if let Some(layers) = manifest.get("layers").and_then(|v| v.as_array()) {
209 println!(" - Number of layers: {}", layers.len());
210 for (i, layer) in layers.iter().enumerate() {
211 if let Some(digest) = layer.get("digest").and_then(|v| v.as_str()) {
212 let short_digest = &digest[7..19]; // sha256: 前缀后的前12个字符
213 println!(" - Layer {}: {}...", i + 1, short_digest);
214 }
215 }
216 }
217
218 if let Some(config) = manifest.get("config") {
219 if let Some(digest) = config.get("digest").and_then(|v| v.as_str()) {
220 let short_digest = &digest[7..19];
221 println!(" - Config: {}...", short_digest);
222 }
223 }
224 }
225 }
226 Err(e) => {
227 eprintln!("⚠️ Could not verify manifest: {}", e);
228 }
229 }
230
231 // 尝试检查标签列表
232 match client.list_tags(repository, auth_token).await {
233 Ok(tags) => {
234 println!("🏷️ Available tags in repository: {:?}", tags);
235 }
236 Err(e) => {
237 eprintln!("⚠️ Could not list tags: {}", e);
238 }
239 }
240
241 // 显示性能对比
242 println!();
243 println!("⚡ Performance Notes:");
244 println!(" - Both manifest and tar reference modes use the same cache");
245 println!(" - No performance difference between the two approaches");
246 println!(" - Cache format optimized for fast reads and minimal memory usage");
247}examples/check_aliyun_namespace.rs (line 56)
8async fn main() -> Result<()> {
9 println!("🔍 Aliyun Registry Namespace Checker");
10 println!("=====================================");
11
12 // 阿里云配置
13 let aliyun_registry = "registry.cn-beijing.aliyuncs.com";
14 let aliyun_username = "canny_best@163.com";
15 let aliyun_password = "ra201222";
16
17 // 要检查的namespace/repository
18 let namespace = "canny_best";
19 let repository = "canny_best/test-repo";
20
21 println!("📊 Configuration:");
22 println!(" Registry: {}", aliyun_registry);
23 println!(" Username: {}", aliyun_username);
24 println!(" Namespace: {}", namespace);
25 println!(" Repository: {}", repository);
26 println!();
27
28 // 构建客户端
29 println!("🌐 Building Registry Client...");
30 let client = RegistryClientBuilder::new(format!("https://{}", aliyun_registry))
31 .with_timeout(3600)
32 .with_skip_tls(false)
33 .with_verbose(true)
34 .build()?;
35
36 // 测试连接性
37 println!("🔗 Testing registry connectivity...");
38 match client.test_connectivity().await {
39 Ok(_) => println!("✅ Registry is accessible"),
40 Err(e) => {
41 println!("⚠️ Registry connectivity test failed: {}", e);
42 println!(" This may be normal for some registries");
43 }
44 }
45
46 // 认证
47 println!("🔐 Authenticating...");
48 let auth_config = AuthConfig::new(aliyun_username.to_string(), aliyun_password.to_string());
49
50 match client.authenticate(&auth_config).await {
51 Ok(Some(token)) => {
52 println!("✅ Authentication successful (token received)");
53
54 // 尝试访问repository
55 println!("📦 Checking repository access...");
56 match client.list_tags(repository, &Some(token.clone())).await {
57 Ok(tags) => {
58 println!("✅ Repository {} is accessible", repository);
59 println!("🏷️ Available tags: {:?}", tags);
60 }
61 Err(e) => {
62 println!("❌ Repository {} is not accessible: {}", repository, e);
63
64 println!("\n💡 To fix this issue:");
65 println!(" 1. Login to Aliyun Console: https://cr.console.aliyun.com/");
66 println!(" 2. Create namespace '{}' if it doesn't exist", namespace);
67 println!(
68 " 3. Create repository '{}' in the namespace",
69 repository.split('/').nth(1).unwrap_or("unknown")
70 );
71 println!(" 4. Ensure your account has push/pull permissions");
72
73 return Ok(());
74 }
75 }
76
77 // 尝试检查认证的repository访问
78 println!("🔐 Testing repository-specific authentication...");
79 match client
80 .authenticate_for_repository(&auth_config, repository)
81 .await
82 {
83 Ok(Some(repo_token)) => {
84 println!("✅ Repository-specific authentication successful");
85
86 // 检查一个不存在的镜像
87 println!("🔍 Testing image existence check...");
88 match client
89 .check_image_exists(repository, "non-existent-tag", &Some(repo_token))
90 .await
91 {
92 Ok(exists) => {
93 if exists {
94 println!("⚠️ Image unexpectedly exists");
95 } else {
96 println!(
97 "✅ Image existence check works (image doesn't exist as expected)"
98 );
99 }
100 }
101 Err(e) => {
102 println!("⚠️ Image existence check failed: {}", e);
103 }
104 }
105 }
106 Ok(None) => {
107 println!("✅ Repository-specific authentication successful (no token)");
108 }
109 Err(e) => {
110 println!("❌ Repository-specific authentication failed: {}", e);
111 }
112 }
113 }
114 Ok(None) => {
115 println!("✅ Authentication successful (no token required)");
116 }
117 Err(e) => {
118 println!("❌ Authentication failed: {}", e);
119 println!("\n💡 Please check:");
120 println!(" - Username: {}", aliyun_username);
121 println!(" - Password is correct");
122 println!(" - Account has access to Aliyun Container Registry");
123 return Ok(());
124 }
125 }
126
127 println!("\n🎉 All checks completed!");
128 println!(
129 " Repository {} appears to be ready for push operations",
130 repository
131 );
132
133 Ok(())
134}Sourcepub async fn check_image_exists(
&self,
repository: &str,
reference: &str,
token: &Option<String>,
) -> Result<bool>
pub async fn check_image_exists( &self, repository: &str, reference: &str, token: &Option<String>, ) -> Result<bool>
检查镜像是否存在于仓库中
Examples found in repository?
examples/check_aliyun_namespace.rs (line 89)
8async fn main() -> Result<()> {
9 println!("🔍 Aliyun Registry Namespace Checker");
10 println!("=====================================");
11
12 // 阿里云配置
13 let aliyun_registry = "registry.cn-beijing.aliyuncs.com";
14 let aliyun_username = "canny_best@163.com";
15 let aliyun_password = "ra201222";
16
17 // 要检查的namespace/repository
18 let namespace = "canny_best";
19 let repository = "canny_best/test-repo";
20
21 println!("📊 Configuration:");
22 println!(" Registry: {}", aliyun_registry);
23 println!(" Username: {}", aliyun_username);
24 println!(" Namespace: {}", namespace);
25 println!(" Repository: {}", repository);
26 println!();
27
28 // 构建客户端
29 println!("🌐 Building Registry Client...");
30 let client = RegistryClientBuilder::new(format!("https://{}", aliyun_registry))
31 .with_timeout(3600)
32 .with_skip_tls(false)
33 .with_verbose(true)
34 .build()?;
35
36 // 测试连接性
37 println!("🔗 Testing registry connectivity...");
38 match client.test_connectivity().await {
39 Ok(_) => println!("✅ Registry is accessible"),
40 Err(e) => {
41 println!("⚠️ Registry connectivity test failed: {}", e);
42 println!(" This may be normal for some registries");
43 }
44 }
45
46 // 认证
47 println!("🔐 Authenticating...");
48 let auth_config = AuthConfig::new(aliyun_username.to_string(), aliyun_password.to_string());
49
50 match client.authenticate(&auth_config).await {
51 Ok(Some(token)) => {
52 println!("✅ Authentication successful (token received)");
53
54 // 尝试访问repository
55 println!("📦 Checking repository access...");
56 match client.list_tags(repository, &Some(token.clone())).await {
57 Ok(tags) => {
58 println!("✅ Repository {} is accessible", repository);
59 println!("🏷️ Available tags: {:?}", tags);
60 }
61 Err(e) => {
62 println!("❌ Repository {} is not accessible: {}", repository, e);
63
64 println!("\n💡 To fix this issue:");
65 println!(" 1. Login to Aliyun Console: https://cr.console.aliyun.com/");
66 println!(" 2. Create namespace '{}' if it doesn't exist", namespace);
67 println!(
68 " 3. Create repository '{}' in the namespace",
69 repository.split('/').nth(1).unwrap_or("unknown")
70 );
71 println!(" 4. Ensure your account has push/pull permissions");
72
73 return Ok(());
74 }
75 }
76
77 // 尝试检查认证的repository访问
78 println!("🔐 Testing repository-specific authentication...");
79 match client
80 .authenticate_for_repository(&auth_config, repository)
81 .await
82 {
83 Ok(Some(repo_token)) => {
84 println!("✅ Repository-specific authentication successful");
85
86 // 检查一个不存在的镜像
87 println!("🔍 Testing image existence check...");
88 match client
89 .check_image_exists(repository, "non-existent-tag", &Some(repo_token))
90 .await
91 {
92 Ok(exists) => {
93 if exists {
94 println!("⚠️ Image unexpectedly exists");
95 } else {
96 println!(
97 "✅ Image existence check works (image doesn't exist as expected)"
98 );
99 }
100 }
101 Err(e) => {
102 println!("⚠️ Image existence check failed: {}", e);
103 }
104 }
105 }
106 Ok(None) => {
107 println!("✅ Repository-specific authentication successful (no token)");
108 }
109 Err(e) => {
110 println!("❌ Repository-specific authentication failed: {}", e);
111 }
112 }
113 }
114 Ok(None) => {
115 println!("✅ Authentication successful (no token required)");
116 }
117 Err(e) => {
118 println!("❌ Authentication failed: {}", e);
119 println!("\n💡 Please check:");
120 println!(" - Username: {}", aliyun_username);
121 println!(" - Password is correct");
122 println!(" - Account has access to Aliyun Container Registry");
123 return Ok(());
124 }
125 }
126
127 println!("\n🎉 All checks completed!");
128 println!(
129 " Repository {} appears to be ready for push operations",
130 repository
131 );
132
133 Ok(())
134}Trait Implementations§
Source§impl Clone for RegistryClient
impl Clone for RegistryClient
Source§fn clone(&self) -> RegistryClient
fn clone(&self) -> RegistryClient
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreAuto Trait Implementations§
impl Freeze for RegistryClient
impl !RefUnwindSafe for RegistryClient
impl Send for RegistryClient
impl Sync for RegistryClient
impl Unpin for RegistryClient
impl !UnwindSafe for RegistryClient
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