provisioning-core/nulib/domain/oci_registry/service.nu

333 lines
8.4 KiB
Text
Raw Permalink Normal View History

# OCI Registry Service Integration
use ../config/loader.nu get-config
# Start registry service
export def start-oci-registry [
registry_type: string = "zot"
config_path?: string
] -> bool {
print $"Starting OCI registry service \(($registry_type)\)..."
let registry_dir = get-registry-directory $registry_type
if not ($registry_dir | path exists) {
print $"ERROR: Registry directory not found: ($registry_dir)"
return false
}
cd $registry_dir
let compose_file = if ($config_path | is-empty) {
"docker-compose.yml"
} else {
$config_path
}
let result = (^docker-compose -f $compose_file up -d | complete)
if $result.exit_code == 0 {
print "✅ Registry service started"
return true
} else {
print $"ERROR: Failed to start registry: ($result.stderr)"
return false
}
}
# Stop registry service
export def stop-oci-registry [
registry_type: string = "zot"
] -> bool {
print $"Stopping OCI registry service \(($registry_type)\)..."
let registry_dir = get-registry-directory $registry_type
if not ($registry_dir | path exists) {
print $"ERROR: Registry directory not found: ($registry_dir)"
return false
}
cd $registry_dir
let result = (^docker-compose down | complete)
if $result.exit_code == 0 {
print "✅ Registry service stopped"
return true
} else {
print $"ERROR: Failed to stop registry: ($result.stderr)"
return false
}
}
# Get registry status
export def get-oci-registry-status [
registry_type: string = "zot"
] -> record {
let registry_dir = get-registry-directory $registry_type
if not ($registry_dir | path exists) {
return {
running: false
error: "Registry directory not found"
}
}
cd $registry_dir
let result = (^docker-compose ps --format json | complete)
if $result.exit_code != 0 {
return {
running: false
error: $result.stderr
}
}
let containers = ($result.stdout | from json)
let running = ($containers | all { |c| $c.State == "running" })
{
running: $running
containers: $containers
type: $registry_type
}
}
# Check registry health
export def check-oci-registry-health [
registry_url: string
] -> bool {
let result = (do {
http get $"http://($registry_url)/v2/" --timeout 5sec
} | complete)
$result.exit_code == 0
}
# Get registry info
export def get-oci-registry-info [
registry_url: string
] -> record {
# Try to fetch catalog
let catalog_result = (do {
http get $"http://($registry_url)/v2/_catalog"
} | complete)
let catalog = if $catalog_result.exit_code == 0 {
$catalog_result.stdout | from json
} else {
{repositories: []}
}
# Count namespaces
let namespaces = ($catalog.repositories
| each { |r| $r | split row "/" | first }
| uniq
| length)
{
url: $registry_url
healthy: ($catalog_result.exit_code == 0)
repositories: ($catalog.repositories | length)
namespaces: $namespaces
timestamp: (date now | format date "%Y-%m-%d %H:%M:%S")
}
}
# Get repository list
export def get-oci-registry-repositories [
registry_url: string
] -> list {
let result = (do {
http get $"http://($registry_url)/v2/_catalog"
} | complete)
if $result.exit_code != 0 {
return []
}
let catalog = ($result.stdout | from json)
$catalog.repositories
}
# Get repository tags
export def get-oci-repository-tags [
registry_url: string
repository: string
] -> list {
let result = (do {
http get $"http://($registry_url)/v2/($repository)/tags/list"
} | complete)
if $result.exit_code != 0 {
return []
}
let tags = ($result.stdout | from json)
$tags.tags | default []
}
# Get manifest for image
export def get-oci-image-manifest [
registry_url: string
repository: string
tag: string
] -> record {
let result = (do {
http get $"http://($registry_url)/v2/($repository)/manifests/($tag)" --headers {
"Accept": "application/vnd.oci.image.manifest.v1+json"
}
} | complete)
if $result.exit_code != 0 {
return {}
}
$result.stdout | from json
}
# Delete image tag
export def delete-oci-image-tag [
registry_url: string
repository: string
tag: string
] -> bool {
# First get the manifest digest
let manifest_result = (do {
http get $"http://($registry_url)/v2/($repository)/manifests/($tag)" --headers {
"Accept": "application/vnd.oci.image.manifest.v1+json"
} --full
} | complete)
if $manifest_result.exit_code != 0 {
print $"ERROR: Failed to get manifest: ($manifest_result.stderr)"
return false
}
let manifest = ($manifest_result.stdout | from json)
let digest = ($manifest.headers | where name == "Docker-Content-Digest" | first | get value)
# Delete using digest
let delete_result = (do {
http delete $"http://($registry_url)/v2/($repository)/manifests/($digest)"
} | complete)
if $delete_result.exit_code == 0 {
print $"✅ Image ($repository):($tag) deleted"
return true
} else {
print $"ERROR: Failed to delete image: ($delete_result.stderr)"
return false
}
}
# Garbage collection (Zot)
export def run-oci-registry-gc [
registry_type: string = "zot"
] -> bool {
match $registry_type {
"zot" => {
# Zot runs GC automatically based on config
print " Zot runs garbage collection automatically"
print " Check config.json for GC settings"
return true
}
"distribution" => {
# Distribution requires manual GC
print "Running garbage collection..."
let registry_dir = get-registry-directory $registry_type
let result = (^docker-compose exec registry \
registry garbage-collect /etc/docker/registry/config.yml | complete)
if $result.exit_code == 0 {
print "✅ Garbage collection completed"
return true
} else {
print $"ERROR: GC failed: ($result.stderr)"
return false
}
}
"harbor" => {
print " Harbor runs GC via UI or API"
print " Use Harbor admin interface for GC"
return true
}
_ => {
print $"ERROR: Unknown registry type: ($registry_type)"
return false
}
}
}
# Get registry metrics (if available)
export def get-oci-registry-metrics [
registry_url: string
registry_type: string = "zot"
] -> string {
let metrics_url = match $registry_type {
"zot" => $"http://($registry_url)/metrics"
"distribution" => $"http://($registry_url):5001/metrics"
_ => null
}
if ($metrics_url | is-empty) {
return "Metrics not available for this registry type"
}
let result = (do {
http get $metrics_url
} | complete)
if $result.exit_code == 0 {
$result.stdout
} else {
$"ERROR: Failed to fetch metrics: ($result.stderr)"
}
}
# Helper: Get registry directory
def get-registry-directory [registry_type: string] -> string {
let config = (get-config)
let base_path = ($config | get paths.base)
$"($base_path)/provisioning/platform/oci-registry/($registry_type)"
}
# Push artifact to registry
export def push-oci-artifact [
registry_url: string
repository: string
tag: string
artifact_path: string
] -> bool {
if not ($artifact_path | path exists) {
print $"ERROR: Artifact not found: ($artifact_path)"
return false
}
# This would require oras or docker buildx
print " Use 'oras push' or 'docker push' to upload artifacts"
print $" Target: ($registry_url)/($repository):($tag)"
print $" Artifact: ($artifact_path)"
false
}
# Pull artifact from registry
export def pull-oci-artifact [
registry_url: string
repository: string
tag: string
output_path: string
] -> bool {
# This would require oras or docker pull
print " Use 'oras pull' or 'docker pull' to download artifacts"
print $" Source: ($registry_url)/($repository):($tag)"
print $" Output: ($output_path)"
false
}