make plans cancellable
There was no cancellation context for a plan, so it would always have to run to completion as SIGINT was being swallowed. Move the shutdown channel to the command Meta since it's used in multiple commands.
This commit is contained in:
parent
8891694762
commit
3aaa1e9d04
|
@ -24,9 +24,6 @@ type ApplyCommand struct {
|
|||
// If true, then this apply command will become the "destroy"
|
||||
// command. It is just like apply but only processes a destroy.
|
||||
Destroy bool
|
||||
|
||||
// When this channel is closed, the apply will be cancelled.
|
||||
ShutdownCh <-chan struct{}
|
||||
}
|
||||
|
||||
func (c *ApplyCommand) Run(args []string) int {
|
||||
|
|
|
@ -837,9 +837,8 @@ func TestApply_shutdown(t *testing.T) {
|
|||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(p),
|
||||
Ui: ui,
|
||||
ShutdownCh: shutdownCh,
|
||||
},
|
||||
|
||||
ShutdownCh: shutdownCh,
|
||||
}
|
||||
|
||||
p.DiffFn = func(
|
||||
|
|
|
@ -17,9 +17,6 @@ import (
|
|||
// configuration and actually builds or changes infrastructure.
|
||||
type ConsoleCommand struct {
|
||||
Meta
|
||||
|
||||
// When this channel is closed, the apply will be cancelled.
|
||||
ShutdownCh <-chan struct{}
|
||||
}
|
||||
|
||||
func (c *ConsoleCommand) Run(args []string) int {
|
||||
|
|
|
@ -76,6 +76,9 @@ type Meta struct {
|
|||
// is not suitable, e.g. because of a read-only filesystem.
|
||||
OverrideDataDir string
|
||||
|
||||
// When this channel is closed, the command will be cancelled.
|
||||
ShutdownCh <-chan struct{}
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Protected: commands can set these
|
||||
//----------------------------------------------------------
|
||||
|
|
|
@ -104,17 +104,35 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
opReq.Type = backend.OperationTypePlan
|
||||
|
||||
// Perform the operation
|
||||
op, err := b.Operation(context.Background(), opReq)
|
||||
ctx, ctxCancel := context.WithCancel(context.Background())
|
||||
defer ctxCancel()
|
||||
|
||||
op, err := b.Operation(ctx, opReq)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error starting operation: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Wait for the operation to complete
|
||||
<-op.Done()
|
||||
if err := op.Err; err != nil {
|
||||
c.showDiagnostics(err)
|
||||
return 1
|
||||
select {
|
||||
case <-c.ShutdownCh:
|
||||
// Cancel our context so we can start gracefully exiting
|
||||
ctxCancel()
|
||||
// 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")
|
||||
return 1
|
||||
case <-op.Done():
|
||||
}
|
||||
case <-op.Done():
|
||||
if err := op.Err; err != nil {
|
||||
c.showDiagnostics(err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue