Skip to content

Commit

Permalink
retry node pool writes on failed precondition (#1660)
Browse files Browse the repository at this point in the history
Hypothetically fixes #1643.

@thomasriley, are you able to patch this change into your provider to see if it fixed the problem? I haven't been able to get a working repo so I haven't verified the fix yet.
  • Loading branch information
danawillow authored Jun 22, 2018
1 parent e123401 commit 34a6828
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
28 changes: 19 additions & 9 deletions google/resource_container_node_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,20 +218,34 @@ func resourceContainerNodePoolCreate(d *schema.ResourceData, meta interface{}) e
NodePool: nodePool,
}

operation, err := config.clientContainerBeta.
Projects.Locations.Clusters.NodePools.Create(nodePoolInfo.parent(), req).Do()
timeout := d.Timeout(schema.TimeoutCreate)
startTime := time.Now()

var operation *containerBeta.Operation
err = resource.Retry(timeout, func() *resource.RetryError {
operation, err = config.clientContainerBeta.
Projects.Locations.Clusters.NodePools.Create(nodePoolInfo.parent(), req).Do()

if err != nil {
if isFailedPreconditionError(err) {
// We get failed precondition errors if the cluster is updating
// while we try to add the node pool.
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
if err != nil {
return fmt.Errorf("error creating NodePool: %s", err)
}
timeout -= time.Since(startTime)

d.SetId(fmt.Sprintf("%s/%s/%s", nodePoolInfo.location, nodePoolInfo.cluster, nodePool.Name))

timeoutInMinutes := int(d.Timeout(schema.TimeoutCreate).Minutes())

waitErr := containerBetaOperationWait(config,
operation, nodePoolInfo.project,
nodePoolInfo.location, "creating GKE NodePool", timeoutInMinutes, 3)
nodePoolInfo.location, "creating GKE NodePool", int(timeout.Minutes()), 3)

if waitErr != nil {
// The resource didn't actually create
Expand Down Expand Up @@ -259,10 +273,6 @@ func resourceContainerNodePoolRead(d *schema.ResourceData, meta interface{}) err
nodePool, err = config.clientContainerBeta.
Projects.Locations.Clusters.NodePools.Get(nodePoolInfo.fullyQualifiedName(name)).Do()

if err != nil {
return resource.NonRetryableError(err)
}

if err != nil {
return resource.NonRetryableError(err)
}
Expand Down
19 changes: 19 additions & 0 deletions google/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,25 @@ func isApiNotEnabledError(err error) bool {
return false
}

func isFailedPreconditionError(err error) bool {
gerr, ok := errwrap.GetType(err, &googleapi.Error{}).(*googleapi.Error)
if !ok {
return false
}
if gerr == nil {
return false
}
if gerr.Code != 400 {
return false
}
for _, e := range gerr.Errors {
if e.Reason == "failedPrecondition" {
return true
}
}
return false
}

func isConflictError(err error) bool {
if e, ok := err.(*googleapi.Error); ok && e.Code == 409 {
return true
Expand Down

0 comments on commit 34a6828

Please sign in to comment.