feat: agentctl reload — subcomando de hot-reload via SIGHUP
Nuevo subcomando: agentctl reload [agent-id] - Sin argumento: elimina run/reload.txt y envía SIGHUP → todos los agentes se recargan. - Con agent-id: escribe run/reload.txt con el ID y envía SIGHUP → solo ese agente se recarga. Si el launcher no está corriendo, muestra error claro. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ func main() {
|
|||||||
listCmd(mgr),
|
listCmd(mgr),
|
||||||
startCmd(mgr, &binPath),
|
startCmd(mgr, &binPath),
|
||||||
stopCmd(mgr),
|
stopCmd(mgr),
|
||||||
|
reloadCmd(mgr),
|
||||||
removeCmd(mgr),
|
removeCmd(mgr),
|
||||||
avatarCmd(),
|
avatarCmd(),
|
||||||
displaynameCmd(),
|
displaynameCmd(),
|
||||||
@@ -171,6 +173,48 @@ func stopCmd(mgr *process.Manager) *cobra.Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── reload ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
func reloadCmd(mgr *process.Manager) *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "reload [agent-id]",
|
||||||
|
Short: "Hot-reload an agent (or all agents) without stopping the launcher",
|
||||||
|
Long: `Sends SIGHUP to the running launcher, which triggers a hot-reload.
|
||||||
|
If an agent-id is given, only that agent is reloaded.
|
||||||
|
If no agent-id is given, all agents are reloaded.
|
||||||
|
|
||||||
|
The launcher must be running. Use 'agentctl start' first if needed.`,
|
||||||
|
Args: cobra.MaximumNArgs(1),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
pid := mgr.UnifiedPID()
|
||||||
|
if pid <= 0 {
|
||||||
|
return fmt.Errorf("launcher is not running")
|
||||||
|
}
|
||||||
|
|
||||||
|
target := ""
|
||||||
|
if len(args) == 1 {
|
||||||
|
target = args[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if target != "" {
|
||||||
|
if err := os.WriteFile("run/reload.txt", []byte(target), 0o644); err != nil {
|
||||||
|
return fmt.Errorf("write reload target: %w", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("reload %-20s sending SIGHUP to PID %d\n", target, pid)
|
||||||
|
} else {
|
||||||
|
// Remove any stale reload.txt so SIGHUP reloads all agents.
|
||||||
|
_ = os.Remove("run/reload.txt")
|
||||||
|
fmt.Printf("reload %-20s sending SIGHUP to PID %d\n", "(all)", pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := syscall.Kill(pid, syscall.SIGHUP); err != nil {
|
||||||
|
return fmt.Errorf("kill -HUP %d: %w", pid, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── remove ────────────────────────────────────────────────────────────────
|
// ── remove ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func removeCmd(mgr *process.Manager) *cobra.Command {
|
func removeCmd(mgr *process.Manager) *cobra.Command {
|
||||||
|
|||||||
Reference in New Issue
Block a user