github.com/svenhamers/terraform@v0.11.12-beta1/backend/remote/backend_context.go (about)

     1  package remote
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"log"
     8  	"strings"
     9  
    10  	"github.com/hashicorp/errwrap"
    11  	"github.com/hashicorp/terraform/backend"
    12  	"github.com/hashicorp/terraform/command/clistate"
    13  	"github.com/hashicorp/terraform/state"
    14  	"github.com/hashicorp/terraform/terraform"
    15  )
    16  
    17  // Context implements backend.Enhanced.
    18  func (b *Remote) Context(op *backend.Operation) (*terraform.Context, state.State, error) {
    19  	if op.LockState {
    20  		op.StateLocker = clistate.NewLocker(context.Background(), op.StateLockTimeout, b.CLI, b.cliColorize())
    21  	} else {
    22  		op.StateLocker = clistate.NewNoopLocker()
    23  	}
    24  
    25  	// Get the latest state.
    26  	log.Printf("[TRACE] backend/remote: requesting state manager for workspace %q", op.Workspace)
    27  	s, err := b.State(op.Workspace)
    28  	if err != nil {
    29  		return nil, nil, errwrap.Wrapf("Error loading state: {{err}}", err)
    30  	}
    31  
    32  	log.Printf("[TRACE] backend/remote: requesting state lock for workspace %q", op.Workspace)
    33  	if err := op.StateLocker.Lock(s, op.Type.String()); err != nil {
    34  		return nil, nil, errwrap.Wrapf("Error locking state: {{err}}", err)
    35  	}
    36  
    37  	log.Printf("[TRACE] backend/remote: reading remote state for workspace %q", op.Workspace)
    38  	if err := s.RefreshState(); err != nil {
    39  		return nil, nil, errwrap.Wrapf("Error loading state: {{err}}", err)
    40  	}
    41  
    42  	// Initialize our context options
    43  	var opts terraform.ContextOpts
    44  	if v := b.ContextOpts; v != nil {
    45  		opts = *v
    46  	}
    47  
    48  	// Copy set options from the operation
    49  	opts.Destroy = op.Destroy
    50  	opts.Module = op.Module
    51  	opts.Targets = op.Targets
    52  	opts.UIInput = op.UIIn
    53  
    54  	// Load the latest state. If we enter contextFromPlanFile below then the
    55  	// state snapshot in the plan file must match this, or else it'll return
    56  	// error diagnostics.
    57  	log.Printf("[TRACE] backend/remote: retrieving remote state snapshot for workspace %q", op.Workspace)
    58  	opts.State = s.State()
    59  
    60  	tfCtx, err := terraform.NewContext(&opts)
    61  
    62  	// any errors resolving plugins returns this
    63  	if rpe, ok := err.(*terraform.ResourceProviderError); ok {
    64  		b.pluginInitRequired(rpe)
    65  		// we wrote the full UI error here, so return a generic error for flow
    66  		// control in the command.
    67  		return nil, nil, errors.New("error satisfying plugin requirements")
    68  	}
    69  
    70  	if err != nil {
    71  		return nil, nil, err
    72  	}
    73  
    74  	log.Printf("[TRACE] backend/remote: finished building terraform.Context")
    75  
    76  	return tfCtx, s, nil
    77  }
    78  
    79  func (b *Remote) pluginInitRequired(providerErr *terraform.ResourceProviderError) {
    80  	b.CLI.Output(b.Colorize().Color(fmt.Sprintf(
    81  		strings.TrimSpace(errPluginInit)+"\n",
    82  		providerErr)))
    83  }
    84  
    85  // this relies on multierror to format the plugin errors below the copy
    86  const errPluginInit = `
    87  [reset][bold][yellow]Plugin reinitialization required. Please run "terraform init".[reset]
    88  [yellow]Reason: Could not satisfy plugin requirements.
    89  
    90  Plugins are external binaries that Terraform uses to access and manipulate
    91  resources. The configuration provided requires plugins which can't be located,
    92  don't satisfy the version constraints, or are otherwise incompatible.
    93  
    94  [reset][red]%s
    95  
    96  [reset][yellow]Terraform automatically discovers provider requirements from your
    97  configuration, including providers used in child modules. To see the
    98  requirements and constraints from each module, run "terraform providers".
    99  `