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.
pull/16816/head
James Bardin 9 years ago
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…
Cancel
Save