Merge pull request #5563 from hashicorp/fix_5483
make restart command work correctly even if user has their own check …
This commit is contained in:
commit
ce1f2457fd
|
@ -3,7 +3,7 @@ package restart
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -17,7 +17,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var DefaultRestartCommand = "shutdown /r /f /t 0 /c \"packer restart\""
|
var DefaultRestartCommand = "shutdown /r /f /t 0 /c \"packer restart\""
|
||||||
var DefaultRestartCheckCommand = winrm.Powershell(`if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'}; echo "${env:COMPUTERNAME} restarted."`)
|
var DefaultRestartCheckCommand = winrm.Powershell(`echo "${env:COMPUTERNAME} restarted."`)
|
||||||
var retryableSleep = 5 * time.Second
|
var retryableSleep = 5 * time.Second
|
||||||
var TryCheckReboot = "shutdown.exe -f -r -t 60"
|
var TryCheckReboot = "shutdown.exe -f -r -t 60"
|
||||||
var AbortReboot = "shutdown.exe -a"
|
var AbortReboot = "shutdown.exe -a"
|
||||||
|
@ -174,30 +174,58 @@ WaitLoop:
|
||||||
}
|
}
|
||||||
|
|
||||||
var waitForCommunicator = func(p *Provisioner) error {
|
var waitForCommunicator = func(p *Provisioner) error {
|
||||||
|
runCustomRestartCheck := true
|
||||||
|
if p.config.RestartCheckCommand == DefaultRestartCheckCommand {
|
||||||
|
runCustomRestartCheck = false
|
||||||
|
}
|
||||||
|
// This command is configurable by the user to make sure that the
|
||||||
|
// vm has met their necessary criteria for having restarted. If the
|
||||||
|
// user doesn't set a special restart command, we just run the
|
||||||
|
// default as cmdModuleLoad below.
|
||||||
|
cmdRestartCheck := &packer.RemoteCmd{Command: p.config.RestartCheckCommand}
|
||||||
|
log.Printf("Checking that communicator is connected with: '%s'",
|
||||||
|
cmdRestartCheck.Command)
|
||||||
for {
|
for {
|
||||||
cmd := &packer.RemoteCmd{Command: p.config.RestartCheckCommand}
|
|
||||||
var buf, buf2 bytes.Buffer
|
|
||||||
cmd.Stdout = &buf
|
|
||||||
cmd.Stdout = io.MultiWriter(cmd.Stdout, &buf2)
|
|
||||||
select {
|
select {
|
||||||
case <-p.cancel:
|
case <-p.cancel:
|
||||||
log.Println("Communicator wait canceled, exiting loop")
|
log.Println("Communicator wait canceled, exiting loop")
|
||||||
return fmt.Errorf("Communicator wait canceled")
|
return fmt.Errorf("Communicator wait canceled")
|
||||||
case <-time.After(retryableSleep):
|
case <-time.After(retryableSleep):
|
||||||
}
|
}
|
||||||
|
if runCustomRestartCheck {
|
||||||
log.Printf("Checking that communicator is connected with: '%s'", cmd.Command)
|
// run user-configured restart check
|
||||||
|
err := cmdRestartCheck.StartWithUi(p.comm, p.ui)
|
||||||
err := cmd.StartWithUi(p.comm, p.ui)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Communication connection err: %s", err)
|
log.Printf("Communication connection err: %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Connected to machine")
|
log.Printf("Connected to machine")
|
||||||
stdoutToRead := buf2.String()
|
runCustomRestartCheck = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the non-user-configurable check that powershell
|
||||||
|
// modules have loaded.
|
||||||
|
|
||||||
|
// If we catch the restart in just the right place, we will be able
|
||||||
|
// to run the restart check but the output will be an error message
|
||||||
|
// about how it needs powershell modules to load, and we will start
|
||||||
|
// provisioning before powershell is actually ready.
|
||||||
|
// In this next check, we parse stdout to make sure that the command is
|
||||||
|
// actually running as expected.
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
cmdModuleLoad := &packer.RemoteCmd{
|
||||||
|
Command: DefaultRestartCheckCommand,
|
||||||
|
Stdin: nil,
|
||||||
|
Stdout: &stdout,
|
||||||
|
Stderr: &stderr}
|
||||||
|
|
||||||
|
p.comm.Start(cmdModuleLoad)
|
||||||
|
cmdModuleLoad.Wait()
|
||||||
|
|
||||||
|
stdoutToRead := stdout.String()
|
||||||
|
stderrToRead := stderr.String()
|
||||||
if !strings.Contains(stdoutToRead, "restarted.") {
|
if !strings.Contains(stdoutToRead, "restarted.") {
|
||||||
|
log.Printf("Stderr is %s", stderrToRead)
|
||||||
log.Printf("echo didn't succeed; retrying...")
|
log.Printf("echo didn't succeed; retrying...")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,14 @@ Optional parameters:
|
||||||
detect it is rebooting.
|
detect it is rebooting.
|
||||||
|
|
||||||
- `restart_check_command` (string) - A command to execute to check if the
|
- `restart_check_command` (string) - A command to execute to check if the
|
||||||
restart succeeded. This will be done in a loop.
|
restart succeeded. This will be done in a loop. Example usage:
|
||||||
|
|
||||||
|
``` json
|
||||||
|
{
|
||||||
|
"type": "windows-restart",
|
||||||
|
"restart_check_command": "powershell -command \"& {Write-Output 'restarted.'}\""
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
- `restart_timeout` (string) - The timeout to wait for the restart. By
|
- `restart_timeout` (string) - The timeout to wait for the restart. By
|
||||||
default this is 5 minutes. Example value: `5m`. If you are installing
|
default this is 5 minutes. Example value: `5m`. If you are installing
|
||||||
|
|
Loading…
Reference in New Issue