command: Enable reading remote-enabled state
This commit is contained in:
parent
bf10111745
commit
53704db4ee
|
@ -42,6 +42,8 @@ type Meta struct {
|
|||
oldUi cli.Ui
|
||||
|
||||
// useRemoteState is enabled if we are using remote state storage
|
||||
// This is set when the context is loaded if we read from a remote
|
||||
// enabled state file.
|
||||
useRemoteState bool
|
||||
|
||||
// statePath is the path to the state file. If this is empty, then
|
||||
|
@ -106,25 +108,16 @@ func (m *Meta) Context(copts contextOpts) (*terraform.Context, bool, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Load up the state
|
||||
var state *terraform.State
|
||||
// Load the statePath if not given
|
||||
if copts.StatePath != "" {
|
||||
f, err := os.Open(copts.StatePath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
// If the state file doesn't exist, it is okay, since it
|
||||
// is probably a new infrastructure.
|
||||
err = nil
|
||||
} else if err == nil {
|
||||
state, err = terraform.ReadState(f)
|
||||
f.Close()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("Error loading state: %s", err)
|
||||
}
|
||||
m.statePath = copts.StatePath
|
||||
}
|
||||
|
||||
// Store the loaded state
|
||||
state, err := m.loadState()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
m.state = state
|
||||
|
||||
// Load the root module
|
||||
|
@ -171,6 +164,43 @@ func (m *Meta) UIInput() terraform.UIInput {
|
|||
}
|
||||
}
|
||||
|
||||
// laodState is used to load the Terraform state. We give precedence
|
||||
// to a remote state if enabled, and then check the normal state path.
|
||||
func (m *Meta) loadState() (*terraform.State, error) {
|
||||
// Check if we remote state is enabled
|
||||
localCache, _, err := remote.ReadLocalState()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error loading state: %s", err)
|
||||
}
|
||||
|
||||
// Set the state if enabled
|
||||
var state *terraform.State
|
||||
if localCache != nil {
|
||||
state = localCache
|
||||
m.useRemoteState = true
|
||||
}
|
||||
|
||||
// Load up the state
|
||||
if m.statePath != "" {
|
||||
f, err := os.Open(m.statePath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
// If the state file doesn't exist, it is okay, since it
|
||||
// is probably a new infrastructure.
|
||||
err = nil
|
||||
} else if m.useRemoteState && err == nil {
|
||||
err = fmt.Errorf("Remote state enabled, but state file '%s' also present.", m.statePath)
|
||||
f.Close()
|
||||
} else if err == nil {
|
||||
state, err = terraform.ReadState(f)
|
||||
f.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error loading state: %s", err)
|
||||
}
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// PersistState is used to write out the state, handling backup of
|
||||
// the existing state file and respecting path configurations.
|
||||
func (m *Meta) PersistState(s *terraform.State) error {
|
||||
|
|
|
@ -255,3 +255,78 @@ func TestMeta_persistRemote(t *testing.T) {
|
|||
t.Fatalf("backup should exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMeta_loadState_remote(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
|
||||
err := remote.EnsureDirectory()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
s := terraform.NewState()
|
||||
s.Serial = 1000
|
||||
if err := remote.PersistState(s); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
m := new(Meta)
|
||||
s1, err := m.loadState()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if s1.Serial < 1000 {
|
||||
t.Fatalf("Bad: %#v", s1)
|
||||
}
|
||||
|
||||
if !m.useRemoteState {
|
||||
t.Fatalf("should enable remote")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMeta_loadState_statePath(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
|
||||
m := new(Meta)
|
||||
|
||||
s := terraform.NewState()
|
||||
s.Serial = 1000
|
||||
if err := m.persistLocalState(s); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
s1, err := m.loadState()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if s1.Serial < 1000 {
|
||||
t.Fatalf("Bad: %#v", s1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMeta_loadState_conflict(t *testing.T) {
|
||||
tmp, cwd := testCwd(t)
|
||||
defer testFixCwd(t, tmp, cwd)
|
||||
|
||||
err := remote.EnsureDirectory()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
m := new(Meta)
|
||||
|
||||
s := terraform.NewState()
|
||||
if err := remote.PersistState(s); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if err := m.persistLocalState(s); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
_, err = m.loadState()
|
||||
if err == nil {
|
||||
t.Fatalf("should error with conflict")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue