Merge pull request #7056 from hashicorp/fix_6799

Add registry key check for windows-restart provisioner
This commit is contained in:
Megan Marsh 2018-12-12 13:14:05 -08:00 committed by GitHub
commit e253892434
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 1 deletions

View File

@ -23,6 +23,12 @@ var retryableSleep = 5 * time.Second
var TryCheckReboot = `shutdown /r /f /t 60 /c "packer restart test"`
var AbortReboot = `shutdown /a`
var DefaultRegistryKeys = []string{
"HKLM:SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending",
"HKLM:SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\PackagesPending",
"HKLM:Software\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootInProgress",
}
type Config struct {
common.PackerConfig `mapstructure:",squash"`
@ -36,6 +42,12 @@ type Config struct {
// The timeout for waiting for the machine to restart
RestartTimeout time.Duration `mapstructure:"restart_timeout"`
// Whether to check the registry (see RegistryKeys) for pending reboots
CheckKey bool `mapstructure:"check_registry"`
// custom keys to check for
RegistryKeys []string `mapstructure:"registry_keys"`
ctx interpolate.Context
}
@ -73,6 +85,10 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
p.config.RestartTimeout = 5 * time.Minute
}
if len(p.config.RegistryKeys) == 0 {
p.config.RegistryKeys = DefaultRegistryKeys
}
return nil
}
@ -212,7 +228,6 @@ var waitForCommunicator = func(p *Provisioner) error {
log.Printf("Connected to machine")
runCustomRestartCheck = false
}
// This is the non-user-configurable check that powershell
// modules have loaded.
@ -234,6 +249,37 @@ var waitForCommunicator = func(p *Provisioner) error {
log.Printf("echo didn't succeed; retrying...")
continue
}
if p.config.CheckKey {
log.Printf("Connected to machine")
shouldContinue := false
for _, RegKey := range p.config.RegistryKeys {
KeyTestCommand := winrm.Powershell(fmt.Sprintf(`Test-Path "%s"`, RegKey))
cmdKeyCheck := &packer.RemoteCmd{Command: KeyTestCommand}
log.Printf("Checking registry for pending reboots")
var buf, buf2 bytes.Buffer
cmdKeyCheck.Stdout = &buf
cmdKeyCheck.Stdout = io.MultiWriter(cmdKeyCheck.Stdout, &buf2)
err := p.comm.Start(cmdKeyCheck)
if err != nil {
log.Printf("Communication connection err: %s", err)
shouldContinue = true
}
cmdKeyCheck.Wait()
stdoutToRead := buf2.String()
if strings.Contains(stdoutToRead, "True") {
log.Printf("RegistryKey %s exists; waiting...", KeyTestCommand)
shouldContinue = true
} else {
log.Printf("No Registry keys found; exiting wait loop")
}
}
if shouldContinue {
continue
}
}
break
}

View File

@ -38,6 +38,28 @@ The reference of available configuration options is listed below.
Optional parameters:
- `check_registry` (bool) - if `true`, checks for several registry keys that
indicate that the system is going to reboot. This is useful if an
installation kicks off a reboot and you want the provisioner to wait for
that reboot to complete before reconnecting. Please note that this option is
a beta feature, and we generally recommend that you finish installs that
auto-reboot (like windows updates) during your autounattend phase before our
winrm provisioner connects.
- `registry_keys` (array of strings) - if `check-registry` is `true`,
windows-restart will not reconnect until after all of the listed keys are
no longer present in the registry.
default:
```
var DefaultRegistryKeys = []string{
"HKLM:SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending",
"HKLM:SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\PackagesPending",
"HKLM:Software\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootInProgress",
}
```
- `restart_command` (string) - The command to execute to initiate the
restart. By default this is `shutdown /r /f /t 0 /c "packer restart"`.