148 lines
4.2 KiB
Go
148 lines
4.2 KiB
Go
package lifecycle
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
agentctl "github.com/kandev/kandev/internal/agentctl/client"
|
|
)
|
|
|
|
type StartProcessRequest struct {
|
|
SessionID string
|
|
Kind string
|
|
ScriptName string
|
|
Command string
|
|
WorkingDir string
|
|
Env map[string]string
|
|
}
|
|
|
|
func (m *Manager) StartProcess(ctx context.Context, req StartProcessRequest) (*agentctl.ProcessInfo, error) {
|
|
if req.SessionID == "" {
|
|
return nil, fmt.Errorf("session_id is required")
|
|
}
|
|
execution, ok := m.executionStore.GetBySessionID(req.SessionID)
|
|
if !ok {
|
|
return nil, fmt.Errorf("no execution found for session %s", req.SessionID)
|
|
}
|
|
client := execution.GetAgentCtlClient()
|
|
if client == nil {
|
|
return nil, fmt.Errorf("agentctl client not available for session %s", req.SessionID)
|
|
}
|
|
|
|
return client.StartProcess(ctx, agentctl.StartProcessRequest{
|
|
SessionID: req.SessionID,
|
|
Kind: agentctl.ProcessKind(req.Kind),
|
|
ScriptName: req.ScriptName,
|
|
Command: req.Command,
|
|
WorkingDir: req.WorkingDir,
|
|
Env: req.Env,
|
|
})
|
|
}
|
|
|
|
// WaitForAgentctlReadyForSession waits for agentctl to be ready for a session.
|
|
func (m *Manager) WaitForAgentctlReadyForSession(ctx context.Context, sessionID string) error {
|
|
if sessionID == "" {
|
|
return fmt.Errorf("session_id is required")
|
|
}
|
|
execution, ok := m.executionStore.GetBySessionID(sessionID)
|
|
if !ok {
|
|
return fmt.Errorf("no execution found for session %s", sessionID)
|
|
}
|
|
client := execution.GetAgentCtlClient()
|
|
if client == nil {
|
|
return fmt.Errorf("agentctl client not available for session %s", sessionID)
|
|
}
|
|
return client.WaitForReady(ctx, 10*time.Second)
|
|
}
|
|
|
|
func (m *Manager) StopProcess(ctx context.Context, processID string) error {
|
|
if processID == "" {
|
|
return fmt.Errorf("process_id is required")
|
|
}
|
|
for _, exec := range m.executionStore.List() {
|
|
client := exec.GetAgentCtlClient()
|
|
if client == nil {
|
|
continue
|
|
}
|
|
if err := client.StopProcess(ctx, processID); err == nil {
|
|
return nil
|
|
}
|
|
}
|
|
return fmt.Errorf("process not found: %s", processID)
|
|
}
|
|
|
|
// StopProcessForSession stops a running process by ID within a specific session.
|
|
func (m *Manager) StopProcessForSession(ctx context.Context, sessionID, processID string) error {
|
|
if sessionID == "" {
|
|
return fmt.Errorf("session_id is required")
|
|
}
|
|
if processID == "" {
|
|
return fmt.Errorf("process_id is required")
|
|
}
|
|
execution, ok := m.executionStore.GetBySessionID(sessionID)
|
|
if !ok {
|
|
return fmt.Errorf("no execution found for session %s", sessionID)
|
|
}
|
|
client := execution.GetAgentCtlClient()
|
|
if client == nil {
|
|
return fmt.Errorf("agentctl client not available for session %s", sessionID)
|
|
}
|
|
return client.StopProcess(ctx, processID)
|
|
}
|
|
|
|
func (m *Manager) ListProcesses(ctx context.Context, sessionID string) ([]agentctl.ProcessInfo, error) {
|
|
if sessionID == "" {
|
|
return nil, fmt.Errorf("session_id is required")
|
|
}
|
|
execution, ok := m.executionStore.GetBySessionID(sessionID)
|
|
if !ok {
|
|
return nil, fmt.Errorf("no execution found for session %s", sessionID)
|
|
}
|
|
client := execution.GetAgentCtlClient()
|
|
if client == nil {
|
|
return nil, fmt.Errorf("agentctl client not available for session %s", sessionID)
|
|
}
|
|
return client.ListProcesses(ctx, sessionID)
|
|
}
|
|
|
|
func (m *Manager) GetProcess(ctx context.Context, processID string, includeOutput bool) (*agentctl.ProcessInfo, error) {
|
|
if processID == "" {
|
|
return nil, fmt.Errorf("process_id is required")
|
|
}
|
|
for _, exec := range m.executionStore.List() {
|
|
if exec.GetAgentCtlClient() == nil {
|
|
continue
|
|
}
|
|
proc, err := exec.GetAgentCtlClient().GetProcess(ctx, processID, includeOutput)
|
|
if err == nil {
|
|
return proc, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("process not found: %s", processID)
|
|
}
|
|
|
|
// StopAllProcesses attempts to stop all running processes across all executions.
|
|
func (m *Manager) StopAllProcesses(ctx context.Context) error {
|
|
executions := m.executionStore.List()
|
|
var errs []error
|
|
for _, exec := range executions {
|
|
client := exec.GetAgentCtlClient()
|
|
if client == nil {
|
|
continue
|
|
}
|
|
procs, err := client.ListProcesses(ctx, exec.SessionID)
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
continue
|
|
}
|
|
for _, proc := range procs {
|
|
if err := client.StopProcess(ctx, proc.ID); err != nil {
|
|
errs = append(errs, err)
|
|
}
|
|
}
|
|
}
|
|
return errors.Join(errs...)
|
|
}
|