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

370 lines
9.2 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OCI Registry Management Commands
use ../config/loader.nu get-config
# Start OCI registry
export def "oci-registry start" [
--type: string = "zot" # zot, harbor, distribution
--config: string
--detach (-d)
] {
print $"🚀 Starting OCI registry \(($type)\)..."
let registry_path = get-registry-path $type
if not ($registry_path | path exists) {
error make {
msg: $"Registry path not found: ($registry_path)"
}
}
cd $registry_path
let compose_file = if ($config | is-empty) {
"docker-compose.yml"
} else {
$config
}
let flags = if $detach { ["-d"] } else { [] }
^docker-compose -f $compose_file up ...$flags
if $detach {
print "✅ Registry started in background"
print $" Use 'oci-registry logs --type ($type)' to view logs"
print $" Use 'oci-registry status --type ($type)' to check status"
}
}
# Stop OCI registry
export def "oci-registry stop" [
--type: string = "zot"
--remove-volumes (-v)
] {
print $"🛑 Stopping OCI registry \(($type)\)..."
let registry_path = get-registry-path $type
cd $registry_path
let flags = if $remove_volumes { ["-v"] } else { [] }
^docker-compose down ...$flags
print "✅ Registry stopped"
}
# Get registry status
export def "oci-registry status" [
--type: string = "zot"
--format: string = "table" # table, json
] -> any {
let registry_path = get-registry-path $type
cd $registry_path
let containers = (^docker-compose ps --format json | from json)
match $format {
"json" => {
$containers
}
"table" => {
$containers | select Name State Status
}
_ => {
$containers | select Name State Status
}
}
}
# Initialize registry (create namespaces, policies)
export def "oci-registry init" [
--type: string = "zot"
--registry-url: string = "localhost:5000"
--admin-password: string = "admin"
--skip-test
] {
let script_path = $"(get-oci-registry-root)/scripts/init-registry.nu"
let args = [
"--registry-type" $type
"--registry-url" $registry_url
"--admin-password" $admin_password
]
let args = if $skip_test {
$args | append ["--skip-test"]
} else {
$args
}
nu $script_path ...$args
}
# Configure registry setting
export def "oci-registry configure" [
--type: string = "zot"
setting: string
value: string
] {
print $"⚙️ Configuring ($setting) = ($value)..."
match $type {
"zot" => {
configure-zot-setting $setting $value
}
"harbor" => {
configure-harbor-setting $setting $value
}
"distribution" => {
configure-distribution-setting $setting $value
}
_ => {
error make {
msg: $"Unknown registry type: ($type)"
}
}
}
}
# Get registry logs
export def "oci-registry logs" [
--type: string = "zot"
--follow (-f)
--tail: int = 100
] {
let registry_path = get-registry-path $type
cd $registry_path
let flags = if $follow {
["--follow", "--tail", ($tail | into string)]
} else {
["--tail", ($tail | into string)]
}
^docker-compose logs ...$flags
}
# Health check
export def "oci-registry health" [
--type: string = "zot"
--registry-url: string = "localhost:5000"
] -> record {
print "🏥 Checking registry health..."
let api_check = check-api-health $registry_url
let catalog_check = check-catalog-health $registry_url
let metrics_check = check-metrics-health $registry_url $type
let overall = $api_check.healthy and $catalog_check.healthy
{
healthy: $overall
api: $api_check
catalog: $catalog_check
metrics: $metrics_check
timestamp: (date now | format date "%Y-%m-%d %H:%M:%S")
}
}
# Push test image
export def "oci-registry test-push" [
--registry-url: string = "localhost:5000"
] {
print "🧪 Pushing test image..."
# Pull hello-world
^docker pull hello-world:latest
# Tag for our registry
^docker tag hello-world:latest $"($registry_url)/provisioning-test/hello:latest"
# Push to registry
^docker push $"($registry_url)/provisioning-test/hello:latest"
print "✅ Test image pushed successfully"
}
# Pull test image
export def "oci-registry test-pull" [
--registry-url: string = "localhost:5000"
] {
print "🧪 Pulling test image..."
^docker pull $"($registry_url)/provisioning-test/hello:latest"
print "✅ Test image pulled successfully"
}
# List namespaces
export def "oci-registry namespaces" [
--registry-url: string = "localhost:5000"
--type: string = "zot"
] -> table {
let result = (do {
http get $"http://($registry_url)/v2/_catalog"
} | complete)
if $result.exit_code != 0 {
error make {
msg: $"Failed to fetch catalog: ($result.stderr)"
}
}
let repos = ($result.stdout | from json | get repositories)
let namespaces = ($repos | each { |repo|
$repo | split row "/" | first
} | uniq)
$namespaces | each { |ns|
let repo_count = ($repos | where { |r| $r | str starts-with $ns } | length)
{
namespace: $ns
repositories: $repo_count
}
}
}
# Create namespace
export def "oci-registry namespace create" [
name: string
--registry-url: string = "localhost:5000"
--type: string = "zot"
] {
print $"📦 Creating namespace: ($name)..."
match $type {
"zot" => {
print " Namespace will be created on first push"
}
"harbor" => {
create-harbor-namespace $registry_url $name
}
"distribution" => {
print " Namespace will be created on first push"
}
_ => {
error make {
msg: $"Unknown registry type: ($type)"
}
}
}
}
# Delete namespace
export def "oci-registry namespace delete" [
name: string
--registry-url: string = "localhost:5000"
--type: string = "zot"
--force
] {
if not $force {
let confirm = (input $"⚠️ Delete namespace '($name)'? This will remove all images. \(y/N\): ")
if $confirm != "y" {
print "Cancelled"
return
}
}
print $"🗑️ Deleting namespace: ($name)..."
match $type {
"harbor" => {
delete-harbor-namespace $registry_url $name
}
_ => {
print $" ⚠ Namespace deletion not supported for ($type)"
print " Delete all images manually and run garbage collection"
}
}
}
# Helper functions
def get-registry-path [type: string] -> string {
let root = get-oci-registry-root
$"($root)/($type)"
}
def get-oci-registry-root [] -> string {
let config = (get-config)
let base_path = ($config | get paths.base)
$"($base_path)/provisioning/platform/oci-registry"
}
def check-api-health [registry_url: string] -> record {
let result = (do {
http get $"http://($registry_url)/v2/" --timeout 5sec
} | complete)
{
healthy: ($result.exit_code == 0)
message: (if $result.exit_code == 0 { "OK" } else { $result.stderr })
}
}
def check-catalog-health [registry_url: string] -> record {
let result = (do {
http get $"http://($registry_url)/v2/_catalog" --timeout 5sec
} | complete)
{
healthy: ($result.exit_code == 0)
message: (if $result.exit_code == 0 { "OK" } else { $result.stderr })
}
}
def check-metrics-health [registry_url: string, type: string] -> record {
let metrics_url = match $type {
"zot" => $"http://($registry_url)/metrics"
"distribution" => $"http://($registry_url):5001/metrics"
_ => null
}
if ($metrics_url | is-empty) {
return {
healthy: false
message: "Metrics not supported"
}
}
let result = (do {
http get $metrics_url --timeout 5sec
} | complete)
{
healthy: ($result.exit_code == 0)
message: (if $result.exit_code == 0 { "OK" } else { "Not available" })
}
}
def configure-zot-setting [setting: string, value: string] {
print " Zot configuration requires editing config.json and restarting"
print $" Setting: ($setting)"
print $" Value: ($value)"
}
def configure-harbor-setting [setting: string, value: string] {
print " Harbor configuration via API not fully implemented"
print $" Setting: ($setting)"
print $" Value: ($value)"
}
def configure-distribution-setting [setting: string, value: string] {
print " Distribution configuration requires editing config.yml and restarting"
print $" Setting: ($setting)"
print $" Value: ($value)"
}
def create-harbor-namespace [registry_url: string, name: string] {
print " Harbor project creation requires authentication"
print $" Run: oci-registry init --type harbor"
}
def delete-harbor-namespace [registry_url: string, name: string] {
print " Harbor project deletion requires authentication"
print $" Use Harbor UI or API with admin credentials"
}