github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/backend/local/backend_refresh.go (about)

     1  package local
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  
     8  	"github.com/hashicorp/errwrap"
     9  	"github.com/hashicorp/go-multierror"
    10  	"github.com/hashicorp/terraform/backend"
    11  	clistate "github.com/hashicorp/terraform/command/state"
    12  	"github.com/hashicorp/terraform/config/module"
    13  	"github.com/hashicorp/terraform/state"
    14  )
    15  
    16  func (b *Local) opRefresh(
    17  	ctx context.Context,
    18  	op *backend.Operation,
    19  	runningOp *backend.RunningOperation) {
    20  	// Check if our state exists if we're performing a refresh operation. We
    21  	// only do this if we're managing state with this backend.
    22  	if b.Backend == nil {
    23  		if _, err := os.Stat(b.StatePath); err != nil {
    24  			if os.IsNotExist(err) {
    25  				runningOp.Err = fmt.Errorf(
    26  					"The Terraform state file for your infrastructure does not\n"+
    27  						"exist. The 'refresh' command only works and only makes sense\n"+
    28  						"when there is existing state that Terraform is managing. Please\n"+
    29  						"double-check the value given below and try again. If you\n"+
    30  						"haven't created infrastructure with Terraform yet, use the\n"+
    31  						"'terraform apply' command.\n\n"+
    32  						"Path: %s",
    33  					b.StatePath)
    34  				return
    35  			}
    36  
    37  			runningOp.Err = fmt.Errorf(
    38  				"There was an error reading the Terraform state that is needed\n"+
    39  					"for refreshing. The path and error are shown below.\n\n"+
    40  					"Path: %s\n\nError: %s",
    41  				b.StatePath, err)
    42  			return
    43  		}
    44  	}
    45  
    46  	// If we have no config module given to use, create an empty tree to
    47  	// avoid crashes when Terraform.Context is initialized.
    48  	if op.Module == nil {
    49  		op.Module = module.NewEmptyTree()
    50  	}
    51  
    52  	// Get our context
    53  	tfCtx, opState, err := b.context(op)
    54  	if err != nil {
    55  		runningOp.Err = err
    56  		return
    57  	}
    58  
    59  	if op.LockState {
    60  		lockInfo := state.NewLockInfo()
    61  		lockInfo.Operation = op.Type.String()
    62  		lockID, err := clistate.Lock(opState, lockInfo, b.CLI, b.Colorize())
    63  		if err != nil {
    64  			runningOp.Err = errwrap.Wrapf("Error locking state: {{err}}", err)
    65  			return
    66  		}
    67  
    68  		defer func() {
    69  			if err := clistate.Unlock(opState, lockID, b.CLI, b.Colorize()); err != nil {
    70  				runningOp.Err = multierror.Append(runningOp.Err, err)
    71  			}
    72  		}()
    73  	}
    74  
    75  	// Set our state
    76  	runningOp.State = opState.State()
    77  
    78  	// Perform operation and write the resulting state to the running op
    79  	newState, err := tfCtx.Refresh()
    80  	runningOp.State = newState
    81  	if err != nil {
    82  		runningOp.Err = errwrap.Wrapf("Error refreshing state: {{err}}", err)
    83  		return
    84  	}
    85  
    86  	// Write and persist the state
    87  	if err := opState.WriteState(newState); err != nil {
    88  		runningOp.Err = errwrap.Wrapf("Error writing state: {{err}}", err)
    89  		return
    90  	}
    91  	if err := opState.PersistState(); err != nil {
    92  		runningOp.Err = errwrap.Wrapf("Error saving state: {{err}}", err)
    93  		return
    94  	}
    95  }