11package app
22
33import (
4- "context"
54 "fmt"
65
76 "github.com/spf13/cobra"
87
9- "github.com/stacklok/toolhive/pkg/container"
10- rt "github.com/stacklok/toolhive/pkg/container/runtime"
11- "github.com/stacklok/toolhive/pkg/labels"
128 "github.com/stacklok/toolhive/pkg/lifecycle"
13- "github.com/stacklok/toolhive/pkg/logger"
14- "github.com/stacklok/toolhive/pkg/process"
15- "github.com/stacklok/toolhive/pkg/runner"
169)
1710
1811var restartCmd = & cobra.Command {
@@ -32,160 +25,12 @@ func restartCmdFunc(cmd *cobra.Command, args []string) error {
3225 // Get container name
3326 containerName := args [0 ]
3427
35- // Create container runtime
36- runtime , err := container . NewFactory (). Create (ctx )
28+ // Create lifecycle manager.
29+ manager , err := lifecycle . NewManager (ctx )
3730 if err != nil {
38- return fmt .Errorf ("failed to create container runtime : %v" , err )
31+ return fmt .Errorf ("failed to create lifecycle manager : %v" , err )
3932 }
4033
41- // Try to find the container ID
42- containerID , err := findContainerID (ctx , runtime , containerName )
43- var containerBaseName string
44- var running bool
45-
46- if err != nil {
47- logger .Warnf ("Warning: Failed to find container: %v" , err )
48- logger .Warnf ("Trying to find state with name %s directly..." , containerName )
49-
50- // Try to use the provided name as the base name
51- containerBaseName = containerName
52- running = false
53- } else {
54- // Container found, check if it's running
55- running , err = runtime .IsContainerRunning (ctx , containerID )
56- if err != nil {
57- return fmt .Errorf ("failed to check if container is running: %v" , err )
58- }
59-
60- // Get the base container name
61- containerBaseName , err = getContainerBaseName (ctx , runtime , containerID )
62- if err != nil {
63- logger .Warnf ("Warning: Could not find base container name in labels: %v" , err )
64- logger .Warnf ("Using provided name %s as base name" , containerName )
65- containerBaseName = containerName
66- }
67- }
68-
69- // Check if the proxy process is running
70- proxyRunning := isProxyRunning (containerBaseName )
71-
72- if running && proxyRunning {
73- logger .Infof ("Container %s and proxy are already running" , containerName )
74- return nil
75- }
76-
77- // If the container is running but the proxy is not, stop the container first
78- if containerID != "" && running && ! proxyRunning {
79- logger .Infof ("Container %s is running but proxy is not. Stopping container..." , containerName )
80- if err := runtime .StopContainer (ctx , containerID ); err != nil {
81- return fmt .Errorf ("failed to stop container: %v" , err )
82- }
83- logger .Infof ("Container %s stopped" , containerName )
84- }
85-
86- // Load the configuration from the state store
87- mcpRunner , err := loadRunnerFromState (ctx , containerBaseName , runtime )
88- if err != nil {
89- return fmt .Errorf ("failed to load state for %s: %v" , containerBaseName , err )
90- }
91-
92- logger .Infof ("Loaded configuration from state for %s" , containerBaseName )
93-
94- // Run the tooling server
95- logger .Infof ("Starting tooling server %s..." , containerName )
96- return RunMCPServer (ctx , mcpRunner .Config , false )
97- }
98-
99- // isProxyRunning checks if the proxy process is running
100- func isProxyRunning (containerBaseName string ) bool {
101- if containerBaseName == "" {
102- return false
103- }
104-
105- // Try to read the PID file
106- pid , err := process .ReadPIDFile (containerBaseName )
107- if err != nil {
108- return false
109- }
110-
111- // Check if the process exists and is running
112- isRunning , err := process .FindProcess (pid )
113- if err != nil {
114- logger .Warnf ("Warning: Error checking process: %v" , err )
115- return false
116- }
117-
118- return isRunning
119- }
120-
121- // loadRunnerFromState attempts to load a Runner from the state store
122- func loadRunnerFromState (ctx context.Context , baseName string , runtime rt.Runtime ) (* runner.Runner , error ) {
123- // Load the runner from the state store
124- r , err := runner .LoadState (ctx , baseName )
125- if err != nil {
126- return nil , err
127- }
128-
129- // Update the runtime in the loaded configuration
130- r .Config .Runtime = runtime
131-
132- return r , nil
133- }
134-
135- /*
136- * The following functions are duplicated in container/manager.go until
137- * we can refactor the code to avoid this duplication.
138- */
139-
140- // getContainerBaseName gets the base container name from the container labels
141- func getContainerBaseName (ctx context.Context , runtime rt.Runtime , containerID string ) (string , error ) {
142- containers , err := runtime .ListContainers (ctx )
143- if err != nil {
144- return "" , fmt .Errorf ("failed to list containers: %v" , err )
145- }
146-
147- for _ , c := range containers {
148- if c .ID == containerID {
149- return labels .GetContainerBaseName (c .Labels ), nil
150- }
151- }
152-
153- return "" , fmt .Errorf ("container %s not found" , containerID )
154- }
155-
156- func findContainerID (ctx context.Context , runtime rt.Runtime , name string ) (string , error ) {
157- c , err := findContainerByName (ctx , runtime , name )
158- if err != nil {
159- return "" , err
160- }
161- return c .ID , nil
162- }
163-
164- func findContainerByName (ctx context.Context , runtime rt.Runtime , name string ) (* rt.ContainerInfo , error ) {
165- // List containers to find the one with the given name
166- containers , err := runtime .ListContainers (ctx )
167- if err != nil {
168- return nil , fmt .Errorf ("failed to list containers: %v" , err )
169- }
170-
171- // Find the container with the given name
172- for _ , c := range containers {
173- // Check if the container is managed by ToolHive
174- if ! labels .IsToolHiveContainer (c .Labels ) {
175- continue
176- }
177-
178- // Check if the container name matches
179- containerName := labels .GetContainerName (c .Labels )
180- if containerName == "" {
181- name = c .Name // Fallback to container name
182- }
183-
184- // Check if the name matches (exact match or prefix match)
185- if containerName == name || c .ID == name {
186- return & c , nil
187- }
188- }
189-
190- return nil , fmt .Errorf ("%w: %s" , lifecycle .ErrContainerNotFound , name )
34+ // Restart the container in a detached process.
35+ return manager .RestartContainer (ctx , containerName )
19136}
0 commit comments