516 lines
13 KiB
Markdown
Raw Permalink Normal View History

2025-10-07 10:32:04 +01:00
# Extension Loading System
**Version**: 1.0.0
**Status**: Implemented
**Date**: 2025-10-06
## Overview
A comprehensive extension loading mechanism with OCI registry support, lazy loading, caching, and version resolution. Supports loading extensions from multiple sources: OCI registries, Gitea repositories, and local filesystems.
## Architecture
```
Extension Loading System
├── OCI Client (oci/client.nu)
│ ├── Artifact pull/push operations
│ ├── Registry authentication
│ └── Manifest management
├── Cache System (cache.nu)
│ ├── Local artifact caching
│ ├── Cache index management
│ └── Automatic pruning
├── Loader (loader_oci.nu)
│ ├── Multi-source loading
│ ├── Lazy loading
│ └── Automatic source detection
├── Version Resolution (versions.nu)
│ ├── Semver parsing and comparison
│ ├── Constraint satisfaction (^, ~, ranges)
│ └── OCI tag resolution
├── Discovery (discovery.nu)
│ ├── Multi-source discovery
│ ├── Extension search
│ └── Metadata extraction
└── CLI Commands (commands.nu)
├── Load, search, list
├── Cache management
└── Publishing
```
## Features
### 1. Multi-Source Support
Load extensions from:
- **OCI Registry**: Container artifact registry (localhost:5000 by default)
- **Gitea**: Git repository hosting (planned)
- **Local**: Filesystem paths
### 2. Lazy Loading
Extensions are loaded on-demand:
1. Check if already in memory → return
2. Check cache → load from cache
3. Determine source (auto-detect or explicit)
4. Download from source
5. Cache locally
6. Load into memory
### 3. OCI Registry Integration
Full OCI artifact support:
- Pull artifacts with authentication
- Push extensions to registry
- List and search artifacts
- Version tag management
- Manifest metadata extraction
### 4. Caching System
Intelligent local caching:
- Cache directory: `~/.provisioning/cache/extensions/{type}/{name}/{version}/`
- Cache index: JSON-based index for fast lookups
- Automatic pruning: Remove old cached versions
- Statistics: Track cache size and usage
### 5. Version Resolution
Semver-compliant version resolution:
- **Exact**: `1.2.3` → exactly version 1.2.3
- **Caret**: `^1.2.0` → >=1.2.0 <2.0.0 (compatible)
- **Tilde**: `~1.2.0` → >=1.2.0 <1.3.0 (approximately)
- **Range**: `1.2.0-1.5.0` → between versions
- **Latest**: `*` or `latest` → highest version
### 6. Discovery & Search
Multi-source extension discovery:
- Discover all extensions across sources
- Search by name or type
- Filter by extension type (provider, taskserv, cluster)
- Get available versions
## Configuration
### OCI Registry Configuration
Add to workspace config (`workspace/config/local-overrides.toml`):
```toml
[oci]
registry = "localhost:5000"
namespace = "provisioning-extensions"
auth_token_path = "~/.provisioning/oci-token"
insecure = false
timeout = 300
retry_count = 3
[extensions]
source_type = "auto" # auto, oci, gitea, local
```
### Environment Variables
- `PROVISIONING_OCI_REGISTRY`: Override OCI registry
- `PROVISIONING_OCI_NAMESPACE`: Override namespace
- `PROVISIONING_EXTENSIONS_PATH`: Additional extension paths
## CLI Usage
### Load Extension
```bash
# Load latest from auto-detected source
provisioning ext load kubernetes
# Load specific version from OCI
provisioning ext load kubernetes --version 1.28.0 --source oci
# Force reload
provisioning ext load kubernetes --force
# Load provider
provisioning ext load aws --type provider
```
### Search Extensions
```bash
# Search all sources
provisioning ext search kubernetes
# Search OCI registry only
provisioning ext search kubernetes --source oci
# Search local only
provisioning ext search kube --source local
```
### List Extensions
```bash
# List all extensions
provisioning ext list
# Filter by type
provisioning ext list --type taskserv
# JSON output
provisioning ext list --format json
# List from specific source
provisioning ext list --source oci
```
### Extension Information
```bash
# Show extension info
provisioning ext info kubernetes
# Show specific version
provisioning ext info kubernetes --version 1.28.0
# Show versions
provisioning ext versions kubernetes
```
### Cache Management
```bash
# List cached extensions
provisioning ext cache list
# Show cache statistics
provisioning ext cache stats
# Clear cache for specific extension
provisioning ext cache clear --type taskserv --name kubernetes
# Clear all cache
provisioning ext cache clear --all
# Prune old entries (older than 30 days)
provisioning ext cache prune --days 30
```
### Pull to Cache
```bash
# Pull without loading
provisioning ext pull kubernetes --version 1.28.0
# Pull from specific source
provisioning ext pull redis --source oci
```
### Publishing
```bash
# Publish to OCI registry
provisioning ext publish ./my-extension --version 1.0.0
# Publish to specific registry
provisioning ext publish ./my-extension \
--version 1.0.0 \
--registry localhost:5000 \
--namespace my-namespace
# Force overwrite existing
provisioning ext publish ./my-extension --version 1.0.0 --force
```
### Discovery
```bash
# Discover all extensions
provisioning ext discover
# Filter by type
provisioning ext discover --type taskserv
# Force refresh
provisioning ext discover --refresh
```
### Test OCI Connection
```bash
# Test OCI registry connectivity
provisioning ext test-oci
```
## Publishing Tool Usage
The standalone publishing tool provides additional commands:
```bash
# Publish extension
nu provisioning/tools/publish_extension.nu ./my-extension --version 1.0.0
# Dry run (validate without publishing)
nu provisioning/tools/publish_extension.nu ./my-extension --version 1.0.0 --dry-run
# List published extensions
nu provisioning/tools/publish_extension.nu list
# Show extension info
nu provisioning/tools/publish_extension.nu info kubernetes 1.28.0
# Delete extension
nu provisioning/tools/publish_extension.nu delete kubernetes 1.28.0 --force
```
## Extension Structure
### Required Files
```
my-extension/
├── extension.yaml # Manifest (required)
├── kcl/ # KCL schemas (optional)
│ ├── my-extension.k
│ └── kcl.mod
├── scripts/ # Scripts (optional)
│ └── install.nu
├── templates/ # Templates (optional)
│ └── config.yaml.j2
└── docs/ # Documentation (optional)
└── README.md
```
### Extension Manifest (extension.yaml)
```yaml
extension:
name: my-extension
version: 1.0.0
type: taskserv # provider, taskserv, cluster
description: My awesome extension
author: Your Name <you@example.com>
requires:
- docker
- kubernetes
dependencies:
- containerd
- etcd
metadata:
homepage: https://example.com
repository: https://github.com/user/extension
license: MIT
```
## API Reference
### OCI Client (oci/client.nu)
| Function | Description |
|----------|-------------|
| `oci-pull-artifact` | Pull artifact from OCI registry |
| `oci-push-artifact` | Push artifact to OCI registry |
| `oci-list-artifacts` | List all artifacts in registry |
| `oci-get-artifact-tags` | Get tags for artifact |
| `oci-get-artifact-manifest` | Get manifest for artifact |
| `oci-artifact-exists` | Check if artifact exists |
| `oci-delete-artifact` | Delete artifact from registry |
| `is-oci-available` | Check OCI registry availability |
| `test-oci-connection` | Test connection and auth |
### Cache System (cache.nu)
| Function | Description |
|----------|-------------|
| `get-from-cache` | Get extension from cache |
| `save-oci-to-cache` | Save OCI artifact to cache |
| `save-gitea-to-cache` | Save Gitea artifact to cache |
| `remove-from-cache` | Remove from cache |
| `clear-cache` | Clear entire cache or specific type |
| `list-cached` | List cached extensions |
| `get-cache-stats` | Get cache statistics |
| `prune-cache` | Remove old cache entries |
### Loader (loader_oci.nu)
| Function | Description |
|----------|-------------|
| `load-extension` | Load extension from any source |
### Version Resolution (versions.nu)
| Function | Description |
|----------|-------------|
| `resolve-version` | Resolve version from spec |
| `resolve-oci-version` | Resolve from OCI tags |
| `is-semver` | Check if valid semver |
| `compare-semver` | Compare two versions |
| `sort-by-semver` | Sort versions |
| `get-latest-version` | Get latest from list |
| `satisfies-constraint` | Check constraint satisfaction |
### Discovery (discovery.nu)
| Function | Description |
|----------|-------------|
| `discover-oci-extensions` | Discover OCI extensions |
| `discover-local-extensions` | Discover local extensions |
| `discover-all-extensions` | Discover from all sources |
| `search-extensions` | Search extensions |
| `list-extensions` | List with formatting |
| `get-extension-versions` | Get available versions |
| `get-oci-extension-metadata` | Get OCI metadata |
## Testing
Run the test suite:
```bash
# Run all tests
nu provisioning/core/nulib/lib_provisioning/extensions/tests/run_all_tests.nu
# Run specific test suite
nu provisioning/core/nulib/lib_provisioning/extensions/tests/run_all_tests.nu --suite oci
nu provisioning/core/nulib/lib_provisioning/extensions/tests/run_all_tests.nu --suite cache
nu provisioning/core/nulib/lib_provisioning/extensions/tests/run_all_tests.nu --suite versions
nu provisioning/core/nulib/lib_provisioning/extensions/tests/run_all_tests.nu --suite discovery
# Run individual test
nu provisioning/core/nulib/lib_provisioning/extensions/tests/test_oci_client.nu
nu provisioning/core/nulib/lib_provisioning/extensions/tests/test_cache.nu
nu provisioning/core/nulib/lib_provisioning/extensions/tests/test_versions.nu
nu provisioning/core/nulib/lib_provisioning/extensions/tests/test_discovery.nu
```
## Integration Examples
### Example 1: Load Taskserv from OCI
```nushell
use lib_provisioning/extensions/loader_oci.nu load-extension
let result = (load-extension "taskserv" "kubernetes" "^1.28.0" --source-type "oci")
if $result.success {
print $"Loaded kubernetes:($result.version) from ($result.source)"
} else {
print $"Failed: ($result.error)"
}
```
### Example 2: Discover and Cache All Extensions
```nushell
use lib_provisioning/extensions/discovery.nu discover-all-extensions
use lib_provisioning/extensions/loader_oci.nu load-extension
let extensions = (discover-all-extensions --include-oci)
for ext in $extensions {
print $"Caching ($ext.name):($ext.latest)..."
load-extension $ext.type $ext.name $ext.latest
}
```
### Example 3: Version Resolution
```nushell
use lib_provisioning/extensions/versions.nu resolve-oci-version
let version = (resolve-oci-version "taskserv" "kubernetes" "^1.28.0")
print $"Resolved to: ($version)"
```
## Troubleshooting
### OCI Registry Not Reachable
```bash
# Test connection
provisioning ext test-oci
# Check config
provisioning env | grep OCI
# Verify registry is running
curl http://localhost:5000/v2/
```
### Extension Not Found
```bash
# Search all sources
provisioning ext search <name>
# Check specific source
provisioning ext list --source oci
provisioning ext list --source local
# Discover with refresh
provisioning ext discover --refresh
```
### Cache Issues
```bash
# Check cache stats
provisioning ext cache stats
# Clear and rebuild
provisioning ext cache clear --all
# Prune old entries
provisioning ext cache prune --days 7
```
### Version Resolution Issues
```bash
# Check available versions
provisioning ext versions <extension-name>
# Try explicit version
provisioning ext load <name> --version 1.2.3
# Force reload
provisioning ext load <name> --force
```
## Performance Considerations
- **Lazy Loading**: Extensions loaded on-demand, not at startup
- **Caching**: Downloaded artifacts cached locally for fast access
- **Parallel Discovery**: Multiple sources discovered concurrently
- **Index-Based Lookup**: Cache index for O(1) lookups
## Security
- **Token-Based Auth**: OCI registry authentication via tokens
- **Manifest Validation**: Extension structure validated before loading
- **Permission Checks**: Extension permission policies enforced
- **Secure Defaults**: HTTPS for registries (HTTP only for localhost)
## Future Enhancements
- [ ] Gitea source implementation
- [ ] Digital signature verification
- [ ] Multi-registry support
- [ ] Extension dependency resolution
- [ ] Automatic updates
- [ ] Extension sandboxing
- [ ] WebAssembly extensions
- [ ] Extension marketplace UI
## Contributing
See main project contributing guidelines. Extension system follows:
- Nushell idiomatic patterns
- PAP (Project Architecture Principles)
- KCL idiomatic patterns for schemas
## License
Same as main project.