github.com/loicalbertin/terraform@v0.6.15-0.20170626182346-8e2583055467/backend/init/init.go (about)

     1  // Package init contains the list of backends that can be initialized and
     2  // basic helper functions for initializing those backends.
     3  package init
     4  
     5  import (
     6  	"sync"
     7  
     8  	"github.com/hashicorp/terraform/backend"
     9  
    10  	backendatlas "github.com/hashicorp/terraform/backend/atlas"
    11  	backendlegacy "github.com/hashicorp/terraform/backend/legacy"
    12  	backendlocal "github.com/hashicorp/terraform/backend/local"
    13  	backendconsul "github.com/hashicorp/terraform/backend/remote-state/consul"
    14  	backendinmem "github.com/hashicorp/terraform/backend/remote-state/inmem"
    15  	backendS3 "github.com/hashicorp/terraform/backend/remote-state/s3"
    16  )
    17  
    18  // backends is the list of available backends. This is a global variable
    19  // because backends are currently hardcoded into Terraform and can't be
    20  // modified without recompilation.
    21  //
    22  // To read an available backend, use the Backend function. This ensures
    23  // safe concurrent read access to the list of built-in backends.
    24  //
    25  // Backends are hardcoded into Terraform because the API for backends uses
    26  // complex structures and supporting that over the plugin system is currently
    27  // prohibitively difficult. For those wanting to implement a custom backend,
    28  // they can do so with recompilation.
    29  var backends map[string]func() backend.Backend
    30  var backendsLock sync.Mutex
    31  
    32  func init() {
    33  	// Our hardcoded backends. We don't need to acquire a lock here
    34  	// since init() code is serial and can't spawn goroutines.
    35  	backends = map[string]func() backend.Backend{
    36  		"atlas":  func() backend.Backend { return &backendatlas.Backend{} },
    37  		"local":  func() backend.Backend { return &backendlocal.Local{} },
    38  		"consul": func() backend.Backend { return backendconsul.New() },
    39  		"inmem":  func() backend.Backend { return backendinmem.New() },
    40  		"s3":     func() backend.Backend { return backendS3.New() },
    41  	}
    42  
    43  	// Add the legacy remote backends that haven't yet been convertd to
    44  	// the new backend API.
    45  	backendlegacy.Init(backends)
    46  }
    47  
    48  // Backend returns the initialization factory for the given backend, or
    49  // nil if none exists.
    50  func Backend(name string) func() backend.Backend {
    51  	backendsLock.Lock()
    52  	defer backendsLock.Unlock()
    53  	return backends[name]
    54  }
    55  
    56  // Set sets a new backend in the list of backends. If f is nil then the
    57  // backend will be removed from the map. If this backend already exists
    58  // then it will be overwritten.
    59  //
    60  // This method sets this backend globally and care should be taken to do
    61  // this only before Terraform is executing to prevent odd behavior of backends
    62  // changing mid-execution.
    63  func Set(name string, f func() backend.Backend) {
    64  	backendsLock.Lock()
    65  	defer backendsLock.Unlock()
    66  
    67  	if f == nil {
    68  		delete(backends, name)
    69  		return
    70  	}
    71  
    72  	backends[name] = f
    73  }