provisioning/scripts/libs/os/svc.nu

335 lines
8.3 KiB
Text

#!/usr/bin/env nu
# Service management abstraction
# Provides OS-agnostic service operations (enable, start, stop, status, etc.)
use std
use ./detect.nu as os_detect
# Helper: Result type
def ok [value: any] { {ok: $value, err: null} }
def err [message: string] { {ok: null, err: $message} }
def is-ok [result: record] { $result.err == null }
# Enable service (start on boot)
export def enable [service: string] {
# GUARD: Validate input
if ($service | is-empty) {
return (err "service name cannot be empty")
}
let current_os = (os_detect detect)
let result = match $current_os {
"debian" | "ubuntu" => {
(^systemctl enable $service 2>&1 | complete)
}
"nixos" => {
err "Use NixOS modules to enable services"
}
"alpine" => {
(^rc-service $service start 2>&1 | complete)
}
"macos" => {
(^launchctl load $"/Library/LaunchDaemons/($service).plist" 2>&1 | complete)
}
_ => {
return (err $"Service enable not supported on ($current_os)")
}
}
if $result.exit_code == 0 {
ok $"Service ($service) enabled"
} else {
err $"Failed to enable ($service): ($result.stderr)"
}
}
# Disable service (prevent start on boot)
export def disable [service: string] {
# GUARD: Validate input
if ($service | is-empty) {
return (err "service name cannot be empty")
}
let current_os = (os_detect detect)
let result = match $current_os {
"debian" | "ubuntu" => {
(^systemctl disable $service 2>&1 | complete)
}
"nixos" => {
err "Use NixOS modules to disable services"
}
"alpine" => {
(^rc-update del $service default 2>&1 | complete)
}
"macos" => {
(^launchctl unload $"/Library/LaunchDaemons/($service).plist" 2>&1 | complete)
}
_ => {
return (err $"Service disable not supported on ($current_os)")
}
}
if $result.exit_code == 0 {
ok $"Service ($service) disabled"
} else {
err $"Failed to disable ($service): ($result.stderr)"
}
}
# Start service (immediately)
export def start [service: string] {
# GUARD: Validate input
if ($service | is-empty) {
return (err "service name cannot be empty")
}
let current_os = (os_detect detect)
let result = match $current_os {
"debian" | "ubuntu" => {
(^systemctl start $service 2>&1 | complete)
}
"nixos" => {
(^systemctl start $service 2>&1 | complete)
}
"alpine" => {
(^rc-service $service start 2>&1 | complete)
}
"macos" => {
(^launchctl start $service 2>&1 | complete)
}
_ => {
return (err $"Service start not supported on ($current_os)")
}
}
if $result.exit_code == 0 {
ok $"Service ($service) started"
} else {
err $"Failed to start ($service): ($result.stderr)"
}
}
# Stop service
export def stop [service: string] {
# GUARD: Validate input
if ($service | is-empty) {
return (err "service name cannot be empty")
}
let current_os = (os_detect detect)
let result = match $current_os {
"debian" | "ubuntu" => {
(^systemctl stop $service 2>&1 | complete)
}
"nixos" => {
(^systemctl stop $service 2>&1 | complete)
}
"alpine" => {
(^rc-service $service stop 2>&1 | complete)
}
"macos" => {
(^launchctl stop $service 2>&1 | complete)
}
_ => {
return (err $"Service stop not supported on ($current_os)")
}
}
if $result.exit_code == 0 {
ok $"Service ($service) stopped"
} else {
err $"Failed to stop ($service): ($result.stderr)"
}
}
# Restart service
export def restart [service: string] {
# GUARD: Validate input
if ($service | is-empty) {
return (err "service name cannot be empty")
}
let current_os = (os_detect detect)
let result = match $current_os {
"debian" | "ubuntu" => {
(^systemctl restart $service 2>&1 | complete)
}
"nixos" => {
(^systemctl restart $service 2>&1 | complete)
}
"alpine" => {
(^rc-service $service restart 2>&1 | complete)
}
"macos" => {
(^launchctl stop $service 2>&1 | complete)
(^launchctl start $service 2>&1 | complete)
}
_ => {
return (err $"Service restart not supported on ($current_os)")
}
}
if $result.exit_code == 0 {
ok $"Service ($service) restarted"
} else {
err $"Failed to restart ($service): ($result.stderr)"
}
}
# Get service status
export def status [service: string] {
# GUARD: Validate input
if ($service | is-empty) {
return (err "service name cannot be empty")
}
let current_os = (os_detect detect)
let status_output = match $current_os {
"debian" | "ubuntu" => {
let status_result = (^systemctl status $service 2>&1 | complete)
$status_result.stdout
}
"nixos" => {
let status_result = (^systemctl status $service 2>&1 | complete)
$status_result.stdout
}
"alpine" => {
let status_result = (^rc-service $service status 2>&1 | complete)
$status_result.stdout
}
"macos" => {
let status_result = (^launchctl list $service 2>&1 | complete)
$status_result.stdout
}
_ => {
return (err $"Service status not supported on ($current_os)")
}
}
ok ($status_output | str trim)
}
# Check if service is running
export def is-running [service: string] {
# GUARD: Validate input
if ($service | is-empty) {
return (err "service name cannot be empty")
}
let current_os = (os_detect detect)
let is_running = match $current_os {
"debian" | "ubuntu" => {
(^systemctl is-active $service 2>&1 | complete).exit_code == 0
}
"nixos" => {
(^systemctl is-active $service 2>&1 | complete).exit_code == 0
}
"alpine" => {
(^rc-service $service status 2>&1 | complete).exit_code == 0
}
"macos" => {
let list_result = (^launchctl list $service 2>&1 | complete)
$list_result.exit_code == 0
}
_ => {
return (err $"Service check not supported on ($current_os)")
}
}
ok $is_running
}
# Reload service configuration (for services that support it)
export def reload [service: string] {
# GUARD: Validate input
if ($service | is-empty) {
return (err "service name cannot be empty")
}
let current_os = (os_detect detect)
let result = match $current_os {
"debian" | "ubuntu" => {
(^systemctl reload $service 2>&1 | complete)
}
"nixos" => {
(^systemctl reload $service 2>&1 | complete)
}
"alpine" => {
# Alpine doesn't have reload, use restart
(^rc-service $service restart 2>&1 | complete)
}
"macos" => {
# macOS doesn't have reload, use restart
(^launchctl stop $service 2>&1 | complete)
(^launchctl start $service 2>&1 | complete)
}
_ => {
return (err $"Service reload not supported on ($current_os)")
}
}
if $result.exit_code == 0 {
ok $"Service ($service) reloaded"
} else {
err $"Failed to reload ($service): ($result.stderr)"
}
}
# Main: Show usage
export def main [] {
print "Service management abstraction library"
print ""
print "Usage:"
print " svc enable <service>"
print " svc disable <service>"
print " svc start <service>"
print " svc stop <service>"
print " svc restart <service>"
print " svc reload <service>"
print " svc status <service>"
print " svc is-running <service>"
print ""
print "Supported OS: debian, ubuntu, alpine, nixos, macos"
print ""
print "Note: NixOS services are defined via configuration.nix, not imperatively"
}