move backend operation cancellation into meta
Create a single command method for running and operation with cancellation.
This commit is contained in:
parent
7cba68326a
commit
67a6152091
|
@ -2,12 +2,10 @@ package command
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/tfdiags"
|
||||
|
||||
|
@ -159,47 +157,9 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
opReq.AutoApprove = autoApprove
|
||||
opReq.DestroyForce = destroyForce
|
||||
|
||||
// Perform the operation
|
||||
op, err := b.Operation(context.Background(), opReq)
|
||||
op, err := c.RunOperation(b, opReq)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error starting operation: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Wait for the operation to complete or an interrupt to occur
|
||||
select {
|
||||
case <-c.ShutdownCh:
|
||||
// gracefully stop the operation
|
||||
op.Stop()
|
||||
|
||||
// Notify the user
|
||||
c.Ui.Output(outputInterrupt)
|
||||
|
||||
// Still get the result, since there is still one
|
||||
select {
|
||||
case <-c.ShutdownCh:
|
||||
c.Ui.Error(
|
||||
"Two interrupts received. Exiting immediately. Note that data\n" +
|
||||
"loss may have occurred.")
|
||||
|
||||
// cancel the operation completely
|
||||
op.Cancel()
|
||||
|
||||
// the operation should return asap
|
||||
// but timeout just in case
|
||||
select {
|
||||
case <-op.Done():
|
||||
case <-time.After(5 * time.Second):
|
||||
}
|
||||
|
||||
return 1
|
||||
|
||||
case <-op.Done():
|
||||
}
|
||||
case <-op.Done():
|
||||
if err := op.Err; err != nil {
|
||||
diags = diags.Append(err)
|
||||
}
|
||||
diags = diags.Append(err)
|
||||
}
|
||||
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
@ -3,6 +3,7 @@ package command
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
@ -259,6 +260,54 @@ func (m *Meta) StdinPiped() bool {
|
|||
return fi.Mode()&os.ModeNamedPipe != 0
|
||||
}
|
||||
|
||||
func (m *Meta) RunOperation(b backend.Enhanced, opReq *backend.Operation) (*backend.RunningOperation, error) {
|
||||
op, err := b.Operation(context.Background(), opReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error starting operation: %s", err)
|
||||
}
|
||||
|
||||
// Wait for the operation to complete or an interrupt to occur
|
||||
select {
|
||||
case <-m.ShutdownCh:
|
||||
// gracefully stop the operation
|
||||
op.Stop()
|
||||
|
||||
// Notify the user
|
||||
m.Ui.Output(outputInterrupt)
|
||||
|
||||
// Still get the result, since there is still one
|
||||
select {
|
||||
case <-m.ShutdownCh:
|
||||
m.Ui.Error(
|
||||
"Two interrupts received. Exiting immediately. Note that data\n" +
|
||||
"loss may have occurred.")
|
||||
|
||||
// cancel the operation completely
|
||||
op.Cancel()
|
||||
|
||||
// the operation should return asap
|
||||
// but timeout just in case
|
||||
select {
|
||||
case <-op.Done():
|
||||
case <-time.After(5 * time.Second):
|
||||
}
|
||||
|
||||
return nil, errors.New("operation canceled")
|
||||
|
||||
case <-op.Done():
|
||||
// operation completed after Stop
|
||||
}
|
||||
case <-op.Done():
|
||||
// operation completed normally
|
||||
}
|
||||
|
||||
if op.Err != nil {
|
||||
return op, op.Err
|
||||
}
|
||||
|
||||
return op, nil
|
||||
}
|
||||
|
||||
const (
|
||||
ProviderSkipVerifyEnvVar = "TF_SKIP_PROVIDER_VERIFY"
|
||||
)
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/config"
|
||||
|
@ -108,43 +106,9 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
opReq.Type = backend.OperationTypePlan
|
||||
|
||||
// Perform the operation
|
||||
op, err := b.Operation(context.Background(), opReq)
|
||||
op, err := c.RunOperation(b, opReq)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error starting operation: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
select {
|
||||
case <-c.ShutdownCh:
|
||||
// Cancel our context so we can start gracefully exiting
|
||||
op.Stop()
|
||||
|
||||
// Notify the user
|
||||
c.Ui.Output(outputInterrupt)
|
||||
|
||||
// Still get the result, since there is still one
|
||||
select {
|
||||
case <-c.ShutdownCh:
|
||||
c.Ui.Error(
|
||||
"Two interrupts received. Exiting immediately")
|
||||
|
||||
// cancel the operation completely
|
||||
op.Cancel()
|
||||
|
||||
// the operation should return asap
|
||||
// but timeout just in case
|
||||
select {
|
||||
case <-op.Done():
|
||||
case <-time.After(5 * time.Second):
|
||||
}
|
||||
|
||||
return 1
|
||||
case <-op.Done():
|
||||
}
|
||||
case <-op.Done():
|
||||
if err := op.Err; err != nil {
|
||||
diags = diags.Append(err)
|
||||
}
|
||||
diags = diags.Append(err)
|
||||
}
|
||||
|
||||
c.showDiagnostics(diags)
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/config"
|
||||
|
@ -76,47 +74,9 @@ func (c *RefreshCommand) Run(args []string) int {
|
|||
opReq.Type = backend.OperationTypeRefresh
|
||||
opReq.Module = mod
|
||||
|
||||
// Perform the operation
|
||||
op, err := b.Operation(context.Background(), opReq)
|
||||
op, err := c.RunOperation(b, opReq)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error starting operation: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Wait for the operation to complete or an interrupt to occur
|
||||
select {
|
||||
case <-c.ShutdownCh:
|
||||
// gracefully stop the operation
|
||||
op.Stop()
|
||||
|
||||
// Notify the user
|
||||
c.Ui.Output(outputInterrupt)
|
||||
|
||||
// Still get the result, since there is still one
|
||||
select {
|
||||
case <-c.ShutdownCh:
|
||||
c.Ui.Error(
|
||||
"Two interrupts received. Exiting immediately. Note that data\n" +
|
||||
"loss may have occurred.")
|
||||
|
||||
// cancel the operation completely
|
||||
op.Cancel()
|
||||
|
||||
// the operation should return asap
|
||||
// but timeout just in case
|
||||
select {
|
||||
case <-op.Done():
|
||||
case <-time.After(5 * time.Second):
|
||||
}
|
||||
|
||||
return 1
|
||||
|
||||
case <-op.Done():
|
||||
}
|
||||
case <-op.Done():
|
||||
if err := op.Err; err != nil {
|
||||
diags = diags.Append(err)
|
||||
}
|
||||
diags = diags.Append(err)
|
||||
}
|
||||
|
||||
c.showDiagnostics(diags)
|
||||
|
|
Loading…
Reference in New Issue