Allow start/stop/restart to target a single component via <service>/<component> syntax, matching deploy/logs/purge. When a component is specified, start/stop skip toggling the service-level active flag. Agent-side filtering returns NotFound for unknown components. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
164 lines
4.0 KiB
Go
164 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
mcpv1 "git.wntrmute.dev/mc/mcp/gen/mcp/v1"
|
|
"git.wntrmute.dev/mc/mcp/internal/config"
|
|
"git.wntrmute.dev/mc/mcp/internal/servicedef"
|
|
)
|
|
|
|
func stopCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "stop <service>[/<component>]",
|
|
Short: "Stop components (or all), set active=false",
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
cfg, err := config.LoadCLIConfig(cfgPath)
|
|
if err != nil {
|
|
return fmt.Errorf("load config: %w", err)
|
|
}
|
|
|
|
serviceName, component := parseServiceArg(args[0])
|
|
defPath := filepath.Join(cfg.Services.Dir, serviceName+".toml")
|
|
|
|
def, err := servicedef.Load(defPath)
|
|
if err != nil {
|
|
return fmt.Errorf("load service def: %w", err)
|
|
}
|
|
|
|
// Only flip active=false when stopping the whole service.
|
|
if component == "" {
|
|
active := false
|
|
def.Active = &active
|
|
if err := servicedef.Write(defPath, def); err != nil {
|
|
return fmt.Errorf("write service def: %w", err)
|
|
}
|
|
}
|
|
|
|
address, err := findNodeAddress(cfg, def.Node)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
client, conn, err := dialAgent(address, cfg)
|
|
if err != nil {
|
|
return fmt.Errorf("dial agent: %w", err)
|
|
}
|
|
defer func() { _ = conn.Close() }()
|
|
|
|
resp, err := client.StopService(context.Background(), &mcpv1.StopServiceRequest{
|
|
Name: serviceName,
|
|
Component: component,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("stop service: %w", err)
|
|
}
|
|
|
|
printComponentResults(resp.GetResults())
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func startCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "start <service>[/<component>]",
|
|
Short: "Start components (or all), set active=true",
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
cfg, err := config.LoadCLIConfig(cfgPath)
|
|
if err != nil {
|
|
return fmt.Errorf("load config: %w", err)
|
|
}
|
|
|
|
serviceName, component := parseServiceArg(args[0])
|
|
defPath := filepath.Join(cfg.Services.Dir, serviceName+".toml")
|
|
|
|
def, err := servicedef.Load(defPath)
|
|
if err != nil {
|
|
return fmt.Errorf("load service def: %w", err)
|
|
}
|
|
|
|
// Only flip active=true when starting the whole service.
|
|
if component == "" {
|
|
active := true
|
|
def.Active = &active
|
|
if err := servicedef.Write(defPath, def); err != nil {
|
|
return fmt.Errorf("write service def: %w", err)
|
|
}
|
|
}
|
|
|
|
address, err := findNodeAddress(cfg, def.Node)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
client, conn, err := dialAgent(address, cfg)
|
|
if err != nil {
|
|
return fmt.Errorf("dial agent: %w", err)
|
|
}
|
|
defer func() { _ = conn.Close() }()
|
|
|
|
resp, err := client.StartService(context.Background(), &mcpv1.StartServiceRequest{
|
|
Name: serviceName,
|
|
Component: component,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("start service: %w", err)
|
|
}
|
|
|
|
printComponentResults(resp.GetResults())
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func restartCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "restart <service>[/<component>]",
|
|
Short: "Restart components (or all)",
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
cfg, err := config.LoadCLIConfig(cfgPath)
|
|
if err != nil {
|
|
return fmt.Errorf("load config: %w", err)
|
|
}
|
|
|
|
serviceName, component := parseServiceArg(args[0])
|
|
defPath := filepath.Join(cfg.Services.Dir, serviceName+".toml")
|
|
|
|
def, err := servicedef.Load(defPath)
|
|
if err != nil {
|
|
return fmt.Errorf("load service def: %w", err)
|
|
}
|
|
|
|
address, err := findNodeAddress(cfg, def.Node)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
client, conn, err := dialAgent(address, cfg)
|
|
if err != nil {
|
|
return fmt.Errorf("dial agent: %w", err)
|
|
}
|
|
defer func() { _ = conn.Close() }()
|
|
|
|
resp, err := client.RestartService(context.Background(), &mcpv1.RestartServiceRequest{
|
|
Name: serviceName,
|
|
Component: component,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("restart service: %w", err)
|
|
}
|
|
|
|
printComponentResults(resp.GetResults())
|
|
return nil
|
|
},
|
|
}
|
|
}
|