20 KiB
Multi-Repository Architecture with OCI Registry Support
Version: 1.0.0 Date: 2025-10-06 Status: Implementation Complete
Overview
This document describes the multi-repository architecture for the provisioning system, enabling modular development, independent versioning, and distributed extension management through OCI registry integration.
Architecture Goals
- Separation of Concerns: Core, Extensions, and Platform in separate repositories
- Independent Versioning: Each component can be versioned and released independently
- Distributed Development: Multiple teams can work on different repositories
- OCI-Native Distribution: Extensions distributed as OCI artifacts
- Dependency Management: Automated dependency resolution across repositories
- Backward Compatibility: Support legacy monorepo structure during transition
Repository Structure
Repository 1: provisioning-core
Purpose: Core system functionality - CLI, libraries, base schemas
provisioning-core/
├── core/
│ ├── cli/ # Command-line interface
│ │ ├── provisioning # Main CLI entry point
│ │ └── module-loader # Dynamic module loader
│ ├── nulib/ # Core Nushell libraries
│ │ ├── lib_provisioning/ # Core library modules
│ │ │ ├── config/ # Configuration management
│ │ │ ├── oci/ # OCI client integration
│ │ │ ├── dependencies/ # Dependency resolution
│ │ │ ├── module/ # Module system
│ │ │ ├── layer/ # Layer system
│ │ │ └── workspace/ # Workspace management
│ │ └── workflows/ # Core workflow system
│ ├── plugins/ # System plugins
│ └── scripts/ # Utility scripts
├── schemas/ # Base Nickel schemas
│ ├── main.ncl # Main schema entry
│ ├── lib.ncl # Core library types
│ ├── settings.ncl # Settings schema
│ ├── dependencies.ncl # Dependency schemas (with OCI support)
│ ├── server.ncl # Server schemas
│ ├── cluster.ncl # Cluster schemas
│ └── workflows.ncl # Workflow schemas
├── config/ # Core configuration templates
├── templates/ # Core templates
├── tools/ # Build and distribution tools
│ ├── oci-package.nu # OCI packaging tool
│ ├── build-core.nu # Core build script
│ └── release-core.nu # Core release script
├── tests/ # Core system tests
└── docs/ # Core documentation
├── api/ # API documentation
├── architecture/ # Architecture docs
└── development/ # Development guides
Distribution:
- Published as OCI artifact:
oci://registry/provisioning-core:v3.5.0 - Contains all core functionality needed to run the provisioning system
- Version format:
v{major}.{minor}.{patch}(for example, v3.5.0)
CI/CD:
- Build on commit to main
- Publish OCI artifact on git tag (v*)
- Run integration tests before publishing
- Update changelog automatically
Repository 2: provisioning-extensions
Purpose: All provider, taskserv, and cluster extensions
provisioning-extensions/
├── providers/
│ ├── aws/
│ │ ├── schemas/ # Nickel schemas
│ │ │ ├── manifest.toml # Nickel dependencies
│ │ │ ├── aws.ncl # Main provider schema
│ │ │ ├── defaults_aws.ncl # AWS defaults
│ │ │ └── server_aws.ncl # AWS server schema
│ │ ├── scripts/ # Nushell scripts
│ │ │ └── install.nu # Installation script
│ │ ├── templates/ # Provider templates
│ │ ├── docs/ # Provider documentation
│ │ └── manifest.yaml # Extension manifest
│ ├── upcloud/
│ │ └── (same structure)
│ └── local/
│ └── (same structure)
├── taskservs/
│ ├── kubernetes/
│ │ ├── schemas/
│ │ │ ├── manifest.toml
│ │ │ ├── kubernetes.ncl # Main taskserv schema
│ │ │ ├── version.ncl # Version management
│ │ │ └── dependencies.ncl # Taskserv dependencies
│ │ ├── scripts/
│ │ │ ├── install.nu # Installation script
│ │ │ ├── check.nu # Health check script
│ │ │ └── uninstall.nu # Uninstall script
│ │ ├── templates/ # Config templates
│ │ ├── docs/ # Taskserv docs
│ │ ├── tests/ # Taskserv tests
│ │ └── manifest.yaml # Extension manifest
│ ├── containerd/
│ ├── cilium/
│ ├── postgres/
│ └── (50+ more taskservs...)
├── clusters/
│ ├── buildkit/
│ │ └── (same structure)
│ ├── web/
│ └── (other clusters...)
├── tools/
│ ├── extension-builder.nu # Build individual extensions
│ ├── mass-publish.nu # Publish all extensions
│ └── validate-extensions.nu # Validate all extensions
└── docs/
├── extension-guide.md # Extension development guide
└── publishing.md # Publishing guide
Distribution: Each extension published separately as OCI artifact:
oci://registry/provisioning-extensions/kubernetes:1.28.0oci://registry/provisioning-extensions/aws:2.0.0oci://registry/provisioning-extensions/buildkit:0.12.0
Extension Manifest (manifest.yaml):
name: kubernetes
type: taskserv
version: 1.28.0
description: Kubernetes container orchestration platform
author: Provisioning Team
license: MIT
homepage: https://kubernetes.io
repository: https://gitea.example.com/provisioning-extensions/kubernetes
dependencies:
containerd: ">=1.7.0"
etcd: ">=3.5.0"
tags:
- kubernetes
- container-orchestration
- cncf
platforms:
- linux/amd64
- linux/arm64
min_provisioning_version: "3.0.0"
CI/CD:
- Build and publish each extension independently
- Git tag format:
{extension-type}/{extension-name}/v{version}- Example:
taskservs/kubernetes/v1.28.0
- Example:
- Automated publishing to OCI registry on tag
- Run extension-specific tests before publishing
Repository 3: provisioning-platform
Purpose: Platform services (orchestrator, control-center, MCP server, API gateway)
provisioning-platform/
├── orchestrator/ # Rust orchestrator service
│ ├── src/
│ ├── Cargo.toml
│ ├── Dockerfile
│ └── README.md
├── control-center/ # Web control center
│ ├── src/
│ ├── package.json
│ ├── Dockerfile
│ └── README.md
├── mcp-server/ # Model Context Protocol server
│ ├── src/
│ ├── Cargo.toml
│ ├── Dockerfile
│ └── README.md
├── api-gateway/ # REST API gateway
│ ├── src/
│ ├── Cargo.toml
│ ├── Dockerfile
│ └── README.md
├── docker-compose.yml # Local development stack
├── kubernetes/ # K8s deployment manifests
│ ├── orchestrator.yaml
│ ├── control-center.yaml
│ ├── mcp-server.yaml
│ └── api-gateway.yaml
└── docs/
├── deployment.md
└── api-reference.md
Distribution: Standard Docker images in OCI registry:
oci://registry/provisioning-platform/orchestrator:v1.2.0oci://registry/provisioning-platform/control-center:v1.2.0oci://registry/provisioning-platform/mcp-server:v1.0.0oci://registry/provisioning-platform/api-gateway:v1.0.0
CI/CD:
- Build Docker images on commit to main
- Publish images on git tag (v*)
- Multi-architecture builds (amd64, arm64)
- Security scanning before publishing
OCI Registry Integration
Registry Structure
OCI Registry (localhost:5000 or harbor.company.com)
├── provisioning-core/
│ ├── v3.5.0 # Core system artifact
│ ├── v3.4.0
│ └── latest -> v3.5.0
├── provisioning-extensions/
│ ├── kubernetes:1.28.0 # Individual extension artifacts
│ ├── kubernetes:1.27.0
│ ├── containerd:1.7.0
│ ├── aws:2.0.0
│ ├── upcloud:1.5.0
│ └── (100+ more extensions)
└── provisioning-platform/
├── orchestrator:v1.2.0 # Platform service images
├── control-center:v1.2.0
├── mcp-server:v1.0.0
└── api-gateway:v1.0.0
OCI Artifact Structure
Each extension packaged as OCI artifact:
kubernetes-1.28.0.tar.gz
├── schemas/ # Nickel schemas
│ ├── kubernetes.ncl
│ ├── version.ncl
│ └── dependencies.ncl
├── scripts/ # Nushell scripts
│ ├── install.nu
│ ├── check.nu
│ └── uninstall.nu
├── templates/ # Template files
│ ├── kubeconfig.j2
│ └── kubelet-config.yaml.j2
├── docs/ # Documentation
│ └── README.md
├── manifest.yaml # Extension manifest
└── oci-manifest.json # OCI manifest metadata
Dependency Management
Workspace Configuration
File: workspace/config/provisioning.yaml
# Core system dependency
dependencies:
core:
source: "oci://harbor.company.com/provisioning-core:v3.5.0"
# Alternative: source: "gitea://provisioning-core"
# Extensions repository configuration
extensions:
source_type: "oci" # oci, gitea, local
# OCI registry configuration
oci:
registry: "localhost:5000"
namespace: "provisioning-extensions"
tls_enabled: false
auth_token_path: "~/.provisioning/tokens/oci"
# Loaded extension modules
modules:
providers:
- "oci://localhost:5000/provisioning-extensions/aws:2.0.0"
- "oci://localhost:5000/provisioning-extensions/upcloud:1.5.0"
taskservs:
- "oci://localhost:5000/provisioning-extensions/kubernetes:1.28.0"
- "oci://localhost:5000/provisioning-extensions/containerd:1.7.0"
- "oci://localhost:5000/provisioning-extensions/cilium:1.14.0"
clusters:
- "oci://localhost:5000/provisioning-extensions/buildkit:0.12.0"
# Platform services
platform:
source_type: "oci"
oci:
registry: "harbor.company.com"
namespace: "provisioning-platform"
images:
orchestrator: "harbor.company.com/provisioning-platform/orchestrator:v1.2.0"
control_center: "harbor.company.com/provisioning-platform/control-center:v1.2.0"
# OCI registry configuration
registry:
type: "oci" # oci, gitea, http
oci:
endpoint: "localhost:5000"
namespaces:
extensions: "provisioning-extensions"
nickel: "provisioning-nickel"
platform: "provisioning-platform"
test: "provisioning-test"
Dependency Resolution
The system resolves dependencies in this order:
- Parse Configuration: Read
provisioning.yamland extract dependencies - Resolve Core: Ensure core system version is compatible
- Resolve Extensions: For each extension:
- Check if already installed and version matches
- Pull from OCI registry if needed
- Recursively resolve extension dependencies
- Validate Graph: Check for dependency cycles and conflicts
- Install: Install extensions in topological order
Dependency Resolution Commands
# Resolve and install all dependencies
provisioning dep resolve
# Check for dependency updates
provisioning dep check-updates
# Update specific extension
provisioning dep update kubernetes
# Validate dependency graph
provisioning dep validate
# Show dependency tree
provisioning dep tree kubernetes
OCI Client Operations
CLI Commands
# Pull extension from OCI registry
provisioning oci pull kubernetes:1.28.0
# Push extension to OCI registry
provisioning oci push ./extensions/kubernetes kubernetes 1.28.0
# List available extensions
provisioning oci list --namespace provisioning-extensions
# Search for extensions
provisioning oci search kubernetes
# Show extension versions
provisioning oci tags kubernetes
# Inspect extension manifest
provisioning oci inspect kubernetes:1.28.0
# Login to OCI registry
provisioning oci login localhost:5000 --username _token --password-stdin
# Delete extension
provisioning oci delete kubernetes:1.28.0
# Copy extension between registries
provisioning oci copy \
localhost:5000/provisioning-extensions/kubernetes:1.28.0 \
harbor.company.com/provisioning-extensions/kubernetes:1.28.0
OCI Configuration
# Show OCI configuration
provisioning oci config
# Output:
{
tool: "oras" # or "crane" or "skopeo"
registry: "localhost:5000"
namespace: {
extensions: "provisioning-extensions"
platform: "provisioning-platform"
}
cache_dir: "~/.provisioning/oci-cache"
tls_enabled: false
}
Extension Development Workflow
1. Develop Extension
# Create new extension from template
provisioning generate extension taskserv redis
# Directory structure created:
# extensions/taskservs/redis/
# ├── schemas/
# │ ├── manifest.toml
# │ ├── redis.ncl
# │ ├── version.ncl
# │ └── dependencies.ncl
# ├── scripts/
# │ ├── install.nu
# │ ├── check.nu
# │ └── uninstall.nu
# ├── templates/
# ├── docs/
# │ └── README.md
# ├── tests/
# └── manifest.yaml
2. Test Extension Locally
# Load extension from local path
provisioning module load taskserv workspace_dev redis --source local
# Test installation
provisioning taskserv create redis --infra test-env --check
# Run extension tests
provisioning test extension redis
3. Package Extension
# Validate extension structure
provisioning oci package validate ./extensions/taskservs/redis
# Package as OCI artifact
provisioning oci package ./extensions/taskservs/redis
# Output: redis-1.0.0.tar.gz
4. Publish Extension
# Login to registry (one-time)
provisioning oci login localhost:5000
# Publish extension
provisioning oci push ./extensions/taskservs/redis redis 1.0.0
# Verify publication
provisioning oci tags redis
# Output:
# ┬───────────┬─────────┬───────────────────────────────────────────────────┐
# │ artifact │ version │ reference │
# ├───────────┼─────────┼───────────────────────────────────────────────────┤
# │ redis │ 1.0.0 │ localhost:5000/provisioning-extensions/redis:1.0.0│
# └───────────┴─────────┴───────────────────────────────────────────────────┘
5. Use Published Extension
# Add to workspace configuration
# workspace/config/provisioning.yaml:
# dependencies:
# extensions:
# modules:
# taskservs:
# - "oci://localhost:5000/provisioning-extensions/redis:1.0.0"
# Pull and install
provisioning dep resolve
# Extension automatically downloaded and installed
Registry Deployment Options
Local Registry (Solo Development)
Using Zot (lightweight OCI registry):
# Start local OCI registry
provisioning oci-registry start
# Configuration:
# - Endpoint: localhost:5000
# - Storage: ~/.provisioning/oci-registry/
# - No authentication by default
# - TLS disabled (local only)
# Stop registry
provisioning oci-registry stop
# Check status
provisioning oci-registry status
Remote Registry (Multi-User/Enterprise)
Using Harbor:
# workspace/config/provisioning.yaml
dependencies:
registry:
type: "oci"
oci:
endpoint: "https://harbor.company.com"
namespaces:
extensions: "provisioning/extensions"
platform: "provisioning/platform"
tls_enabled: true
auth_token_path: "~/.provisioning/tokens/harbor"
Features:
- Multi-user authentication
- Role-based access control (RBAC)
- Vulnerability scanning
- Replication across registries
- Webhook notifications
- Image signing (cosign/notation)
Migration from Monorepo
Phase 1: Parallel Structure (Current)
- Monorepo still exists and works
- OCI distribution layer added on top
- Extensions can be loaded from local or OCI
- No breaking changes
Phase 2: Gradual Migration
# Migrate extensions one by one
for ext in (ls provisioning/extensions/taskservs); do
provisioning oci publish $ext.name
done
# Update workspace configurations to use OCI
provisioning workspace migrate-to-oci workspace_prod
Phase 3: Repository Split
-
Create
provisioning-corerepository- Extract core/ and schemas/ directories
- Set up CI/CD for core publishing
- Publish initial OCI artifact
-
Create
provisioning-extensionsrepository- Extract extensions/ directory
- Set up CI/CD for extension publishing
- Publish all extensions to OCI registry
-
Create
provisioning-platformrepository- Extract platform/ directory
- Set up Docker image builds
- Publish platform services
-
Update workspaces
- Reconfigure to use OCI dependencies
- Test multi-repo setup
- Verify all functionality works
Phase 4: Deprecate Monorepo
- Archive monorepo
- Redirect to new repositories
- Update documentation
- Announce migration complete
Benefits Summary
Modularity
✅ Independent repositories for core, extensions, and platform ✅ Extensions can be developed and versioned separately ✅ Clear ownership and responsibility boundaries
Distribution
✅ OCI-native distribution (industry standard) ✅ Built-in versioning with OCI tags ✅ Efficient caching with OCI layers ✅ Works with standard tools (skopeo, crane, oras)
Security
✅ TLS support for registries ✅ Authentication and authorization ✅ Vulnerability scanning (Harbor) ✅ Image signing (cosign, notation) ✅ RBAC for access control
Developer Experience
✅ Simple CLI commands for extension management ✅ Automatic dependency resolution ✅ Local testing before publishing ✅ Easy extension discovery and installation
Operations
✅ Air-gapped deployments (mirror OCI registry) ✅ Bandwidth efficient (only download what's needed) ✅ Version pinning for reproducibility ✅ Rollback support (use previous versions)
Ecosystem
✅ Compatible with existing OCI tooling ✅ Can use public registries (DockerHub, GitHub, etc.) ✅ Mirror to multiple registries ✅ Replication for high availability
Implementation Status
| Component | Status | Notes |
|---|---|---|
| Nickel Schemas | ✅ Complete | OCI schemas in dependencies.ncl |
| OCI Client | ✅ Complete | oci/client.nu with skopeo/crane/oras |
| OCI Commands | ✅ Complete | oci/commands.nu CLI interface |
| Dependency Resolver | ✅ Complete | dependencies/resolver.nu |
| OCI Packaging | ✅ Complete | tools/oci-package.nu |
| Repository Design | ✅ Complete | This document |
| Migration Plan | ✅ Complete | Phased approach defined |
| Documentation | ✅ Complete | User guides and API docs |
| CI/CD Setup | ⏳ Pending | Automated publishing pipelines |
| Registry Deployment | ⏳ Pending | Zot/Harbor setup |
Related Documentation
- OCI Packaging Tool - Extension packaging
- OCI Client Library - OCI operations
- Dependency Resolver - Dependency management
- Nickel Schemas - Type definitions
- Extension Development Guide - How to create extensions
Maintained By: Architecture Team Review Cycle: Quarterly Next Review: 2026-01-06