github.com/cloudfoundry-incubator/stembuild@v0.0.0-20211223202937-5b61d62226c6/remotemanager/winrm_rebootchecker.go (about) 1 package remotemanager 2 3 import ( 4 "errors" 5 "fmt" 6 "github.com/cloudfoundry-incubator/stembuild/poller" 7 "time" 8 ) 9 10 var tryCheckReboot = `shutdown /r /f /t 60 /c "stembuild reboot test"` 11 var abortReboot = `shutdown /a` 12 13 type RebootWaiter struct { 14 poller poller.PollerI 15 rebootChecker RebootCheckerI 16 } 17 18 func NewRebootWaiter(poller poller.PollerI, rebootChecker RebootCheckerI) *RebootWaiter { 19 return &RebootWaiter{ 20 poller, 21 rebootChecker, 22 } 23 } 24 25 func (rw *RebootWaiter) WaitForRebootFinished() error { 26 err := rw.poller.Poll(10*time.Second, rw.rebootChecker.RebootHasFinished) 27 28 if err != nil { 29 return fmt.Errorf("error polling for reboot: %s", err) 30 } 31 return nil 32 } 33 34 //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . RebootCheckerI 35 type RebootCheckerI interface { 36 RebootHasFinished() (bool, error) 37 } 38 39 type RebootChecker struct { 40 remoteManager RemoteManager 41 } 42 43 func NewRebootChecker(winrmRemoteManager RemoteManager) *RebootChecker { 44 return &RebootChecker{winrmRemoteManager} 45 } 46 47 // Inspired by Hashicorp Packer waitForRestart 48 func (rc *RebootChecker) RebootHasFinished() (bool, error) { 49 50 exitCode, err := rc.remoteManager.ExecuteCommand(tryCheckReboot) 51 if err != nil { 52 return false, nil 53 } 54 if exitCode == 0 { 55 var abortExitCode int 56 var abortErr error 57 for i := 0; i < 5; i++ { 58 abortExitCode, abortErr = rc.remoteManager.ExecuteCommand(abortReboot) 59 60 if abortErr == nil { 61 break 62 } 63 } 64 65 if abortErr != nil { 66 return false, fmt.Errorf("unable to abort reboot: %s", abortErr) 67 } 68 69 if abortExitCode == 0 { 70 return true, nil 71 } else { 72 return false, errors.New("unable to abort reboot.") 73 } 74 75 } 76 return false, err 77 }