Skip to content

Commit 19c5742

Browse files
authored
Enable groups (#1460)
1 parent 890ab5e commit 19c5742

32 files changed

+555
-980
lines changed

cmd/thv/app/client.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,10 @@ func init() {
102102
clientCmd.AddCommand(clientRemoveCmd)
103103
clientCmd.AddCommand(clientListRegisteredCmd)
104104

105-
// TODO: Re-enable when group functionality is complete
106-
//clientRegisterCmd.Flags().StringSliceVar(
107-
// &groupAddNames, "group", []string{groups.DefaultGroup}, "Only register workloads from specified groups")
108-
//clientRemoveCmd.Flags().StringSliceVar(
109-
// &groupRmNames, "group", []string{}, "Remove client from specified groups (if not set, removes all workloads from the client)")
105+
clientRegisterCmd.Flags().StringSliceVar(
106+
&groupAddNames, "group", []string{groups.DefaultGroup}, "Only register workloads from specified groups")
107+
clientRemoveCmd.Flags().StringSliceVar(
108+
&groupRmNames, "group", []string{}, "Remove client from specified groups (if not set, removes all workloads from the client)")
110109
}
111110

112111
func clientStatusCmdFunc(cmd *cobra.Command, _ []string) error {
@@ -157,11 +156,11 @@ func clientSetupCmdFunc(cmd *cobra.Command, _ []string) error {
157156
return registerSelectedClients(cmd, selectedClients, selectedGroups)
158157
}
159158

160-
// Helper to get available (installed but unregistered) clients
159+
// Helper to get available (installed) clients
161160
func getAvailableClients(statuses []client.MCPClientStatus) []client.MCPClientStatus {
162161
var available []client.MCPClientStatus
163162
for _, s := range statuses {
164-
if s.Installed && !s.Registered {
163+
if s.Installed {
165164
available = append(available, s)
166165
}
167166
}

cmd/thv/app/commands.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func NewRootCmd(enableUpdates bool) *cobra.Command {
5454
rootCmd.AddCommand(newSecretCommand())
5555
rootCmd.AddCommand(inspectorCommand())
5656
rootCmd.AddCommand(newMCPCommand())
57-
// rootCmd.AddCommand(groupCmd) // TODO: add back in once we have a working group command, and update the docs
57+
rootCmd.AddCommand(groupCmd)
5858

5959
// Silence printing the usage on error
6060
rootCmd.SilenceUsage = true

cmd/thv/app/common.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/stacklok/toolhive/pkg/config"
1010
"github.com/stacklok/toolhive/pkg/secrets"
11+
"github.com/stacklok/toolhive/pkg/validation"
1112
"github.com/stacklok/toolhive/pkg/workloads"
1213
)
1314

@@ -149,7 +150,7 @@ func completeLogsArgs(cmd *cobra.Command, args []string, _ string) ([]string, co
149150

150151
// ValidateGroupFlag returns a cobra PreRunE-compatible function
151152
// that validates the --group flag *if provided*.
152-
/*func validateGroupFlag() func(cmd *cobra.Command, args []string) error {
153+
func validateGroupFlag() func(cmd *cobra.Command, args []string) error {
153154
return func(cmd *cobra.Command, _ []string) error {
154155
groupName, err := cmd.Flags().GetString("group")
155156
if err != nil {
@@ -168,4 +169,4 @@ func completeLogsArgs(cmd *cobra.Command, args []string, _ string) ([]string, co
168169

169170
return nil
170171
}
171-
}*/
172+
}

cmd/thv/app/list.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ func init() {
3232
listCmd.Flags().BoolVarP(&listAll, "all", "a", false, "Show all workloads (default shows just running)")
3333
listCmd.Flags().StringVar(&listFormat, "format", FormatText, "Output format (json, text, or mcpservers)")
3434
listCmd.Flags().StringArrayVarP(&listLabelFilter, "label", "l", []string{}, "Filter workloads by labels (format: key=value)")
35-
// TODO: Re-enable when group functionality is complete
36-
// listCmd.Flags().StringVar(&listGroupFilter, "group", "", "Filter workloads by group")
35+
listCmd.Flags().StringVar(&listGroupFilter, "group", "", "Filter workloads by group")
3736

38-
// listCmd.PreRunE = validateGroupFlag()
37+
listCmd.PreRunE = validateGroupFlag()
3938
}
4039

4140
func listCmdFunc(cmd *cobra.Command, _ []string) error {

cmd/thv/app/restart.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,12 @@ var restartCmd = &cobra.Command{
2929
func init() {
3030
restartCmd.Flags().BoolVarP(&restartAll, "all", "a", false, "Restart all MCP servers")
3131
restartCmd.Flags().BoolVarP(&restartForeground, "foreground", "f", false, "Run the restarted workload in foreground mode")
32-
// TODO: Uncomment when groups are fully supported
33-
//restartCmd.Flags().StringVarP(&restartGroup, "group", "g", "", "Restart all MCP servers in a specific group")
34-
//
35-
//// Mark the flags as mutually exclusive
36-
//restartCmd.MarkFlagsMutuallyExclusive("all", "group")
32+
restartCmd.Flags().StringVarP(&restartGroup, "group", "g", "", "Restart all MCP servers in a specific group")
3733

38-
// restartCmd.PreRunE = validateGroupFlag()
34+
// Mark the flags as mutually exclusive
35+
restartCmd.MarkFlagsMutuallyExclusive("all", "group")
36+
37+
restartCmd.PreRunE = validateGroupFlag()
3938
}
4039

4140
func restartCmdFunc(cmd *cobra.Command, args []string) error {

cmd/thv/app/rm.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@ var rmCmd = &cobra.Command{
2020
}
2121

2222
func init() {
23-
// TODO: Re-enable when group functionality is complete
24-
// rmCmd.Flags().String("group", "", "Delete all workloads in the specified group")
23+
rmCmd.Flags().String("group", "", "Delete all workloads in the specified group")
2524

26-
// rmCmd.PreRunE = validateGroupFlag()
25+
rmCmd.PreRunE = validateGroupFlag()
2726
}
2827

2928
//nolint:gocyclo // This function is complex but manageable

cmd/thv/app/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func init() {
8282
// Add run flags
8383
AddRunFlags(runCmd, &runFlags)
8484

85-
//runCmd.PreRunE = validateGroupFlag()
85+
runCmd.PreRunE = validateGroupFlag()
8686

8787
// This is used for the K8s operator which wraps the run command, but shouldn't be visible to users.
8888
if err := runCmd.Flags().MarkHidden("k8s-pod-patch"); err != nil {

cmd/thv/app/run_flags.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,8 @@ func AddRunFlags(cmd *cobra.Command, config *RunFlags) {
9494
cmd.Flags().StringVar(&config.Transport, "transport", "", "Transport mode (sse, streamable-http or stdio)")
9595
cmd.Flags().StringVar(&config.ProxyMode, "proxy-mode", "sse", "Proxy mode for stdio transport (sse or streamable-http)")
9696
cmd.Flags().StringVar(&config.Name, "name", "", "Name of the MCP server (auto-generated from image if not provided)")
97-
// TODO: Re-enable when group functionality is complete
98-
// cmd.Flags().StringVar(&config.Group, "group", "default",
99-
// "Name of the group this workload belongs to (defaults to 'default' if not specified)")
97+
cmd.Flags().StringVar(&config.Group, "group", "default",
98+
"Name of the group this workload belongs to (defaults to 'default' if not specified)")
10099
cmd.Flags().StringVar(&config.Host, "host", transport.LocalhostIPv4, "Host for the HTTP proxy to listen on (IP or hostname)")
101100
cmd.Flags().IntVar(&config.ProxyPort, "proxy-port", 0, "Port for the HTTP proxy to listen on (host port)")
102101
cmd.Flags().IntVar(&config.TargetPort, "target-port", 0,

cmd/thv/app/stop.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,12 @@ var (
3232
func init() {
3333
stopCmd.Flags().IntVar(&stopTimeout, "timeout", 30, "Timeout in seconds before forcibly stopping the workload")
3434
stopCmd.Flags().BoolVar(&stopAll, "all", false, "Stop all running MCP servers")
35-
// TODO: Re-enable group flag when groups are implemented
36-
//stopCmd.Flags().StringVarP(&stopGroup, "group", "g", "", "Stop all MCP servers in a specific group")
37-
//
38-
//// Mark the flags as mutually exclusive
39-
//stopCmd.MarkFlagsMutuallyExclusive("all", "group")
40-
//
41-
//stopCmd.PreRunE = validateGroupFlag()
35+
stopCmd.Flags().StringVarP(&stopGroup, "group", "g", "", "Stop all MCP servers in a specific group")
36+
37+
// Mark the flags as mutually exclusive
38+
stopCmd.MarkFlagsMutuallyExclusive("all", "group")
39+
40+
stopCmd.PreRunE = validateGroupFlag()
4241
}
4342

4443
// validateStopArgs validates the arguments for the stop command

cmd/thv/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/stacklok/toolhive/pkg/client"
99
"github.com/stacklok/toolhive/pkg/container/runtime"
1010
"github.com/stacklok/toolhive/pkg/logger"
11+
"github.com/stacklok/toolhive/pkg/migration"
1112
)
1213

1314
func main() {
@@ -20,8 +21,7 @@ func main() {
2021

2122
// Check and perform default group migration if needed
2223
// Migrates existing workloads to the default group, only executes once
23-
// TODO: Re-enable when group functionality is complete
24-
//migration.CheckAndPerformDefaultGroupMigration()
24+
migration.CheckAndPerformDefaultGroupMigration()
2525

2626
// Skip update check for completion command or if we are running in kubernetes
2727
if err := app.NewRootCmd(!app.IsCompletionCommand(os.Args) && !runtime.IsKubernetesRuntime()).Execute(); err != nil {

0 commit comments

Comments
 (0)