@@ -607,13 +607,84 @@ func (s *Service) DeleteBranch(ctx context.Context, params DeleteBranchParams) e
607607 return nil
608608}
609609
610+ // killRestoreProcess kills an active restore process if it's running
611+ func (s * Service ) killRestoreProcess (ctx context.Context , restoreName string ) {
612+ pidFile := fmt .Sprintf ("/var/log/branchd/restore-%s.pid" , restoreName )
613+ logFile := fmt .Sprintf ("/var/log/branchd/restore-%s.log" , restoreName )
614+
615+ // Check if PID file exists and process is running
616+ checkCmd := fmt .Sprintf (`
617+ if [ -f %s ]; then
618+ pid=$(cat %s)
619+ if kill -0 $pid 2>/dev/null; then
620+ echo "running:$pid"
621+ else
622+ echo "stopped"
623+ fi
624+ else
625+ echo "not_found"
626+ fi
627+ ` , pidFile , pidFile )
628+
629+ cmd := exec .CommandContext (ctx , "bash" , "-c" , checkCmd )
630+ outputBytes , err := cmd .CombinedOutput ()
631+ if err != nil {
632+ s .logger .Warn ().
633+ Err (err ).
634+ Str ("restore_name" , restoreName ).
635+ Msg ("Failed to check restore process status" )
636+ }
637+
638+ output := strings .TrimSpace (string (outputBytes ))
639+
640+ // If process is running, kill it
641+ if strings .HasPrefix (output , "running:" ) {
642+ pid := strings .TrimPrefix (output , "running:" )
643+
644+ // Kill the process (SIGTERM first, then SIGKILL if needed)
645+ killCmd := fmt .Sprintf (`
646+ pid=%s
647+ if kill -0 $pid 2>/dev/null; then
648+ kill -TERM $pid 2>/dev/null || true
649+ sleep 1
650+ if kill -0 $pid 2>/dev/null; then
651+ kill -KILL $pid 2>/dev/null || true
652+ fi
653+ fi
654+ ` , pid )
655+
656+ killExecCmd := exec .CommandContext (ctx , "bash" , "-c" , killCmd )
657+ if killOutput , killErr := killExecCmd .CombinedOutput (); killErr != nil {
658+ s .logger .Warn ().
659+ Err (killErr ).
660+ Str ("output" , string (killOutput )).
661+ Str ("pid" , pid ).
662+ Msg ("Failed to kill restore process" )
663+ } else {
664+ s .logger .Info ().
665+ Str ("restore_name" , restoreName ).
666+ Str ("pid" , pid ).
667+ Msg ("Restore process killed successfully" )
668+ }
669+ }
670+
671+ // Clean up PID and log files
672+ cleanupCmd := fmt .Sprintf ("rm -f %s %s" , pidFile , logFile )
673+ cleanupExecCmd := exec .CommandContext (ctx , "bash" , "-c" , cleanupCmd )
674+ if cleanupOutput , cleanupErr := cleanupExecCmd .CombinedOutput (); cleanupErr != nil {
675+ s .logger .Warn ().
676+ Err (cleanupErr ).
677+ Str ("output" , string (cleanupOutput )).
678+ Msg ("Failed to clean up restore files" )
679+ } else {
680+ s .logger .Debug ().
681+ Str ("restore_name" , restoreName ).
682+ Msg ("Restore PID and log files cleaned up" )
683+ }
684+ }
685+
610686// DeleteRestore deletes a restore from the main cluster
611687func (s * Service ) DeleteRestore (ctx context.Context , restore * models.Restore ) error {
612- s .logger .Info ().
613- Str ("restore_id" , restore .ID ).
614- Str ("restore_name" , restore .Name ).
615- Msg ("Starting restore deletion" )
616-
617688 // Load config to get PostgreSQL version
618689 var config models.Config
619690 if err := s .db .First (& config ).Error ; err != nil {
@@ -637,6 +708,9 @@ func (s *Service) DeleteRestore(ctx context.Context, restore *models.Restore) er
637708 return fmt .Errorf ("unsupported PostgreSQL version: %s" , config .PostgresVersion )
638709 }
639710
711+ // Kill any active restore process before dropping the database
712+ s .killRestoreProcess (ctx , restore .Name )
713+
640714 // Drop restore database from PostgreSQL cluster
641715 dropCmd := fmt .Sprintf ("sudo -u postgres psql -p %d -c 'DROP DATABASE IF EXISTS \" %s\" '" , port , restore .Name )
642716 cmd := exec .CommandContext (ctx , "bash" , "-c" , dropCmd )
0 commit comments