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