173 lines
4.9 KiB
Text
173 lines
4.9 KiB
Text
# Runner daemon handler — list/destroy/pin/unpin/status via lian-build daemon HTTP API.
|
|
|
|
const DAEMON_DEFAULT_URL = "http://localhost:14150"
|
|
|
|
def daemon-url []: nothing -> string {
|
|
$env.LIAN_BUILD_DAEMON_URL? | default $DAEMON_DEFAULT_URL
|
|
}
|
|
|
|
def format-runner [r: record]: nothing -> record {
|
|
let ttl = if $r.lifecycle.ttl_minutes == 0 { "—" } else { $"($r.lifecycle.ttl_minutes)m" }
|
|
let sched = $r.lifecycle.destroy_at? | default "—"
|
|
{
|
|
id: ($r.id | str substring 0..<8)
|
|
workspace: $r.workspace
|
|
host: $"($r.ssh_host):($r.ssh_port)"
|
|
status: $r.status
|
|
pin: $r.lifecycle.pin
|
|
ttl: $ttl
|
|
destroy_at: $sched
|
|
spawned_at: $r.spawned_at
|
|
}
|
|
}
|
|
|
|
def runner-list [base_url: string]: nothing -> nothing {
|
|
let rows = try {
|
|
http get $"($base_url)/runners"
|
|
} catch {
|
|
print $"error: daemon unreachable at ($base_url)"
|
|
print " Start with: lian-build serve"
|
|
return
|
|
}
|
|
|
|
if ($rows | is-empty) {
|
|
print "no active runners"
|
|
return
|
|
}
|
|
|
|
$rows | each { |r| format-runner $r } | table
|
|
}
|
|
|
|
def runner-status [base_url: string, id: string]: nothing -> nothing {
|
|
if ($id | is-empty) {
|
|
print "error: runner status requires an id (full UUID or 8-char prefix)"
|
|
exit 1
|
|
}
|
|
|
|
let rows = try {
|
|
http get $"($base_url)/runners"
|
|
} catch {
|
|
print $"error: daemon unreachable at ($base_url)"
|
|
print " Start with: lian-build serve"
|
|
return
|
|
}
|
|
|
|
let matches = $rows | where { |r| ($r.id | str starts-with $id) }
|
|
|
|
if ($matches | is-empty) {
|
|
print $"error: no runner matching id '($id)'"
|
|
exit 1
|
|
}
|
|
|
|
$matches | first | table
|
|
}
|
|
|
|
def runner-destroy [base_url: string, id: string, confirmed: bool]: nothing -> nothing {
|
|
if not $confirmed {
|
|
print $"Destroy runner ($id)? This cannot be undone."
|
|
let answer = (input "Confirm [y/N]: " | str downcase | str trim)
|
|
if $answer != "y" {
|
|
print "aborted"
|
|
return
|
|
}
|
|
}
|
|
|
|
let result = try {
|
|
http delete $"($base_url)/runners/($id)"
|
|
{ ok: true }
|
|
} catch { |e|
|
|
{ ok: false, error: ($e | get msg? | default "request failed") }
|
|
}
|
|
|
|
if $result.ok {
|
|
print $"runner ($id) queued for destruction"
|
|
} else {
|
|
print $"error: ($result.error)"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
def runner-set-pin [base_url: string, id: string, pin: bool]: nothing -> nothing {
|
|
let endpoint = if $pin { "pin" } else { "unpin" }
|
|
|
|
let result = try {
|
|
http post $"($base_url)/runners/($id)/($endpoint)" {}
|
|
{ ok: true }
|
|
} catch { |e|
|
|
{ ok: false, error: ($e | get msg? | default "request failed") }
|
|
}
|
|
|
|
if $result.ok {
|
|
let verb = if $pin { "pinned" } else { "unpinned" }
|
|
print $"runner ($id) ($verb)"
|
|
} else {
|
|
print $"error: ($result.error)"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
def runner-help []: nothing -> nothing {
|
|
print "Runner Daemon Commands"
|
|
print "======================"
|
|
print ""
|
|
print "Usage: provisioning runner <command> [options]"
|
|
print ""
|
|
print "Commands:"
|
|
print " list List active runners"
|
|
print " status <id> Show full record for a runner (prefix match)"
|
|
print " destroy <id> Destroy a runner (prompts unless --yes)"
|
|
print " pin <id> Pin runner — daemon will not auto-destroy it"
|
|
print " unpin <id> Unpin runner — daemon resumes TTL/schedule enforcement"
|
|
print ""
|
|
print "Environment:"
|
|
print $" LIAN_BUILD_DAEMON_URL Daemon base URL (default: ($DAEMON_DEFAULT_URL))"
|
|
print ""
|
|
print "Examples:"
|
|
print " provisioning runner list"
|
|
print " provisioning runner status a1b2c3d4"
|
|
print " provisioning runner destroy a1b2c3d4 --yes"
|
|
print " provisioning runner pin a1b2c3d4"
|
|
}
|
|
|
|
export def handle_runner_command [
|
|
command: string
|
|
ops: string
|
|
flags: record
|
|
]: nothing -> nothing {
|
|
let url = daemon-url
|
|
let id = ($ops | str trim)
|
|
let confirmed = ($flags.auto_confirm? | default false)
|
|
|
|
match $command {
|
|
"list" | "l" => {
|
|
runner-list $url
|
|
}
|
|
"status" | "s" => {
|
|
runner-status $url $id
|
|
}
|
|
"destroy" | "d" => {
|
|
if ($id | is-empty) {
|
|
print "error: runner destroy requires an id"
|
|
exit 1
|
|
}
|
|
runner-destroy $url $id $confirmed
|
|
}
|
|
"pin" | "p" => {
|
|
if ($id | is-empty) {
|
|
print "error: runner pin requires an id"
|
|
exit 1
|
|
}
|
|
runner-set-pin $url $id true
|
|
}
|
|
"unpin" | "u" => {
|
|
if ($id | is-empty) {
|
|
print "error: runner unpin requires an id"
|
|
exit 1
|
|
}
|
|
runner-set-pin $url $id false
|
|
}
|
|
_ => {
|
|
runner-help
|
|
}
|
|
}
|
|
}
|