ceremonyclient/client/cmd/node/service.go
2025-04-07 10:11:03 -08:00

285 lines
8.4 KiB
Go

package node
import (
"fmt"
"os"
"os/exec"
"github.com/spf13/cobra"
"source.quilibrium.com/quilibrium/monorepo/client/utils"
)
// nodeServiceCmd represents the command to manage the Quilibrium node service
var nodeServiceCmd = &cobra.Command{
Use: "service [command]",
Short: "Manage the Quilibrium node service",
Long: `Manage the Quilibrium node service.
Available commands:
start Start the node service
stop Stop the node service
restart Restart the node service
status Check the status of the node service
enable Enable the node service to start on boot
disable Disable the node service from starting on boot
install Install the service for the current OS
Examples:
# Start the node service
qclient node service start
# Check service status
qclient node service status
# Enable service to start on boot
qclient node service enable`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
command := args[0]
switch command {
case "start":
startService()
case "stop":
stopService()
case "restart":
restartService()
case "status":
checkServiceStatus()
case "enable":
enableService()
case "disable":
disableService()
case "reload":
reloadService()
case "install":
installService()
default:
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command)
fmt.Fprintf(os.Stderr, "Available commands: start, stop, restart, status, enable, disable, reload, install\n")
os.Exit(1)
}
},
}
// installService installs the appropriate service configuration for the current OS
func installService() {
if err := utils.CheckAndRequestSudo("Installing service requires root privileges"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
fmt.Fprintf(os.Stdout, "Installing Quilibrium node service for %s...\n", osType)
if osType == "darwin" {
installMacOSService()
} else if osType == "linux" {
if err := createSystemdServiceFile(); err != nil {
fmt.Fprintf(os.Stderr, "Error creating systemd service file: %v\n", err)
return
}
} else {
fmt.Fprintf(os.Stderr, "Error: Unsupported operating system: %s\n", osType)
return
}
fmt.Fprintf(os.Stdout, "Quilibrium node service installed successfully\n")
}
// startService starts the Quilibrium node service
func startService() {
if err := utils.CheckAndRequestSudo("Starting service requires root privileges"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
if osType == "darwin" {
// MacOS launchd command
cmd := exec.Command("sudo", "launchctl", "start", fmt.Sprintf("com.quilibrium.%s", serviceName))
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error starting service: %v\n", err)
return
}
} else {
// Linux systemd command
cmd := exec.Command("sudo", "systemctl", "start", serviceName)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error starting service: %v\n", err)
return
}
}
fmt.Fprintf(os.Stdout, "Started Quilibrium node service\n")
}
// stopService stops the Quilibrium node service
func stopService() {
if err := utils.CheckAndRequestSudo("Stopping service requires root privileges"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
if osType == "darwin" {
// MacOS launchd command
cmd := exec.Command("sudo", "launchctl", "stop", fmt.Sprintf("com.quilibrium.%s", serviceName))
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error stopping service: %v\n", err)
return
}
} else {
// Linux systemd command
cmd := exec.Command("sudo", "systemctl", "stop", serviceName)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error stopping service: %v\n", err)
return
}
}
fmt.Fprintf(os.Stdout, "Stopped Quilibrium node service\n")
}
// restartService restarts the Quilibrium node service
func restartService() {
if err := utils.CheckAndRequestSudo("Restarting service requires root privileges"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
if osType == "darwin" {
// MacOS launchd command - stop then start
stopCmd := exec.Command("sudo", "launchctl", "stop", fmt.Sprintf("com.quilibrium.%s", serviceName))
if err := stopCmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error stopping service: %v\n", err)
return
}
startCmd := exec.Command("sudo", "launchctl", "start", fmt.Sprintf("com.quilibrium.%s", serviceName))
if err := startCmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error starting service: %v\n", err)
return
}
} else {
// Linux systemd command
cmd := exec.Command("sudo", "systemctl", "restart", serviceName)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error restarting service: %v\n", err)
return
}
}
fmt.Fprintf(os.Stdout, "Restarted Quilibrium node service\n")
}
// reloadService reloads the Quilibrium node service
func reloadService() {
if err := utils.CheckAndRequestSudo("Reloading service requires root privileges"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
if osType == "darwin" {
// MacOS launchd command - unload then load
plistPath := fmt.Sprintf("/Library/LaunchDaemons/com.quilibrium.%s.plist", serviceName)
unloadCmd := exec.Command("sudo", "launchctl", "unload", plistPath)
if err := unloadCmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error unloading service: %v\n", err)
return
}
loadCmd := exec.Command("sudo", "launchctl", "load", plistPath)
if err := loadCmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error loading service: %v\n", err)
return
}
fmt.Fprintf(os.Stdout, "Reloaded launchd service\n")
} else {
// Linux systemd command
cmd := exec.Command("sudo", "systemctl", "daemon-reload")
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error reloading service: %v\n", err)
return
}
fmt.Fprintf(os.Stdout, "Reloaded systemd service\n")
}
}
// checkServiceStatus checks the status of the Quilibrium node service
func checkServiceStatus() {
if err := utils.CheckAndRequestSudo("Checking service status requires root privileges"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
if osType == "darwin" {
// MacOS launchd command
cmd := exec.Command("sudo", "launchctl", "list", fmt.Sprintf("com.quilibrium.%s", serviceName))
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error checking service status: %v\n", err)
}
} else {
// Linux systemd command
cmd := exec.Command("sudo", "systemctl", "status", serviceName)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error checking service status: %v\n", err)
}
}
}
// enableService enables the Quilibrium node service to start on boot
func enableService() {
if err := utils.CheckAndRequestSudo("Enabling service requires root privileges"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
if osType == "darwin" {
// MacOS launchd command - load with -w flag to enable at boot
plistPath := fmt.Sprintf("/Library/LaunchDaemons/com.quilibrium.%s.plist", serviceName)
cmd := exec.Command("sudo", "launchctl", "load", "-w", plistPath)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error enabling service: %v\n", err)
return
}
} else {
// Linux systemd command
cmd := exec.Command("sudo", "systemctl", "enable", serviceName)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error enabling service: %v\n", err)
return
}
}
fmt.Fprintf(os.Stdout, "Enabled Quilibrium node service to start on boot\n")
}
// disableService disables the Quilibrium node service from starting on boot
func disableService() {
if err := utils.CheckAndRequestSudo("Disabling service requires root privileges"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
if osType == "darwin" {
// MacOS launchd command - unload with -w flag to disable at boot
plistPath := fmt.Sprintf("/Library/LaunchDaemons/com.quilibrium.%s.plist", serviceName)
cmd := exec.Command("sudo", "launchctl", "unload", "-w", plistPath)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error disabling service: %v\n", err)
return
}
} else {
// Linux systemd command
cmd := exec.Command("sudo", "systemctl", "disable", serviceName)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error disabling service: %v\n", err)
return
}
}
fmt.Fprintf(os.Stdout, "Disabled Quilibrium node service from starting on boot\n")
}