9.2 KiB
9.2 KiB
OCI Registry Integration Guide
Overview
The OCI integration module provides OCI Distribution Spec v2 compliant registry integration for pulling KCL packages and extension artifacts.
Architecture
┌──────────────────┐
│ Orchestrator │
│ (Rust) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ OCI Manager │
│ │
│ - LRU caching │
│ - Pull artifacts│
│ - List packages │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ OCI Client │
│ (Distribution) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ OCI Registry │
│ (HTTP API v2) │
└──────────────────┘
Features
1. KCL Package Management
Pull KCL configuration packages from OCI registry:
let package_path = oci_manager.pull_kcl_package(
"provisioning-core",
"1.0.0"
).await?;
2. Extension Artifacts
Pull extension artifacts (providers, taskservs, clusters):
let artifact_path = oci_manager.pull_extension_artifact(
"taskserv", // Extension type
"kubernetes", // Extension name
"1.28.0" // Version
).await?;
3. Manifest Caching
Manifests are cached using LRU strategy:
- Cache size: 100 manifests
- Cache key:
{name}:{version} - Automatic eviction: Oldest entries removed when full
4. Artifact Listing
List all artifacts in a namespace:
let artifacts = oci_manager.list_oci_artifacts("kcl").await?;
for artifact in artifacts {
println!("{} v{} ({})", artifact.name, artifact.version, artifact.size);
}
OCI Distribution Spec v2
Implements OCI Distribution Specification v2:
- Manifest retrieval:
GET /v2/{namespace}/{repository}/manifests/{reference} - Blob download:
GET /v2/{namespace}/{repository}/blobs/{digest} - Tag listing:
GET /v2/{namespace}/{repository}/tags/list - Artifact existence:
HEAD /v2/{namespace}/{repository}/manifests/{reference}
Configuration
OCI settings in config.defaults.toml:
[orchestrator.oci]
registry_url = "http://localhost:5000"
namespace = "provisioning-extensions"
cache_dir = "{{orchestrator.paths.data_dir}}/oci-cache"
Configuration Options
- registry_url: OCI registry HTTP endpoint
- namespace: Default namespace for artifacts
- cache_dir: Local cache directory for downloaded artifacts
API Endpoints
List OCI Artifacts
POST /api/v1/oci/artifacts
Content-Type: application/json
{
"namespace": "kcl"
}
Response:
{
"success": true,
"data": [
{
"name": "provisioning-core",
"version": "1.0.0",
"digest": "sha256:abc123...",
"size": 102400,
"media_type": "application/vnd.oci.image.manifest.v1+json",
"created_at": "2025-10-06T12:00:00Z"
}
]
}
Usage Examples
Pull KCL Package
use provisioning_orchestrator::oci::OciManager;
use std::path::PathBuf;
let oci_manager = OciManager::new(
"http://localhost:5000".to_string(),
"provisioning-extensions".to_string(),
PathBuf::from("/tmp/oci-cache"),
);
// Pull KCL package
let package_path = oci_manager.pull_kcl_package(
"provisioning-core",
"1.0.0"
).await?;
println!("Package downloaded to: {}", package_path.display());
// Extract package
// tar -xzf package_path
Pull Extension Artifact
// Pull taskserv extension
let artifact_path = oci_manager.pull_extension_artifact(
"taskserv",
"kubernetes",
"1.28.0"
).await?;
// Extract and install
// tar -xzf artifact_path -C /target/path
List Artifacts
let artifacts = oci_manager.list_oci_artifacts("kcl").await?;
for artifact in artifacts {
println!("📦 {} v{}", artifact.name, artifact.version);
println!(" Size: {} bytes", artifact.size);
println!(" Digest: {}", artifact.digest);
println!();
}
Check Artifact Exists
let exists = oci_manager.artifact_exists(
"kcl/provisioning-core",
"1.0.0"
).await?;
if exists {
println!("Artifact exists in registry");
} else {
println!("Artifact not found");
}
Get Manifest (with caching)
let manifest = oci_manager.get_manifest(
"kcl/provisioning-core",
"1.0.0"
).await?;
println!("Schema version: {}", manifest.schema_version);
println!("Media type: {}", manifest.media_type);
println!("Layers: {}", manifest.layers.len());
Clear Manifest Cache
oci_manager.clear_cache().await;
OCI Artifact Structure
Manifest Format
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:abc123...",
"size": 1234
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:def456...",
"size": 102400
}
],
"annotations": {
"org.opencontainers.image.created": "2025-10-06T12:00:00Z",
"org.opencontainers.image.version": "1.0.0"
}
}
Integration with Workflows
Extension Installation with OCI
- Check local cache
- Pull from OCI registry (if not cached)
- Extract artifact
- Validate contents
- Install extension
// Workflow: Install taskserv from OCI
async fn install_taskserv_from_oci(
oci_manager: &OciManager,
name: &str,
version: &str
) -> Result<()> {
// Pull artifact
let artifact_path = oci_manager.pull_extension_artifact(
"taskserv",
name,
version
).await?;
// Extract
extract_tarball(&artifact_path, &target_dir)?;
// Validate
validate_extension_structure(&target_dir)?;
// Install
install_extension(&target_dir)?;
Ok(())
}
Cache Management
Cache Directory Structure
/tmp/oci-cache/
├── kcl/
│ └── provisioning-core/
│ └── 1.0.0/
│ └── package.tar.gz
├── extensions/
│ ├── taskserv/
│ │ └── kubernetes/
│ │ └── 1.28.0/
│ │ └── artifact.tar.gz
│ └── provider/
│ └── aws/
│ └── 2.0.0/
│ └── artifact.tar.gz
Cache Cleanup
Implement cache cleanup strategy:
// Clean old artifacts
async fn cleanup_old_artifacts(cache_dir: &Path, max_age_days: u64) -> Result<()> {
let cutoff = Utc::now() - Duration::days(max_age_days as i64);
for entry in std::fs::read_dir(cache_dir)? {
let entry = entry?;
let metadata = entry.metadata()?;
if let Ok(modified) = metadata.modified() {
let modified: DateTime<Utc> = modified.into();
if modified < cutoff {
std::fs::remove_dir_all(entry.path())?;
}
}
}
Ok(())
}
Error Handling
The OCI integration handles errors gracefully:
- Network errors: Retries with exponential backoff
- Manifest not found: Returns clear error message
- Corrupted downloads: Validates digest before returning
- Disk full: Reports storage error
Testing
Run OCI integration tests:
cd provisioning/platform/orchestrator
cargo test test_oci_integration
Troubleshooting
Artifact pull fails
- Check OCI registry is accessible
- Verify
registry_urlconfiguration - Check network connectivity
- Verify artifact exists in registry
- Review orchestrator logs
Digest mismatch
- Clear local cache
- Re-pull artifact
- Verify registry integrity
- Check for network corruption
Cache issues
- Check cache directory permissions
- Verify disk space
- Clear cache manually if corrupted
Best Practices
- Use specific versions: Always specify version for production
- Verify digests: Validate artifact integrity
- Cache management: Implement cleanup strategy
- Error handling: Handle network failures gracefully
- Monitor downloads: Track download times and failures
Security Considerations
- TLS/HTTPS: Use secure registry connections in production
- Authentication: Implement registry authentication
- Digest verification: Always verify artifact digests
- Access control: Restrict registry access
- Audit logging: Log all pull operations
Performance
Download Optimization
- Parallel layers: Download layers in parallel
- Resume support: Resume interrupted downloads
- Compression: Use gzip for smaller transfers
- Local cache: Cache frequently used artifacts
Metrics
Track OCI operations:
- Pull count: Number of artifact pulls
- Cache hits: Percentage of cache hits
- Download time: Average download duration
- Bandwidth usage: Total bytes downloaded
Future Enhancements
- Push artifacts to registry
- Registry authentication (OAuth2, Basic Auth)
- Multi-registry support
- Mirror/proxy registry
- Artifact signing and verification
- Garbage collection for cache