@@ -481,28 +481,73 @@ func (d *Driver) Remove() error {
481481 }
482482 if machineState == state .Running {
483483 if d .GracefulShutdownTimeout > 0 {
484- // graceful shutdown the machine
485484 log .Infof ("Gracefully shutting down VM %s (ID: %s)" , d .MachineName , d .MachineId )
486- if err := d .Stop (); err != nil {
487- return err
488- }
489- // wait for machine to stop
490- elapsed := 0
491- for elapsed <= d .GracefulShutdownTimeout {
485+
486+ start := time .Now ()
487+ deadline := start .Add (time .Duration (d .GracefulShutdownTimeout ) * time .Second )
488+ sleep := time .Duration (gracefulShutdownSleep ) * time .Second
489+
490+ gracefulShutdownInitiated := false
491+
492+ for time .Now ().Before (deadline ) {
493+ // If we haven't initiated shutdown yet, keep trying.
494+ if ! gracefulShutdownInitiated {
495+ if err := d .Stop (); err != nil {
496+ log .Debugf (
497+ "Failed to initiate graceful shutdown for VM %s (ID: %s): %v. Elapsed time: %d second(s)" ,
498+ d .MachineName , d .MachineId , err , int (time .Since (start ).Seconds ()),
499+ )
500+ } else {
501+ gracefulShutdownInitiated = true
502+ log .Infof (
503+ "Graceful shutdown initiated for VM %s (ID: %s). Elapsed time: %d second(s)" ,
504+ d .MachineName , d .MachineId , int (time .Since (start ).Seconds ()),
505+ )
506+ }
507+ }
508+
509+ // Always check state so we can exit early if it stopped (even if Stop() never succeeded).
492510 if machineState , err = d .GetState (); err != nil {
493511 return err
494512 }
495513 if machineState == state .Stopped {
514+ if gracefulShutdownInitiated {
515+ log .Infof (
516+ "VM %s (ID: %s) stopped gracefully after %d second(s)" ,
517+ d .MachineName , d .MachineId , int (time .Since (start ).Seconds ()),
518+ )
519+ }
496520 break
497521 }
498- elapsed += gracefulShutdownSleep
499- time .Sleep (gracefulShutdownSleep * time .Second )
500- log .Debugf ("Waiting for VM %s (ID: %s) to stop. Elapsed time: %d second(s)" , d .MachineName , d .MachineId , elapsed )
522+
523+ log .Debugf (
524+ "Waiting for VM %s (ID: %s) to stop. Elapsed time: %d second(s)" ,
525+ d .MachineName , d .MachineId , int (time .Since (start ).Seconds ()),
526+ )
527+
528+ // Sleep, but don't go past the deadline.
529+ if rem := time .Until (deadline ); rem < sleep {
530+ time .Sleep (rem )
531+ } else {
532+ time .Sleep (sleep )
533+ }
501534 }
502- if elapsed > d .GracefulShutdownTimeout {
503- log .Infof ("Timeout for graceful shutdown of VM %s (ID: %s)" , d .MachineName , d .MachineId )
535+
536+ if machineState != state .Stopped {
537+ if ! gracefulShutdownInitiated {
538+ log .Infof (
539+ "Failed to initiate graceful shutdown for VM %s (ID: %s) within timeout of %d second(s)" ,
540+ d .MachineName , d .MachineId , d .GracefulShutdownTimeout ,
541+ )
542+ } else {
543+ log .Infof (
544+ "Timeout for graceful shutdown of VM %s (ID: %s) after %d second(s)" ,
545+ d .MachineName , d .MachineId , int (time .Since (start ).Seconds ()),
546+ )
547+ }
504548 }
505549 }
550+
506551 if machineState , err = d .GetState (); err != nil {
507552 return err
508553 }
0 commit comments