@@ -26,7 +26,6 @@ import (
26
26
"github.com/stacklok/toolhive/pkg/secrets"
27
27
"github.com/stacklok/toolhive/pkg/state"
28
28
"github.com/stacklok/toolhive/pkg/transport"
29
- "github.com/stacklok/toolhive/pkg/transport/proxy"
30
29
"github.com/stacklok/toolhive/pkg/workloads/statuses"
31
30
"github.com/stacklok/toolhive/pkg/workloads/types"
32
31
)
@@ -575,16 +574,39 @@ func (d *defaultManager) getWorkloadContainer(ctx context.Context, name string)
575
574
return & container , nil
576
575
}
577
576
577
+ // stopProcess stops the proxy process associated with the container
578
+ func (d * defaultManager ) stopProcess (ctx context.Context , name string ) {
579
+ if name == "" {
580
+ logger .Warnf ("Warning: Could not find base container name in labels" )
581
+ return
582
+ }
583
+
584
+ // Try to read the PID and kill the process
585
+ pid , err := d .statuses .GetWorkloadPID (ctx , name )
586
+ if err != nil {
587
+ logger .Errorf ("No PID file found for %s, proxy may not be running in detached mode" , name )
588
+ return
589
+ }
590
+
591
+ // PID file found, try to kill the process
592
+ logger .Infof ("Stopping proxy process (PID: %d)..." , pid )
593
+ if err := process .KillProcess (pid ); err != nil {
594
+ logger .Warnf ("Warning: Failed to kill proxy process: %v" , err )
595
+ } else {
596
+ logger .Info ("Proxy process stopped" )
597
+ }
598
+
599
+ // Clean up PID file after successful kill
600
+ if err := process .RemovePIDFile (name ); err != nil {
601
+ logger .Warnf ("Warning: Failed to remove PID file: %v" , err )
602
+ }
603
+ }
604
+
578
605
// stopProxyIfNeeded stops the proxy process if the workload has a base name
579
606
func (d * defaultManager ) stopProxyIfNeeded (ctx context.Context , name , baseName string ) {
580
607
logger .Infof ("Removing proxy process for %s..." , name )
581
608
if baseName != "" {
582
- proxy .StopProcess (baseName )
583
- // TODO: refactor the StopProcess function to stop dealing explicitly with PID files.
584
- // Note that this is not a blocker for k8s since this code path is not called there.
585
- if err := d .statuses .ResetWorkloadPID (ctx , baseName ); err != nil {
586
- logger .Warnf ("Warning: Failed to reset workload %s PID: %v" , name , err )
587
- }
609
+ d .stopProcess (ctx , baseName )
588
610
}
589
611
}
590
612
@@ -798,32 +820,40 @@ func (d *defaultManager) restartContainerWorkload(ctx context.Context, name stri
798
820
workloadName = name
799
821
}
800
822
801
- // Get workload state information using the original name
802
- workloadState , err := d .getWorkloadState (ctx , name )
803
- if err != nil {
823
+ // Get workload status using the status manager
824
+ workload , err := d .statuses . GetWorkload (ctx , name )
825
+ if err != nil && ! errors . Is ( err , rt . ErrWorkloadNotFound ) {
804
826
return err
805
827
}
806
828
807
- // Check if already running - use container name for this check
808
- if d .isWorkloadAlreadyRunning (containerName , workloadState ) {
829
+ // Check if already running - compare status to WorkloadStatusRunning
830
+ if err == nil && workload .Status == rt .WorkloadStatusRunning {
831
+ logger .Infof ("Container %s is already running" , containerName )
809
832
return nil
810
833
}
811
834
812
835
// Load runner configuration from state
813
- mcpRunner , err := d .loadRunnerFromState (ctx , workloadState . BaseName )
836
+ mcpRunner , err := d .loadRunnerFromState (ctx , workloadName )
814
837
if err != nil {
815
- return fmt .Errorf ("failed to load state for %s: %v" , workloadState . BaseName , err )
838
+ return fmt .Errorf ("failed to load state for %s: %v" , workloadName , err )
816
839
}
817
840
818
841
// Set workload status to starting - use the workload name for status operations
819
842
if err := d .statuses .SetWorkloadStatus (ctx , workloadName , rt .WorkloadStatusStarting , "" ); err != nil {
820
843
logger .Warnf ("Failed to set workload %s status to starting: %v" , workloadName , err )
821
844
}
822
- logger .Infof ("Loaded configuration from state for %s" , workloadState . BaseName )
845
+ logger .Infof ("Loaded configuration from state for %s" , workloadName )
823
846
824
- // Stop container if running but proxy is not - use the container name for runtime operations
825
- if err := d .stopContainerIfNeeded (ctx , containerName , workloadName , workloadState ); err != nil {
826
- return err
847
+ // Stop container if needed - since workload is not in running status, check if container needs stopping
848
+ if container .IsRunning () {
849
+ logger .Infof ("Container %s is running but workload is not in running state. Stopping container..." , containerName )
850
+ if err := d .runtime .StopWorkload (ctx , containerName ); err != nil {
851
+ if statusErr := d .statuses .SetWorkloadStatus (ctx , workloadName , rt .WorkloadStatusError , "" ); statusErr != nil {
852
+ logger .Warnf ("Failed to set workload %s status to error: %v" , workloadName , statusErr )
853
+ }
854
+ return fmt .Errorf ("failed to stop container %s: %v" , containerName , err )
855
+ }
856
+ logger .Infof ("Container %s stopped" , containerName )
827
857
}
828
858
829
859
// Start the workload with background context to avoid timeout cancellation
@@ -840,34 +870,6 @@ type workloadState struct {
840
870
ProxyRunning bool
841
871
}
842
872
843
- // getWorkloadState retrieves the current state of a workload
844
- func (d * defaultManager ) getWorkloadState (ctx context.Context , name string ) (* workloadState , error ) {
845
- workloadSt := & workloadState {}
846
-
847
- // Try to find the container
848
- container , err := d .runtime .GetWorkloadInfo (ctx , name )
849
- if err != nil {
850
- if errors .Is (err , rt .ErrWorkloadNotFound ) {
851
- logger .Warnf ("Warning: Failed to find container: %v" , err )
852
- logger .Warnf ("Trying to find state with name %s directly..." , name )
853
- // Try to use the provided name as the base name
854
- workloadSt .BaseName = name
855
- workloadSt .Running = false
856
- } else {
857
- return nil , fmt .Errorf ("failed to find workload %s: %v" , name , err )
858
- }
859
- } else {
860
- // Container found, check if it's running and get the base name
861
- workloadSt .Running = container .IsRunning ()
862
- workloadSt .BaseName = labels .GetContainerBaseName (container .Labels )
863
- }
864
-
865
- // Check if the proxy process is running
866
- workloadSt .ProxyRunning = proxy .IsRunning (workloadSt .BaseName )
867
-
868
- return workloadSt , nil
869
- }
870
-
871
873
// getRemoteWorkloadState retrieves the current state of a remote workload
872
874
func (d * defaultManager ) getRemoteWorkloadState (ctx context.Context , name , baseName string ) * workloadState {
873
875
workloadSt := & workloadState {
@@ -884,9 +886,6 @@ func (d *defaultManager) getRemoteWorkloadState(ctx context.Context, name, baseN
884
886
workloadSt .Running = workload .Status == rt .WorkloadStatusRunning
885
887
}
886
888
887
- // Check if the detached process is actually running
888
- workloadSt .ProxyRunning = proxy .IsRunning (baseName )
889
-
890
889
return workloadSt
891
890
}
892
891
@@ -899,25 +898,6 @@ func (*defaultManager) isWorkloadAlreadyRunning(name string, workloadSt *workloa
899
898
return false
900
899
}
901
900
902
- // stopContainerIfNeeded stops the container if it's running but proxy is not
903
- func (d * defaultManager ) stopContainerIfNeeded (
904
- ctx context.Context , containerName , workloadName string , workloadSt * workloadState ,
905
- ) error {
906
- if ! workloadSt .Running {
907
- return nil
908
- }
909
-
910
- logger .Infof ("Container %s is running but proxy is not. Stopping container..." , containerName )
911
- if err := d .runtime .StopWorkload (ctx , containerName ); err != nil {
912
- if statusErr := d .statuses .SetWorkloadStatus (ctx , workloadName , rt .WorkloadStatusError , "" ); statusErr != nil {
913
- logger .Warnf ("Failed to set workload %s status to error: %v" , workloadName , statusErr )
914
- }
915
- return fmt .Errorf ("failed to stop container %s: %v" , containerName , err )
916
- }
917
- logger .Infof ("Container %s stopped" , containerName )
918
- return nil
919
- }
920
-
921
901
// startWorkload starts the workload in either foreground or background mode
922
902
func (d * defaultManager ) startWorkload (ctx context.Context , name string , mcpRunner * runner.Runner , foreground bool ) error {
923
903
logger .Infof ("Starting tooling server %s..." , name )
@@ -1024,8 +1004,9 @@ func (d *defaultManager) stopSingleContainerWorkload(ctx context.Context, worklo
1024
1004
if labels .IsAuxiliaryWorkload (workload .Labels ) {
1025
1005
logger .Debugf ("Skipping proxy stop for auxiliary workload %s" , name )
1026
1006
} else {
1027
- proxy . StopProcess ( name )
1007
+ d . stopProcess ( ctx , name )
1028
1008
}
1009
+
1029
1010
// TODO: refactor the StopProcess function to stop dealing explicitly with PID files.
1030
1011
// Note that this is not a blocker for k8s since this code path is not called there.
1031
1012
if err := d .statuses .ResetWorkloadPID (ctx , name ); err != nil {
0 commit comments