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  }