Make sure the WinRM communicator can reconnect

This commit is contained in:
Sander van Harmelen 2020-05-05 18:13:01 +02:00 committed by Brian Dwyer
parent 10aab86051
commit 9453308c78
3 changed files with 22 additions and 10 deletions

View File

@ -204,7 +204,7 @@ func Provisioner() terraform.ResourceProvisioner {
"max_retries": &schema.Schema{ "max_retries": &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Default: 1, Default: 0,
}, },
"no_proxy": &schema.Schema{ "no_proxy": &schema.Schema{
Type: schema.TypeList, Type: schema.TypeList,
@ -392,6 +392,11 @@ func applyFn(ctx context.Context) error {
o.Output("Starting initial Chef-Client run...") o.Output("Starting initial Chef-Client run...")
for attempt := 0; attempt <= p.MaxRetries; attempt++ { for attempt := 0; attempt <= p.MaxRetries; attempt++ {
// We need a new retry context for each attempt, to make sure
// they all get the correct timeout.
retryCtx, cancel := context.WithTimeout(ctx, comm.Timeout())
defer cancel()
// Make sure to (re)connect before trying to run Chef-Client. // Make sure to (re)connect before trying to run Chef-Client.
if err := communicator.Retry(retryCtx, func() error { if err := communicator.Retry(retryCtx, func() error {
return comm.Connect(o) return comm.Connect(o)
@ -795,7 +800,7 @@ func decodeConfig(d *schema.ResourceData) (*provisioner, error) {
OSType: d.Get("os_type").(string), OSType: d.Get("os_type").(string),
RecreateClient: d.Get("recreate_client").(bool), RecreateClient: d.Get("recreate_client").(bool),
PreventSudo: d.Get("prevent_sudo").(bool), PreventSudo: d.Get("prevent_sudo").(bool),
RetryOnExitCode: getIntListAsMap(d.Get("retry_on_exit_code")), RetryOnExitCode: getRetryOnExitCodes(d),
RunList: getStringList(d.Get("run_list")), RunList: getStringList(d.Get("run_list")),
SecretKey: d.Get("secret_key").(string), SecretKey: d.Get("secret_key").(string),
ServerURL: d.Get("server_url").(string), ServerURL: d.Get("server_url").(string),
@ -855,12 +860,19 @@ func decodeConfig(d *schema.ResourceData) (*provisioner, error) {
return p, nil return p, nil
} }
func getIntListAsMap(v interface{}) map[int]bool { func getRetryOnExitCodes(d *schema.ResourceData) map[int]bool {
result := make(map[int]bool) result := make(map[int]bool)
switch v := v.(type) { v, ok := d.GetOk("retry_on_exit_code")
case nil: if !ok || v == nil {
// Use default exit codes
result[35] = true
result[37] = true
result[213] = true
return result return result
}
switch v := v.(type) {
case []interface{}: case []interface{}:
for _, vv := range v { for _, vv := range v {
if vv, ok := vv.(int); ok { if vv, ok := vv.(int); ok {

View File

@ -52,9 +52,8 @@ func New(s *terraform.InstanceState) (*Communicator, error) {
// Connect implementation of communicator.Communicator interface // Connect implementation of communicator.Communicator interface
func (c *Communicator) Connect(o terraform.UIOutput) error { func (c *Communicator) Connect(o terraform.UIOutput) error {
if c.client != nil { // Set the client to nil since we'll (re)create it
return nil c.client = nil
}
params := winrm.DefaultParameters params := winrm.DefaultParameters
params.Timeout = formatDuration(c.Timeout()) params.Timeout = formatDuration(c.Timeout())

View File

@ -112,7 +112,7 @@ The following arguments are supported:
* `https_proxy (string)` - (Optional) The proxy server for Chef Client HTTPS connections. * `https_proxy (string)` - (Optional) The proxy server for Chef Client HTTPS connections.
* `max_retries (integer)` - (Optional) The number of times to retry the provisioning process * `max_retries (integer)` - (Optional) The number of times to retry the provisioning process
after receiving an exit code in the `retry_on_error` list. Defaults to `1` after receiving an exit code in the `retry_on_error` list. Defaults to `0`
* `named_run_list (string)` - (Optional) The name of an alternate run-list to invoke during the * `named_run_list (string)` - (Optional) The name of an alternate run-list to invoke during the
initial Chef Client run. The run-list must already exist in the Policyfile that defines initial Chef Client run. The run-list must already exist in the Policyfile that defines
@ -136,9 +136,10 @@ The following arguments are supported:
* `recreate_client (boolean)` - (Optional) If `true`, first delete any existing Chef Node and * `recreate_client (boolean)` - (Optional) If `true`, first delete any existing Chef Node and
Client before registering the new Chef Client. Client before registering the new Chef Client.
* `retry_on_error (list of integers)` - (Optional) The error codes upon which Terraform should * `retry_on_error (array)` - (Optional) The error codes upon which Terraform should
gracefully retry the provisioning process. Intended for use with gracefully retry the provisioning process. Intended for use with
[Chef RFC062 codes](https://github.com/chef-boneyard/chef-rfc/blob/master/rfc062-exit-status.md). [Chef RFC062 codes](https://github.com/chef-boneyard/chef-rfc/blob/master/rfc062-exit-status.md).
(Defaults to `[35, 37, 213]`)
* `run_list (array)` - (Optional) A list with recipes that will be invoked during the initial * `run_list (array)` - (Optional) A list with recipes that will be invoked during the initial
Chef Client run. The run-list will also be saved to the Chef Server after a successful Chef Client run. The run-list will also be saved to the Chef Server after a successful