From 8dafcb36fdc85159409f77409872c5ad9ab31f7b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 15 Aug 2016 21:12:32 -0700 Subject: [PATCH] providers/azurerm: cancellable storage account creation --- .../azurerm/resource_arm_storage_account.go | 21 +++++++++++++++++-- helper/signalwrapper/wrapper.go | 5 +++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/builtin/providers/azurerm/resource_arm_storage_account.go b/builtin/providers/azurerm/resource_arm_storage_account.go index 059e92ecb..ecf206119 100644 --- a/builtin/providers/azurerm/resource_arm_storage_account.go +++ b/builtin/providers/azurerm/resource_arm_storage_account.go @@ -11,6 +11,7 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/storage" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/signalwrapper" ) func resourceArmStorageAccount() *schema.Resource { @@ -131,9 +132,25 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e Tags: expandTags(tags), } - _, err := storageClient.Create(resourceGroupName, storageAccountName, opts, make(chan struct{})) + // Create the storage account. We wrap this so that it is cancellable + // with a Ctrl-C since this can take a LONG time. + wrap := signalwrapper.Run(func(cancelCh <-chan struct{}) error { + _, err := storageClient.Create(resourceGroupName, storageAccountName, opts, cancelCh) + return err + }) + + // Check the result of the wrapped function. I put this into a select + // since we will likely also want to introduce a time-based timeout. + var err error + select { + case err = <-wrap.ErrCh: + // Successfully ran (but perhaps not successfully completed) + // the function. + } if err != nil { - return fmt.Errorf("Error creating Azure Storage Account '%s': %s", storageAccountName, err) + return fmt.Errorf( + "Error creating Azure Storage Account '%s': %s", + storageAccountName, err) } // The only way to get the ID back apparently is to read the resource again diff --git a/helper/signalwrapper/wrapper.go b/helper/signalwrapper/wrapper.go index 765661ece..185c963da 100644 --- a/helper/signalwrapper/wrapper.go +++ b/helper/signalwrapper/wrapper.go @@ -5,6 +5,7 @@ package signalwrapper import ( + "log" "os" "os/signal" "sync" @@ -49,6 +50,7 @@ func Run(f CancellableFunc) *Wrapped { // Start the function go func() { + log.Printf("[DEBUG] signalwrapper: executing wrapped function") err := f(cancelCh) // Close the done channel _before_ sending the error in case @@ -57,6 +59,7 @@ func Run(f CancellableFunc) *Wrapped { close(doneCh) // Mark completion + log.Printf("[DEBUG] signalwrapper: wrapped function execution ended") wrapped.done(err) }() @@ -71,6 +74,8 @@ func Run(f CancellableFunc) *Wrapped { case <-doneCh: // Everything happened naturally case <-sigCh: + log.Printf("[DEBUG] signalwrapper: signal received, cancelling wrapped function") + // Stop the function. Goroutine since we don't care about // the result and we'd like to end this goroutine as soon // as possible to avoid any more signals coming in.