diff --git a/backend/atlas/backend.go b/backend/atlas/backend.go index 9cd15d424..a86983829 100644 --- a/backend/atlas/backend.go +++ b/backend/atlas/backend.go @@ -7,13 +7,13 @@ import ( "strings" "sync" + "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/tfdiags" "github.com/zclconf/go-cty/cty" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/configs/configschema" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/cli" "github.com/mitchellh/colorstring" @@ -171,7 +171,7 @@ func (b *Backend) DeleteWorkspace(name string) error { return backend.ErrWorkspacesNotSupported } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { if name != backend.DefaultStateName { return nil, backend.ErrWorkspacesNotSupported } diff --git a/backend/atlas/state_client.go b/backend/atlas/state_client.go index 0e15ff17d..e954c791e 100644 --- a/backend/atlas/state_client.go +++ b/backend/atlas/state_client.go @@ -18,7 +18,7 @@ import ( "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-retryablehttp" "github.com/hashicorp/go-rootcerts" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/terraform" ) diff --git a/backend/atlas/state_client_test.go b/backend/atlas/state_client_test.go index 0e4795c70..eaec7fb7b 100644 --- a/backend/atlas/state_client_test.go +++ b/backend/atlas/state_client_test.go @@ -20,7 +20,7 @@ import ( "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/helper/acctest" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/terraform" ) diff --git a/backend/backend.go b/backend/backend.go index 268b52f67..391a89246 100644 --- a/backend/backend.go +++ b/backend/backend.go @@ -211,7 +211,7 @@ type Operation struct { UIOut terraform.UIOutput // If LockState is true, the Operation must Lock any - // state.Lockers for its duration, and Unlock when complete. + // statemgr.Lockers for its duration, and Unlock when complete. LockState bool // StateLocker is used to lock the state while providing UI feedback to the diff --git a/backend/local/hook_state.go b/backend/local/hook_state.go index a2f78475a..c54f22371 100644 --- a/backend/local/hook_state.go +++ b/backend/local/hook_state.go @@ -9,7 +9,7 @@ import ( ) // StateHook is a hook that continuously updates the state by calling -// WriteState on a state.State. +// WriteState on a statemgr.Full. type StateHook struct { terraform.NilHook sync.Mutex diff --git a/backend/local/hook_state_test.go b/backend/local/hook_state_test.go index 4dc106b92..715f7d27a 100644 --- a/backend/local/hook_state_test.go +++ b/backend/local/hook_state_test.go @@ -3,7 +3,6 @@ package local import ( "testing" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" ) @@ -16,7 +15,7 @@ func TestStateHook(t *testing.T) { is := statemgr.NewTransientInMemory(nil) var hook terraform.Hook = &StateHook{StateMgr: is} - s := state.TestStateInitial() + s := statemgr.TestFullInitialState() action, err := hook.PostStateUpdate(s) if err != nil { t.Fatalf("err: %s", err) diff --git a/backend/remote-state/artifactory/backend.go b/backend/remote-state/artifactory/backend.go index 775584a51..2062968af 100644 --- a/backend/remote-state/artifactory/backend.go +++ b/backend/remote-state/artifactory/backend.go @@ -6,8 +6,8 @@ import ( cleanhttp "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" artifactory "github.com/lusis/go-artifactory/src/artifactory.v401" ) @@ -92,7 +92,7 @@ func (b *Backend) DeleteWorkspace(string) error { return backend.ErrWorkspacesNotSupported } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { if name != backend.DefaultStateName { return nil, backend.ErrWorkspacesNotSupported } diff --git a/backend/remote-state/artifactory/client.go b/backend/remote-state/artifactory/client.go index 030c54b78..b6f280e1e 100644 --- a/backend/remote-state/artifactory/client.go +++ b/backend/remote-state/artifactory/client.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" artifactory "github.com/lusis/go-artifactory/src/artifactory.v401" ) diff --git a/backend/remote-state/artifactory/client_test.go b/backend/remote-state/artifactory/client_test.go index 3e5cb06bd..ebc1a2817 100644 --- a/backend/remote-state/artifactory/client_test.go +++ b/backend/remote-state/artifactory/client_test.go @@ -5,7 +5,7 @@ import ( "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/configs" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/zclconf/go-cty/cty" ) diff --git a/backend/remote-state/azure/backend_state.go b/backend/remote-state/azure/backend_state.go index 07c15ffdc..e7d316287 100644 --- a/backend/remote-state/azure/backend_state.go +++ b/backend/remote-state/azure/backend_state.go @@ -7,9 +7,9 @@ import ( "strings" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs" "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/containers" ) @@ -78,7 +78,7 @@ func (b *Backend) DeleteWorkspace(name string) error { return nil } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { ctx := context.TODO() blobClient, err := b.armClient.getBlobClient(ctx) if err != nil { @@ -99,7 +99,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { //it's listed by States. if name != backend.DefaultStateName { // take a lock on this state while we write it - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockId, err := client.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/azure/client.go b/backend/remote-state/azure/client.go index 23dcba3a4..6c120e722 100644 --- a/backend/remote-state/azure/client.go +++ b/backend/remote-state/azure/client.go @@ -11,8 +11,8 @@ import ( "github.com/hashicorp/go-uuid" "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) const ( @@ -116,7 +116,7 @@ func (c *RemoteClient) Delete() error { return nil } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { stateName := fmt.Sprintf("%s/%s", c.containerName, c.keyName) info.Path = stateName @@ -135,7 +135,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { err = multierror.Append(err, infoErr) } - return &state.LockError{ + return &statemgr.LockError{ Err: err, Info: lockInfo, } @@ -187,7 +187,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { return info.ID, nil } -func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { +func (c *RemoteClient) getLockInfo() (*statemgr.LockInfo, error) { options := blobs.GetPropertiesInput{} if c.leaseID != "" { options.LeaseID = &c.leaseID @@ -209,7 +209,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { return nil, err } - lockInfo := &state.LockInfo{} + lockInfo := &statemgr.LockInfo{} err = json.Unmarshal(data, lockInfo) if err != nil { return nil, err @@ -219,7 +219,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { } // writes info to blob meta data, deletes metadata entry if info is nil -func (c *RemoteClient) writeLockInfo(info *state.LockInfo) error { +func (c *RemoteClient) writeLockInfo(info *statemgr.LockInfo) error { ctx := context.TODO() blob, err := c.giovanniBlobClient.GetProperties(ctx, c.accountName, c.containerName, c.keyName, blobs.GetPropertiesInput{LeaseID: &c.leaseID}) if err != nil { @@ -246,7 +246,7 @@ func (c *RemoteClient) writeLockInfo(info *state.LockInfo) error { } func (c *RemoteClient) Unlock(id string) error { - lockErr := &state.LockError{} + lockErr := &statemgr.LockError{} lockInfo, err := c.getLockInfo() if err != nil { diff --git a/backend/remote-state/azure/client_test.go b/backend/remote-state/azure/client_test.go index 8112d7177..45af094aa 100644 --- a/backend/remote-state/azure/client_test.go +++ b/backend/remote-state/azure/client_test.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/helper/acctest" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs" ) diff --git a/backend/remote-state/consul/backend_state.go b/backend/remote-state/consul/backend_state.go index bdcc9da98..30a12afea 100644 --- a/backend/remote-state/consul/backend_state.go +++ b/backend/remote-state/consul/backend_state.go @@ -5,9 +5,8 @@ import ( "strings" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/states/statemgr" ) @@ -93,7 +92,7 @@ func (b *Backend) StateMgr(name string) (statemgr.Full, error) { // Grab a lock, we use this to write an empty state if one doesn't // exist already. We have to write an empty state as a sentinel value // so States() knows it exists. - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockId, err := stateMgr.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/consul/client.go b/backend/remote-state/consul/client.go index bd37712f3..6007761ee 100644 --- a/backend/remote-state/consul/client.go +++ b/backend/remote-state/consul/client.go @@ -14,8 +14,8 @@ import ( consulapi "github.com/hashicorp/consul/api" multierror "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) const ( @@ -54,7 +54,7 @@ type RemoteClient struct { consulLock *consulapi.Lock lockCh <-chan struct{} - info *state.LockInfo + info *statemgr.LockInfo // cancel our goroutine which is monitoring the lock to automatically // reacquire it when possible. @@ -161,7 +161,7 @@ func (c *RemoteClient) Delete() error { return err } -func (c *RemoteClient) putLockInfo(info *state.LockInfo) error { +func (c *RemoteClient) putLockInfo(info *statemgr.LockInfo) error { info.Path = c.Path info.Created = time.Now().UTC() @@ -174,7 +174,7 @@ func (c *RemoteClient) putLockInfo(info *state.LockInfo) error { return err } -func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { +func (c *RemoteClient) getLockInfo() (*statemgr.LockInfo, error) { path := c.Path + lockInfoSuffix pair, _, err := c.Client.KV().Get(path, nil) if err != nil { @@ -184,7 +184,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { return nil, nil } - li := &state.LockInfo{} + li := &statemgr.LockInfo{} err = json.Unmarshal(pair.Value, li) if err != nil { return nil, fmt.Errorf("error unmarshaling lock info: %s", err) @@ -193,7 +193,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { return li, nil } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { c.mu.Lock() defer c.mu.Unlock() @@ -260,7 +260,7 @@ func (c *RemoteClient) lock() (string, error) { return "", err } - lockErr := &state.LockError{} + lockErr := &statemgr.LockError{} lockCh, err := c.consulLock.Lock(make(chan struct{})) if err != nil { diff --git a/backend/remote-state/consul/client_test.go b/backend/remote-state/consul/client_test.go index 97d9dd89d..9b5d2a53f 100644 --- a/backend/remote-state/consul/client_test.go +++ b/backend/remote-state/consul/client_test.go @@ -9,8 +9,8 @@ import ( "time" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) func TestRemoteClient_impl(t *testing.T) { @@ -109,7 +109,7 @@ func TestConsul_destroyLock(t *testing.T) { c := s.(*remote.State).Client.(*RemoteClient) - info := state.NewLockInfo() + info := statemgr.NewLockInfo() id, err := c.Lock(info) if err != nil { t.Fatal(err) @@ -151,7 +151,7 @@ func TestConsul_lostLock(t *testing.T) { t.Fatal(err) } - info := state.NewLockInfo() + info := statemgr.NewLockInfo() info.Operation = "test-lost-lock" id, err := sA.Lock(info) if err != nil { @@ -200,7 +200,7 @@ func TestConsul_lostLockConnection(t *testing.T) { t.Fatal(err) } - info := state.NewLockInfo() + info := statemgr.NewLockInfo() info.Operation = "test-lost-lock-connection" id, err := s.Lock(info) if err != nil { diff --git a/backend/remote-state/cos/backend_state.go b/backend/remote-state/cos/backend_state.go index 2bc3f2428..7784ab4ff 100644 --- a/backend/remote-state/cos/backend_state.go +++ b/backend/remote-state/cos/backend_state.go @@ -8,9 +8,9 @@ import ( "strings" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" "github.com/likexian/gokit/assert" ) @@ -74,7 +74,7 @@ func (b *Backend) DeleteWorkspace(name string) error { } // StateMgr manage the state, if the named state not exists, a new file will created -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { log.Printf("[DEBUG] state manager, current workspace: %v", name) c, err := b.client(name) @@ -92,7 +92,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { log.Printf("[DEBUG] workspace %v not exists", name) // take a lock on this state while we write it - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockId, err := c.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/cos/backend_test.go b/backend/remote-state/cos/backend_test.go index b372571af..81200de93 100644 --- a/backend/remote-state/cos/backend_test.go +++ b/backend/remote-state/cos/backend_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/likexian/gokit/assert" ) diff --git a/backend/remote-state/cos/client.go b/backend/remote-state/cos/client.go index 281fd2b7a..c3bf1055f 100644 --- a/backend/remote-state/cos/client.go +++ b/backend/remote-state/cos/client.go @@ -13,8 +13,8 @@ import ( "time" multierror "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" tag "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag/v20180813" "github.com/tencentyun/cos-go-sdk-v5" ) @@ -72,7 +72,7 @@ func (c *remoteClient) Delete() error { } // Lock lock remote state file for writing -func (c *remoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *remoteClient) Lock(info *statemgr.LockInfo) (string, error) { log.Printf("[DEBUG] lock remote state file %s", c.lockFile) err := c.cosLock(c.bucket, c.lockFile) @@ -126,11 +126,11 @@ func (c *remoteClient) Unlock(check string) error { return nil } -// lockError returns state.LockError -func (c *remoteClient) lockError(err error) *state.LockError { +// lockError returns statemgr.LockError +func (c *remoteClient) lockError(err error) *statemgr.LockError { log.Printf("[DEBUG] failed to lock or unlock %s: %v", c.lockFile, err) - lockErr := &state.LockError{ + lockErr := &statemgr.LockError{ Err: err, } @@ -145,7 +145,7 @@ func (c *remoteClient) lockError(err error) *state.LockError { } // lockInfo returns LockInfo from lock file -func (c *remoteClient) lockInfo() (*state.LockInfo, error) { +func (c *remoteClient) lockInfo() (*statemgr.LockInfo, error) { exists, data, checksum, err := c.getObject(c.lockFile) if err != nil { return nil, err @@ -155,7 +155,7 @@ func (c *remoteClient) lockInfo() (*state.LockInfo, error) { return nil, fmt.Errorf("lock file %s not exists", c.lockFile) } - info := &state.LockInfo{} + info := &statemgr.LockInfo{} if err := json.Unmarshal(data, info); err != nil { return nil, err } diff --git a/backend/remote-state/etcdv2/backend.go b/backend/remote-state/etcdv2/backend.go index aa0305632..9f9fa0904 100644 --- a/backend/remote-state/etcdv2/backend.go +++ b/backend/remote-state/etcdv2/backend.go @@ -9,8 +9,8 @@ import ( etcdapi "github.com/coreos/etcd/client" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) func New() backend.Backend { @@ -83,7 +83,7 @@ func (b *Backend) DeleteWorkspace(string) error { return backend.ErrWorkspacesNotSupported } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { if name != backend.DefaultStateName { return nil, backend.ErrWorkspacesNotSupported } diff --git a/backend/remote-state/etcdv2/client.go b/backend/remote-state/etcdv2/client.go index faf891ac9..eb7517ca0 100644 --- a/backend/remote-state/etcdv2/client.go +++ b/backend/remote-state/etcdv2/client.go @@ -6,7 +6,7 @@ import ( "fmt" etcdapi "github.com/coreos/etcd/client" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" ) // EtcdClient is a remote client that stores data in etcd. diff --git a/backend/remote-state/etcdv2/client_test.go b/backend/remote-state/etcdv2/client_test.go index c99e68ef3..a212c5fcd 100644 --- a/backend/remote-state/etcdv2/client_test.go +++ b/backend/remote-state/etcdv2/client_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/configs" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/zclconf/go-cty/cty" ) diff --git a/backend/remote-state/etcdv3/backend_state.go b/backend/remote-state/etcdv3/backend_state.go index 44bf0c588..1b8b1882e 100644 --- a/backend/remote-state/etcdv3/backend_state.go +++ b/backend/remote-state/etcdv3/backend_state.go @@ -9,9 +9,9 @@ import ( etcdv3 "github.com/coreos/etcd/clientv3" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) func (b *Backend) Workspaces() ([]string, error) { @@ -41,8 +41,8 @@ func (b *Backend) DeleteWorkspace(name string) error { return err } -func (b *Backend) StateMgr(name string) (state.State, error) { - var stateMgr state.State = &remote.State{ +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { + var stateMgr statemgr.Full = &remote.State{ Client: &RemoteClient{ Client: b.client, DoLock: b.lock, @@ -51,10 +51,10 @@ func (b *Backend) StateMgr(name string) (state.State, error) { } if !b.lock { - stateMgr = &state.LockDisabled{Inner: stateMgr} + stateMgr = &statemgr.LockDisabled{Inner: stateMgr} } - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockId, err := stateMgr.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/etcdv3/client.go b/backend/remote-state/etcdv3/client.go index 155e8d8c1..117c951a8 100644 --- a/backend/remote-state/etcdv3/client.go +++ b/backend/remote-state/etcdv3/client.go @@ -11,8 +11,8 @@ import ( etcdv3 "github.com/coreos/etcd/clientv3" etcdv3sync "github.com/coreos/etcd/clientv3/concurrency" "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) const ( @@ -28,7 +28,7 @@ type RemoteClient struct { etcdMutex *etcdv3sync.Mutex etcdSession *etcdv3sync.Session - info *state.LockInfo + info *statemgr.LockInfo mu sync.Mutex modRevision int64 } @@ -92,7 +92,7 @@ func (c *RemoteClient) Delete() error { return err } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { c.mu.Lock() defer c.mu.Unlock() @@ -118,7 +118,7 @@ func (c *RemoteClient) Unlock(id string) error { return c.unlock(id) } -func (c *RemoteClient) deleteLockInfo(info *state.LockInfo) error { +func (c *RemoteClient) deleteLockInfo(info *statemgr.LockInfo) error { res, err := c.Client.KV.Delete(context.TODO(), c.Key+lockInfoSuffix) if err != nil { return err @@ -129,7 +129,7 @@ func (c *RemoteClient) deleteLockInfo(info *state.LockInfo) error { return nil } -func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { +func (c *RemoteClient) getLockInfo() (*statemgr.LockInfo, error) { res, err := c.Client.KV.Get(context.TODO(), c.Key+lockInfoSuffix) if err != nil { return nil, err @@ -138,7 +138,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { return nil, nil } - li := &state.LockInfo{} + li := &statemgr.LockInfo{} err = json.Unmarshal(res.Kvs[0].Value, li) if err != nil { return nil, fmt.Errorf("Error unmarshaling lock info: %s.", err) @@ -147,7 +147,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { return li, nil } -func (c *RemoteClient) putLockInfo(info *state.LockInfo) error { +func (c *RemoteClient) putLockInfo(info *statemgr.LockInfo) error { c.info.Path = c.etcdMutex.Key() c.info.Created = time.Now().UTC() @@ -168,9 +168,9 @@ func (c *RemoteClient) lock() (string, error) { if err1 := mutex.Lock(ctx); err1 != nil { lockInfo, err2 := c.getLockInfo() if err2 != nil { - return "", &state.LockError{Err: err2} + return "", &statemgr.LockError{Err: err2} } - return "", &state.LockError{Info: lockInfo, Err: err1} + return "", &statemgr.LockError{Info: lockInfo, Err: err1} } c.etcdMutex = mutex diff --git a/backend/remote-state/etcdv3/client_test.go b/backend/remote-state/etcdv3/client_test.go index 447f72948..8abb22a78 100644 --- a/backend/remote-state/etcdv3/client_test.go +++ b/backend/remote-state/etcdv3/client_test.go @@ -7,8 +7,8 @@ import ( "time" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) func TestRemoteClient_impl(t *testing.T) { @@ -83,7 +83,7 @@ func TestEtcdv3_destroyLock(t *testing.T) { c := s.(*remote.State).Client.(*RemoteClient) - info := state.NewLockInfo() + info := statemgr.NewLockInfo() id, err := c.Lock(info) if err != nil { t.Fatal(err) diff --git a/backend/remote-state/gcs/backend_state.go b/backend/remote-state/gcs/backend_state.go index 835ad96a7..d4916190f 100644 --- a/backend/remote-state/gcs/backend_state.go +++ b/backend/remote-state/gcs/backend_state.go @@ -10,9 +10,9 @@ import ( "google.golang.org/api/iterator" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) const ( @@ -86,7 +86,7 @@ func (b *Backend) client(name string) (*remoteClient, error) { // StateMgr reads and returns the named state from GCS. If the named state does // not yet exist, a new state file is created. -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { c, err := b.client(name) if err != nil { return nil, err @@ -102,7 +102,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { // If we have no state, we have to create an empty state if v := st.State(); v == nil { - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockID, err := st.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/gcs/backend_test.go b/backend/remote-state/gcs/backend_test.go index 6944d9388..6d71cb341 100644 --- a/backend/remote-state/gcs/backend_test.go +++ b/backend/remote-state/gcs/backend_test.go @@ -10,7 +10,7 @@ import ( "cloud.google.com/go/storage" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" ) const ( diff --git a/backend/remote-state/gcs/client.go b/backend/remote-state/gcs/client.go index 5163ba0c2..4f23434c3 100644 --- a/backend/remote-state/gcs/client.go +++ b/backend/remote-state/gcs/client.go @@ -8,8 +8,8 @@ import ( "cloud.google.com/go/storage" multierror "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" "golang.org/x/net/context" ) @@ -79,7 +79,7 @@ func (c *remoteClient) Delete() error { // Lock writes to a lock file, ensuring file creation. Returns the generation // number, which must be passed to Unlock(). -func (c *remoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *remoteClient) Lock(info *statemgr.LockInfo) (string, error) { // update the path we're using // we can't set the ID until the info is written info.Path = c.lockFileURL() @@ -120,8 +120,8 @@ func (c *remoteClient) Unlock(id string) error { return nil } -func (c *remoteClient) lockError(err error) *state.LockError { - lockErr := &state.LockError{ +func (c *remoteClient) lockError(err error) *statemgr.LockError { + lockErr := &statemgr.LockError{ Err: err, } @@ -136,7 +136,7 @@ func (c *remoteClient) lockError(err error) *state.LockError { // lockInfo reads the lock file, parses its contents and returns the parsed // LockInfo struct. -func (c *remoteClient) lockInfo() (*state.LockInfo, error) { +func (c *remoteClient) lockInfo() (*statemgr.LockInfo, error) { r, err := c.lockFile().NewReader(c.storageContext) if err != nil { return nil, err @@ -148,7 +148,7 @@ func (c *remoteClient) lockInfo() (*state.LockInfo, error) { return nil, err } - info := &state.LockInfo{} + info := &statemgr.LockInfo{} if err := json.Unmarshal(rawData, info); err != nil { return nil, err } diff --git a/backend/remote-state/http/backend.go b/backend/remote-state/http/backend.go index ea5d8772b..4446ff67c 100644 --- a/backend/remote-state/http/backend.go +++ b/backend/remote-state/http/backend.go @@ -12,8 +12,8 @@ import ( "github.com/hashicorp/go-retryablehttp" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) func New() backend.Backend { @@ -175,7 +175,7 @@ func (b *Backend) configure(ctx context.Context) error { return nil } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { if name != backend.DefaultStateName { return nil, backend.ErrWorkspacesNotSupported } diff --git a/backend/remote-state/http/client.go b/backend/remote-state/http/client.go index 152d26689..9dd91ff24 100644 --- a/backend/remote-state/http/client.go +++ b/backend/remote-state/http/client.go @@ -12,8 +12,8 @@ import ( "net/url" "github.com/hashicorp/go-retryablehttp" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) // httpClient is a remote client that stores data in Consul or HTTP REST. @@ -74,7 +74,7 @@ func (c *httpClient) httpRequest(method string, url *url.URL, data *[]byte, what return resp, nil } -func (c *httpClient) Lock(info *state.LockInfo) (string, error) { +func (c *httpClient) Lock(info *statemgr.LockInfo) (string, error) { if c.LockURL == nil { return "", nil } @@ -102,7 +102,7 @@ func (c *httpClient) Lock(info *state.LockInfo) (string, error) { if err != nil { return "", fmt.Errorf("HTTP remote state already locked, failed to read body") } - existing := state.LockInfo{} + existing := statemgr.LockInfo{} err = json.Unmarshal(body, &existing) if err != nil { return "", fmt.Errorf("HTTP remote state already locked, failed to unmarshal body") diff --git a/backend/remote-state/http/client_test.go b/backend/remote-state/http/client_test.go index c05be2098..c9bce3b78 100644 --- a/backend/remote-state/http/client_test.go +++ b/backend/remote-state/http/client_test.go @@ -11,7 +11,7 @@ import ( "testing" "github.com/hashicorp/go-retryablehttp" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" ) func TestHTTPClient_impl(t *testing.T) { diff --git a/backend/remote-state/inmem/backend.go b/backend/remote-state/inmem/backend.go index c25a80502..1a974a05b 100644 --- a/backend/remote-state/inmem/backend.go +++ b/backend/remote-state/inmem/backend.go @@ -10,9 +10,9 @@ import ( "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" statespkg "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) // we keep the states and locks in package-level variables, so that they can be @@ -36,7 +36,7 @@ func Reset() { } locks = lockMap{ - m: map[string]*state.LockInfo{}, + m: map[string]*statemgr.LockInfo{}, } } @@ -76,7 +76,7 @@ func (b *Backend) configure(ctx context.Context) error { // set the default client lock info per the test config data := schema.FromContextBackendConfig(ctx) if v, ok := data.GetOk("lock_id"); ok && v.(string) != "" { - info := state.NewLockInfo() + info := statemgr.NewLockInfo() info.ID = v.(string) info.Operation = "test" info.Info = "test config" @@ -113,7 +113,7 @@ func (b *Backend) DeleteWorkspace(name string) error { return nil } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { states.Lock() defer states.Unlock() @@ -128,7 +128,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { // to most closely replicate other implementations, we are going to // take a lock and create a new state if it doesn't exist. - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockID, err := s.Lock(lockInfo) if err != nil { @@ -158,16 +158,16 @@ type stateMap struct { // Global level locks for inmem backends. type lockMap struct { sync.Mutex - m map[string]*state.LockInfo + m map[string]*statemgr.LockInfo } -func (l *lockMap) lock(name string, info *state.LockInfo) (string, error) { +func (l *lockMap) lock(name string, info *statemgr.LockInfo) (string, error) { l.Lock() defer l.Unlock() lockInfo := l.m[name] if lockInfo != nil { - lockErr := &state.LockError{ + lockErr := &statemgr.LockError{ Info: lockInfo, } @@ -193,8 +193,8 @@ func (l *lockMap) unlock(name, id string) error { return errors.New("state not locked") } - lockErr := &state.LockError{ - Info: &state.LockInfo{}, + lockErr := &statemgr.LockError{ + Info: &statemgr.LockInfo{}, } if id != lockInfo.ID { diff --git a/backend/remote-state/inmem/backend_test.go b/backend/remote-state/inmem/backend_test.go index d47af944c..a6ac0694e 100644 --- a/backend/remote-state/inmem/backend_test.go +++ b/backend/remote-state/inmem/backend_test.go @@ -11,8 +11,8 @@ import ( "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/helper/logging" - "github.com/hashicorp/terraform/state/remote" statespkg "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" ) func TestMain(m *testing.M) { diff --git a/backend/remote-state/inmem/client.go b/backend/remote-state/inmem/client.go index 51c8d7251..21f229bda 100644 --- a/backend/remote-state/inmem/client.go +++ b/backend/remote-state/inmem/client.go @@ -3,8 +3,8 @@ package inmem import ( "crypto/md5" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) // RemoteClient is a remote client that stores data in memory for testing. @@ -39,7 +39,7 @@ func (c *RemoteClient) Delete() error { return nil } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { return locks.lock(c.Name, info) } func (c *RemoteClient) Unlock(id string) error { diff --git a/backend/remote-state/inmem/client_test.go b/backend/remote-state/inmem/client_test.go index 68396512b..765eac9ee 100644 --- a/backend/remote-state/inmem/client_test.go +++ b/backend/remote-state/inmem/client_test.go @@ -5,7 +5,7 @@ import ( "github.com/hashicorp/hcl/v2" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" ) func TestRemoteClient_impl(t *testing.T) { diff --git a/backend/remote-state/kubernetes/backend_state.go b/backend/remote-state/kubernetes/backend_state.go index 88f4dcbdd..f9c3c76d5 100644 --- a/backend/remote-state/kubernetes/backend_state.go +++ b/backend/remote-state/kubernetes/backend_state.go @@ -6,9 +6,9 @@ import ( "sort" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -71,7 +71,7 @@ func (b *Backend) DeleteWorkspace(name string) error { return client.Delete() } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { c, err := b.remoteClient(name) if err != nil { return nil, err @@ -87,7 +87,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { // If we have no state, we have to create an empty state if v := stateMgr.State(); v == nil { - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockID, err := stateMgr.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/kubernetes/backend_test.go b/backend/remote-state/kubernetes/backend_test.go index 11e72a469..acb3f572e 100644 --- a/backend/remote-state/kubernetes/backend_test.go +++ b/backend/remote-state/kubernetes/backend_test.go @@ -9,7 +9,6 @@ import ( "time" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states/statemgr" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -100,7 +99,7 @@ func TestBackendLocksSoak(t *testing.T) { go func(locker statemgr.Locker, n int) { defer wg.Done() - li := state.NewLockInfo() + li := statemgr.NewLockInfo() li.Operation = "test" li.Who = fmt.Sprintf("client-%v", n) diff --git a/backend/remote-state/kubernetes/client.go b/backend/remote-state/kubernetes/client.go index 894ebe859..5bc57f6bb 100644 --- a/backend/remote-state/kubernetes/client.go +++ b/backend/remote-state/kubernetes/client.go @@ -10,8 +10,8 @@ import ( "fmt" "strings" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -143,7 +143,7 @@ func (c *RemoteClient) Delete() error { return nil } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { leaseName, err := c.createLeaseName() if err != nil { return "", err @@ -187,7 +187,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { return "", err } - lockErr := &state.LockError{ + lockErr := &statemgr.LockError{ Info: currentLockInfo, Err: errors.New("the state is already locked by another terraform client"), } @@ -224,7 +224,7 @@ func (c *RemoteClient) Unlock(id string) error { return err } - lockErr := &state.LockError{Info: lockInfo} + lockErr := &statemgr.LockError{Info: lockInfo} if *lease.Spec.HolderIdentity != id { lockErr.Err = fmt.Errorf("lock id %q does not match existing lock", id) return lockErr @@ -242,13 +242,13 @@ func (c *RemoteClient) Unlock(id string) error { return nil } -func (c *RemoteClient) getLockInfo(lease *coordinationv1.Lease) (*state.LockInfo, error) { +func (c *RemoteClient) getLockInfo(lease *coordinationv1.Lease) (*statemgr.LockInfo, error) { lockData, ok := getLockInfo(lease) if len(lockData) == 0 || !ok { return nil, nil } - lockInfo := &state.LockInfo{} + lockInfo := &statemgr.LockInfo{} err := json.Unmarshal(lockData, lockInfo) if err != nil { return nil, err diff --git a/backend/remote-state/kubernetes/client_test.go b/backend/remote-state/kubernetes/client_test.go index 897d8e0ce..3026afc2d 100644 --- a/backend/remote-state/kubernetes/client_test.go +++ b/backend/remote-state/kubernetes/client_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) func TestRemoteClient_impl(t *testing.T) { @@ -72,7 +72,7 @@ func TestForceUnlock(t *testing.T) { t.Fatal(err) } - info := state.NewLockInfo() + info := statemgr.NewLockInfo() info.Operation = "test" info.Who = "clientA" @@ -98,7 +98,7 @@ func TestForceUnlock(t *testing.T) { t.Fatal(err) } - info = state.NewLockInfo() + info = statemgr.NewLockInfo() info.Operation = "test" info.Who = "clientA" diff --git a/backend/remote-state/manta/backend_state.go b/backend/remote-state/manta/backend_state.go index 1eec6f070..6ce9ba0f6 100644 --- a/backend/remote-state/manta/backend_state.go +++ b/backend/remote-state/manta/backend_state.go @@ -12,9 +12,9 @@ import ( "github.com/joyent/triton-go/storage" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) func (b *Backend) Workspaces() ([]string, error) { @@ -64,7 +64,7 @@ func (b *Backend) DeleteWorkspace(name string) error { return nil } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { if name == "" { return nil, errors.New("missing state name") } @@ -81,7 +81,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { //it's listed by States. if name != backend.DefaultStateName { // take a lock on this state while we write it - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockId, err := client.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/manta/client.go b/backend/remote-state/manta/client.go index 4f8899359..3dba080a1 100644 --- a/backend/remote-state/manta/client.go +++ b/backend/remote-state/manta/client.go @@ -10,8 +10,8 @@ import ( "path" uuid "github.com/hashicorp/go-uuid" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" tritonErrors "github.com/joyent/triton-go/errors" "github.com/joyent/triton-go/storage" ) @@ -86,7 +86,7 @@ func (c *RemoteClient) Delete() error { return err } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { //At Joyent, we want to make sure that the State directory exists before we interact with it //We don't expect users to have to create it in advance //The order of operations of Backend State as follows: @@ -103,7 +103,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { } //firstly we want to check that a lock doesn't already exist - lockErr := &state.LockError{} + lockErr := &statemgr.LockError{} lockInfo, err := c.getLockInfo() if err != nil { if !tritonErrors.IsResourceNotFound(err) { @@ -113,7 +113,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { } if lockInfo != nil { - lockErr := &state.LockError{ + lockErr := &statemgr.LockError{ Err: fmt.Errorf("A lock is already acquired"), Info: lockInfo, } @@ -154,7 +154,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { } func (c *RemoteClient) Unlock(id string) error { - lockErr := &state.LockError{} + lockErr := &statemgr.LockError{} lockInfo, err := c.getLockInfo() if err != nil { @@ -175,7 +175,7 @@ func (c *RemoteClient) Unlock(id string) error { return err } -func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { +func (c *RemoteClient) getLockInfo() (*statemgr.LockInfo, error) { output, err := c.storageClient.Objects().Get(context.Background(), &storage.GetObjectInput{ ObjectPath: path.Join(mantaDefaultRootStore, c.directoryName, lockFileName), }) @@ -190,7 +190,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { return nil, fmt.Errorf("Failed to read lock info: %s", err) } - lockInfo := &state.LockInfo{} + lockInfo := &statemgr.LockInfo{} err = json.Unmarshal(buf.Bytes(), lockInfo) if err != nil { return nil, err diff --git a/backend/remote-state/manta/client_test.go b/backend/remote-state/manta/client_test.go index 8a276a780..078bbe5e8 100644 --- a/backend/remote-state/manta/client_test.go +++ b/backend/remote-state/manta/client_test.go @@ -7,7 +7,7 @@ import ( "time" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" ) func TestRemoteClient_impl(t *testing.T) { diff --git a/backend/remote-state/oss/backend_state.go b/backend/remote-state/oss/backend_state.go index 7f7778012..a336134be 100644 --- a/backend/remote-state/oss/backend_state.go +++ b/backend/remote-state/oss/backend_state.go @@ -8,9 +8,9 @@ import ( "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" "log" "path" @@ -95,7 +95,7 @@ func (b *Backend) DeleteWorkspace(name string) error { return client.Delete() } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { client, err := b.remoteClient(name) if err != nil { return nil, err @@ -120,7 +120,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { // We need to create the object so it's listed by States. if !exists { // take a lock on this state while we write it - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockId, err := client.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/oss/client.go b/backend/remote-state/oss/client.go index cd28458cb..ba9052efa 100644 --- a/backend/remote-state/oss/client.go +++ b/backend/remote-state/oss/client.go @@ -16,8 +16,8 @@ import ( "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore" "github.com/hashicorp/go-multierror" uuid "github.com/hashicorp/go-uuid" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" "github.com/pkg/errors" ) @@ -48,7 +48,7 @@ type RemoteClient struct { lockFile string serverSideEncryption bool acl string - info *state.LockInfo + info *statemgr.LockInfo mu sync.Mutex otsTable string } @@ -147,7 +147,7 @@ func (c *RemoteClient) Delete() error { return nil } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { if c.otsTable == "" { return "", nil } @@ -195,7 +195,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { log.Printf("[WARN] Error getting lock info: %#v", err) err = multierror.Append(err, infoErr) } - lockErr := &state.LockError{ + lockErr := &statemgr.LockError{ Err: err, Info: lockInfo, } @@ -324,7 +324,7 @@ func (c *RemoteClient) deleteMD5() error { return nil } -func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { +func (c *RemoteClient) getLockInfo() (*statemgr.LockInfo, error) { getParams := &tablestore.SingleRowQueryCriteria{ TableName: c.otsTable, PrimaryKey: &tablestore.PrimaryKey{ @@ -352,7 +352,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { if v, ok := object.GetColumnMap().Columns["Info"]; ok && len(v) > 0 { infoData = v[0].Value.(string) } - lockInfo := &state.LockInfo{} + lockInfo := &statemgr.LockInfo{} err = json.Unmarshal([]byte(infoData), lockInfo) if err != nil { return nil, err @@ -364,7 +364,7 @@ func (c *RemoteClient) Unlock(id string) error { return nil } - lockErr := &state.LockError{} + lockErr := &statemgr.LockError{} lockInfo, err := c.getLockInfo() if err != nil { diff --git a/backend/remote-state/oss/client_test.go b/backend/remote-state/oss/client_test.go index d3f0febec..49a2d63b6 100644 --- a/backend/remote-state/oss/client_test.go +++ b/backend/remote-state/oss/client_test.go @@ -10,9 +10,9 @@ import ( "crypto/md5" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/states/statefile" + "github.com/hashicorp/terraform/states/statemgr" ) // NOTE: Before running this testcase, please create a OTS instance called 'tf-oss-remote' @@ -117,7 +117,7 @@ func TestRemoteClientLocks_multipleStates(t *testing.T) { if err != nil { t.Fatal(err) } - if _, err := s1.Lock(state.NewLockInfo()); err != nil { + if _, err := s1.Lock(statemgr.NewLockInfo()); err != nil { t.Fatal("failed to get lock for s1:", err) } @@ -126,7 +126,7 @@ func TestRemoteClientLocks_multipleStates(t *testing.T) { if err != nil { t.Fatal(err) } - if _, err := s2.Lock(state.NewLockInfo()); err != nil { + if _, err := s2.Lock(statemgr.NewLockInfo()); err != nil { t.Fatal("failed to get lock for s2:", err) } } @@ -165,7 +165,7 @@ func TestRemoteForceUnlock(t *testing.T) { t.Fatal(err) } - info := state.NewLockInfo() + info := statemgr.NewLockInfo() info.Operation = "test" info.Who = "clientA" @@ -191,7 +191,7 @@ func TestRemoteForceUnlock(t *testing.T) { t.Fatal(err) } - info = state.NewLockInfo() + info = statemgr.NewLockInfo() info.Operation = "test" info.Who = "clientA" @@ -287,7 +287,7 @@ func TestRemoteClient_stateChecksum(t *testing.T) { client1 := s1.(*remote.State).Client // create an old and new state version to persist - s := state.TestStateInitial() + s := statemgr.TestFullInitialState() sf := &statefile.File{State: s} var oldState bytes.Buffer if err := statefile.Write(sf, &oldState); err != nil { diff --git a/backend/remote-state/pg/backend_state.go b/backend/remote-state/pg/backend_state.go index a886d7f4c..1cbdc5b6c 100644 --- a/backend/remote-state/pg/backend_state.go +++ b/backend/remote-state/pg/backend_state.go @@ -4,9 +4,9 @@ import ( "fmt" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) func (b *Backend) Workspaces() ([]string, error) { @@ -47,9 +47,9 @@ func (b *Backend) DeleteWorkspace(name string) error { return nil } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { // Build the state client - var stateMgr state.State = &remote.State{ + var stateMgr statemgr.Full = &remote.State{ Client: &RemoteClient{ Client: b.db, Name: name, @@ -77,7 +77,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { // exist already. We have to write an empty state as a sentinel value // so Workspaces() knows it exists. if !exists { - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockId, err := stateMgr.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/pg/backend_test.go b/backend/remote-state/pg/backend_test.go index 17edd6a52..19544cf57 100644 --- a/backend/remote-state/pg/backend_test.go +++ b/backend/remote-state/pg/backend_test.go @@ -10,7 +10,7 @@ import ( "testing" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" _ "github.com/lib/pq" ) diff --git a/backend/remote-state/pg/client.go b/backend/remote-state/pg/client.go index a14e5ed4b..2c6db19f1 100644 --- a/backend/remote-state/pg/client.go +++ b/backend/remote-state/pg/client.go @@ -6,8 +6,8 @@ import ( "fmt" uuid "github.com/hashicorp/go-uuid" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" _ "github.com/lib/pq" ) @@ -17,7 +17,7 @@ type RemoteClient struct { Name string SchemaName string - info *state.LockInfo + info *statemgr.LockInfo } func (c *RemoteClient) Get() (*remote.Payload, error) { @@ -60,7 +60,7 @@ func (c *RemoteClient) Delete() error { return nil } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { var err error var lockID string @@ -80,7 +80,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { var didUnlock []byte err := row.Scan(&didUnlock) if err != nil { - return &state.LockError{Info: info, Err: err} + return &statemgr.LockError{Info: info, Err: err} } return nil } @@ -97,22 +97,22 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { var innerDidLock []byte err := innerRow.Scan(&innerDidLock) if err != nil { - return "", &state.LockError{Info: info, Err: err} + return "", &statemgr.LockError{Info: info, Err: err} } if string(innerDidLock) == "false" { - return "", &state.LockError{Info: info, Err: fmt.Errorf("Already locked for workspace creation: %s", c.Name)} + return "", &statemgr.LockError{Info: info, Err: fmt.Errorf("Already locked for workspace creation: %s", c.Name)} } info.Path = "-1" case err != nil: - return "", &state.LockError{Info: info, Err: err} + return "", &statemgr.LockError{Info: info, Err: err} case string(didLock) == "false": // Existing workspace is already locked. Release the attempted creation lock. lockUnlock("-1") - return "", &state.LockError{Info: info, Err: fmt.Errorf("Workspace is already locked: %s", c.Name)} + return "", &statemgr.LockError{Info: info, Err: fmt.Errorf("Workspace is already locked: %s", c.Name)} case string(didLockForCreate) == "false": // Someone has the creation lock already. Release the existing workspace because it might not be safe to touch. lockUnlock(string(pgLockId)) - return "", &state.LockError{Info: info, Err: fmt.Errorf("Cannot lock workspace; already locked for workspace creation: %s", c.Name)} + return "", &statemgr.LockError{Info: info, Err: fmt.Errorf("Cannot lock workspace; already locked for workspace creation: %s", c.Name)} default: // Existing workspace is now locked. Release the attempted creation lock. lockUnlock("-1") @@ -123,7 +123,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { return info.ID, nil } -func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { +func (c *RemoteClient) getLockInfo() (*statemgr.LockInfo, error) { return c.info, nil } @@ -134,7 +134,7 @@ func (c *RemoteClient) Unlock(id string) error { var didUnlock []byte err := row.Scan(&didUnlock) if err != nil { - return &state.LockError{Info: c.info, Err: err} + return &statemgr.LockError{Info: c.info, Err: err} } c.info = nil } diff --git a/backend/remote-state/pg/client_test.go b/backend/remote-state/pg/client_test.go index 2bffc92ed..ded47a5d1 100644 --- a/backend/remote-state/pg/client_test.go +++ b/backend/remote-state/pg/client_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" ) func TestRemoteClient_impl(t *testing.T) { diff --git a/backend/remote-state/s3/backend_state.go b/backend/remote-state/s3/backend_state.go index 861c284b4..c6809f5d6 100644 --- a/backend/remote-state/s3/backend_state.go +++ b/backend/remote-state/s3/backend_state.go @@ -12,9 +12,9 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) func (b *Backend) Workspaces() ([]string, error) { @@ -124,7 +124,7 @@ func (b *Backend) remoteClient(name string) (*RemoteClient, error) { return client, nil } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { client, err := b.remoteClient(name) if err != nil { return nil, err @@ -155,7 +155,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { // We need to create the object so it's listed by States. if !exists { // take a lock on this state while we write it - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockId, err := client.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/s3/backend_test.go b/backend/remote-state/s3/backend_test.go index 82a282652..70d6d57fe 100644 --- a/backend/remote-state/s3/backend_test.go +++ b/backend/remote-state/s3/backend_test.go @@ -14,8 +14,8 @@ import ( awsbase "github.com/hashicorp/aws-sdk-go-base" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/configs/hcl2shim" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" ) const ( diff --git a/backend/remote-state/s3/client.go b/backend/remote-state/s3/client.go index 18c0a08db..e1624f04c 100644 --- a/backend/remote-state/s3/client.go +++ b/backend/remote-state/s3/client.go @@ -18,8 +18,8 @@ import ( "github.com/aws/aws-sdk-go/service/s3" multierror "github.com/hashicorp/go-multierror" uuid "github.com/hashicorp/go-uuid" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) // Store the last saved serial in dynamo with this suffix for consistency checks. @@ -211,7 +211,7 @@ func (c *RemoteClient) Delete() error { return nil } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { if c.ddbTable == "" { return "", nil } @@ -243,7 +243,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { err = multierror.Append(err, infoErr) } - lockErr := &state.LockError{ + lockErr := &statemgr.LockError{ Err: err, Info: lockInfo, } @@ -328,7 +328,7 @@ func (c *RemoteClient) deleteMD5() error { return nil } -func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { +func (c *RemoteClient) getLockInfo() (*statemgr.LockInfo, error) { getParams := &dynamodb.GetItemInput{ Key: map[string]*dynamodb.AttributeValue{ "LockID": {S: aws.String(c.lockPath())}, @@ -348,7 +348,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) { infoData = *v.S } - lockInfo := &state.LockInfo{} + lockInfo := &statemgr.LockInfo{} err = json.Unmarshal([]byte(infoData), lockInfo) if err != nil { return nil, err @@ -362,7 +362,7 @@ func (c *RemoteClient) Unlock(id string) error { return nil } - lockErr := &state.LockError{} + lockErr := &statemgr.LockError{} // TODO: store the path and lock ID in separate fields, and have proper // projection expression only delete the lock if both match, rather than diff --git a/backend/remote-state/s3/client_test.go b/backend/remote-state/s3/client_test.go index b3639fc31..c18f99e3c 100644 --- a/backend/remote-state/s3/client_test.go +++ b/backend/remote-state/s3/client_test.go @@ -9,9 +9,9 @@ import ( "time" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/states/statefile" + "github.com/hashicorp/terraform/states/statemgr" ) func TestRemoteClient_impl(t *testing.T) { @@ -109,7 +109,7 @@ func TestForceUnlock(t *testing.T) { t.Fatal(err) } - info := state.NewLockInfo() + info := statemgr.NewLockInfo() info.Operation = "test" info.Who = "clientA" @@ -135,7 +135,7 @@ func TestForceUnlock(t *testing.T) { t.Fatal(err) } - info = state.NewLockInfo() + info = statemgr.NewLockInfo() info.Operation = "test" info.Who = "clientA" @@ -227,7 +227,7 @@ func TestRemoteClient_stateChecksum(t *testing.T) { client1 := s1.(*remote.State).Client // create an old and new state version to persist - s := state.TestStateInitial() + s := statemgr.TestFullInitialState() sf := &statefile.File{State: s} var oldState bytes.Buffer if err := statefile.Write(sf, &oldState); err != nil { diff --git a/backend/remote-state/swift/backend_state.go b/backend/remote-state/swift/backend_state.go index 735d7cf6a..bdc21c79f 100644 --- a/backend/remote-state/swift/backend_state.go +++ b/backend/remote-state/swift/backend_state.go @@ -5,9 +5,9 @@ import ( "strings" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) const ( @@ -91,7 +91,7 @@ func (b *Backend) DeleteWorkspace(name string) error { return err } -func (b *Backend) StateMgr(name string) (state.State, error) { +func (b *Backend) StateMgr(name string) (statemgr.Full, error) { if name == "" { return nil, fmt.Errorf("missing state name") } @@ -106,11 +106,11 @@ func (b *Backend) StateMgr(name string) (state.State, error) { lockState: b.lock, } - var stateMgr state.State = &remote.State{Client: client} + var stateMgr statemgr.Full = &remote.State{Client: client} // If we're not locking, disable it if !b.lock { - stateMgr = &state.LockDisabled{Inner: stateMgr} + stateMgr = &statemgr.LockDisabled{Inner: stateMgr} } // Check to see if this state already exists. @@ -144,7 +144,7 @@ func (b *Backend) StateMgr(name string) (state.State, error) { // Grab a lock, we use this to write an empty state if one doesn't // exist already. We have to write an empty state as a sentinel value // so States() knows it exists. - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = "init" lockId, err := stateMgr.Lock(lockInfo) if err != nil { diff --git a/backend/remote-state/swift/client.go b/backend/remote-state/swift/client.go index b0083d430..184cef0ab 100644 --- a/backend/remote-state/swift/client.go +++ b/backend/remote-state/swift/client.go @@ -14,8 +14,8 @@ import ( "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers" "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects" "github.com/gophercloud/gophercloud/pagination" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" + "github.com/hashicorp/terraform/states/statemgr" ) const ( @@ -53,7 +53,7 @@ type RemoteClient struct { // lockState is true if we're using locks lockState bool - info *state.LockInfo + info *statemgr.LockInfo // lockCancel cancels the Context use for lockRenewPeriodic, and is // called when unlocking, or before creating a new lock if the lock is @@ -124,7 +124,7 @@ func (c *RemoteClient) Delete() error { return c.delete(c.objectName) } -func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { +func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) { c.mu.Lock() defer c.mu.Unlock() @@ -385,7 +385,7 @@ func (c *RemoteClient) delete(object string) error { return nil } -func (c *RemoteClient) writeLockInfo(info *state.LockInfo, deleteAfter time.Duration, ifNoneMatch string) error { +func (c *RemoteClient) writeLockInfo(info *statemgr.LockInfo, deleteAfter time.Duration, ifNoneMatch string) error { err := c.put(c.lockFilePath(), info.Marshal(), int(deleteAfter.Seconds()), ifNoneMatch) if httpErr, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok && httpErr.Actual == 412 { @@ -405,8 +405,8 @@ func (c *RemoteClient) writeLockInfo(info *state.LockInfo, deleteAfter time.Dura return nil } -func (c *RemoteClient) lockError(err error, conflictingLock *state.LockInfo) *state.LockError { - lockErr := &state.LockError{ +func (c *RemoteClient) lockError(err error, conflictingLock *statemgr.LockInfo) *statemgr.LockError { + lockErr := &statemgr.LockError{ Err: err, Info: conflictingLock, } @@ -416,13 +416,13 @@ func (c *RemoteClient) lockError(err error, conflictingLock *state.LockInfo) *st // lockInfo reads the lock file, parses its contents and returns the parsed // LockInfo struct. -func (c *RemoteClient) lockInfo() (*state.LockInfo, error) { +func (c *RemoteClient) lockInfo() (*statemgr.LockInfo, error) { raw, err := c.get(c.lockFilePath()) if err != nil { return nil, err } - info := &state.LockInfo{} + info := &statemgr.LockInfo{} if err := json.Unmarshal(raw.Data, info); err != nil { return nil, err @@ -431,7 +431,7 @@ func (c *RemoteClient) lockInfo() (*state.LockInfo, error) { return info, nil } -func (c *RemoteClient) lockRenewPeriodic(ctx context.Context, info *state.LockInfo) error { +func (c *RemoteClient) lockRenewPeriodic(ctx context.Context, info *statemgr.LockInfo) error { log.Printf("[DEBUG] Renew lock %v", info) waitDur := lockRenewInterval diff --git a/backend/remote-state/swift/client_test.go b/backend/remote-state/swift/client_test.go index 6a715ee3c..e256f665e 100644 --- a/backend/remote-state/swift/client_test.go +++ b/backend/remote-state/swift/client_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" ) func TestRemoteClient_impl(t *testing.T) { diff --git a/backend/remote/backend.go b/backend/remote/backend.go index e8e9bc343..77ad26225 100644 --- a/backend/remote/backend.go +++ b/backend/remote/backend.go @@ -18,7 +18,7 @@ import ( "github.com/hashicorp/terraform-svchost/disco" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/configs/configschema" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/tfdiags" diff --git a/backend/remote/backend_state.go b/backend/remote/backend_state.go index 29dc8550e..5bbba65e1 100644 --- a/backend/remote/backend_state.go +++ b/backend/remote/backend_state.go @@ -8,14 +8,14 @@ import ( "fmt" tfe "github.com/hashicorp/go-tfe" - "github.com/hashicorp/terraform/state" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/states/statefile" + "github.com/hashicorp/terraform/states/statemgr" ) type remoteClient struct { client *tfe.Client - lockInfo *state.LockInfo + lockInfo *statemgr.LockInfo organization string runID string stateUploadErr bool @@ -106,10 +106,10 @@ func (r *remoteClient) EnableForcePush() { } // Lock the remote state. -func (r *remoteClient) Lock(info *state.LockInfo) (string, error) { +func (r *remoteClient) Lock(info *statemgr.LockInfo) (string, error) { ctx := context.Background() - lockErr := &state.LockError{Info: r.lockInfo} + lockErr := &statemgr.LockError{Info: r.lockInfo} // Lock the workspace. _, err := r.client.Workspaces.Lock(ctx, r.workspace.ID, tfe.WorkspaceLockOptions{ @@ -139,7 +139,7 @@ func (r *remoteClient) Unlock(id string) error { return nil } - lockErr := &state.LockError{Info: r.lockInfo} + lockErr := &statemgr.LockError{Info: r.lockInfo} // With lock info this should be treated as a normal unlock. if r.lockInfo != nil { diff --git a/backend/remote/backend_state_test.go b/backend/remote/backend_state_test.go index 530fdc88b..e7b1a4318 100644 --- a/backend/remote/backend_state_test.go +++ b/backend/remote/backend_state_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/terraform" ) diff --git a/backend/remote/testing.go b/backend/remote/testing.go index 3afaf97aa..9f152b5d1 100644 --- a/backend/remote/testing.go +++ b/backend/remote/testing.go @@ -18,7 +18,7 @@ import ( "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/httpclient" "github.com/hashicorp/terraform/providers" - "github.com/hashicorp/terraform/state/remote" + "github.com/hashicorp/terraform/states/remote" "github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/version" diff --git a/backend/testing.go b/backend/testing.go index e6f591e0e..aea2508c4 100644 --- a/backend/testing.go +++ b/backend/testing.go @@ -12,7 +12,6 @@ import ( "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/configs/hcl2shim" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/tfdiags" @@ -293,7 +292,7 @@ func testLocks(t *testing.T, b1, b2 Backend, testForceUnlock bool) { } // Fast exit if this doesn't support locking at all - if _, ok := b1StateMgr.(state.Locker); !ok { + if _, ok := b1StateMgr.(statemgr.Locker); !ok { t.Logf("TestBackend: backend %T doesn't support state locking, not testing", b1) return } @@ -309,14 +308,14 @@ func testLocks(t *testing.T, b1, b2 Backend, testForceUnlock bool) { } // Reassign so its obvious whats happening - lockerA := b1StateMgr.(state.Locker) - lockerB := b2StateMgr.(state.Locker) + lockerA := b1StateMgr.(statemgr.Locker) + lockerB := b2StateMgr.(statemgr.Locker) - infoA := state.NewLockInfo() + infoA := statemgr.NewLockInfo() infoA.Operation = "test" infoA.Who = "clientA" - infoB := state.NewLockInfo() + infoB := statemgr.NewLockInfo() infoB.Operation = "test" infoB.Who = "clientB" @@ -325,7 +324,7 @@ func testLocks(t *testing.T, b1, b2 Backend, testForceUnlock bool) { t.Fatal("unable to get initial lock:", err) } - // Make sure we can still get the state.State from another instance even + // Make sure we can still get the statemgr.Full from another instance even // when locked. This should only happen when a state is loaded via the // backend, and as a remote state. _, err = b2.StateMgr(DefaultStateName) diff --git a/command/apply_test.go b/command/apply_test.go index f9e3940b5..c4d0ba949 100644 --- a/command/apply_test.go +++ b/command/apply_test.go @@ -23,7 +23,6 @@ import ( "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/providers" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" @@ -305,8 +304,8 @@ func TestApply_defaultState(t *testing.T) { } // create an existing state file - localState := &state.LocalState{Path: statePath} - if err := localState.WriteState(terraform.NewState()); err != nil { + localState := statemgr.NewFilesystem(statePath) + if err := localState.WriteState(states.NewState()); err != nil { t.Fatal(err) } diff --git a/state/local.go b/command/clistate/local_state.go similarity index 95% rename from state/local.go rename to command/clistate/local_state.go index 146651967..f5f9dbac7 100644 --- a/state/local.go +++ b/command/clistate/local_state.go @@ -1,4 +1,4 @@ -package state +package clistate import ( "bytes" @@ -12,6 +12,7 @@ import ( "time" multierror "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" ) @@ -172,7 +173,7 @@ func (s *LocalState) RefreshState() error { } // Lock implements a local filesystem state.Locker. -func (s *LocalState) Lock(info *LockInfo) (string, error) { +func (s *LocalState) Lock(info *statemgr.LockInfo) (string, error) { s.mu.Lock() defer s.mu.Unlock() @@ -192,7 +193,7 @@ func (s *LocalState) Lock(info *LockInfo) (string, error) { err = multierror.Append(err, infoErr) } - lockErr := &LockError{ + lockErr := &statemgr.LockError{ Info: info, Err: err, } @@ -219,7 +220,7 @@ func (s *LocalState) Unlock(id string) error { idErr = multierror.Append(idErr, err) } - return &LockError{ + return &statemgr.LockError{ Err: idErr, Info: info, } @@ -284,14 +285,14 @@ func (s *LocalState) lockInfoPath() string { } // lockInfo returns the data in a lock info file -func (s *LocalState) lockInfo() (*LockInfo, error) { +func (s *LocalState) lockInfo() (*statemgr.LockInfo, error) { path := s.lockInfoPath() infoData, err := ioutil.ReadFile(path) if err != nil { return nil, err } - info := LockInfo{} + info := statemgr.LockInfo{} err = json.Unmarshal(infoData, &info) if err != nil { return nil, fmt.Errorf("state file %q locked, but could not unmarshal lock info: %s", s.Path, err) @@ -300,7 +301,7 @@ func (s *LocalState) lockInfo() (*LockInfo, error) { } // write a new lock info file -func (s *LocalState) writeLockInfo(info *LockInfo) error { +func (s *LocalState) writeLockInfo(info *statemgr.LockInfo) error { path := s.lockInfoPath() info.Path = s.Path info.Created = time.Now().UTC() diff --git a/state/local_lock_unix.go b/command/clistate/local_state_lock_unix.go similarity index 97% rename from state/local_lock_unix.go rename to command/clistate/local_state_lock_unix.go index 470b31491..7b2769e37 100644 --- a/state/local_lock_unix.go +++ b/command/clistate/local_state_lock_unix.go @@ -1,6 +1,6 @@ // +build !windows -package state +package clistate import ( "io" diff --git a/state/local_lock_windows.go b/command/clistate/local_state_lock_windows.go similarity index 99% rename from state/local_lock_windows.go rename to command/clistate/local_state_lock_windows.go index 01738c9bb..071aed494 100644 --- a/state/local_lock_windows.go +++ b/command/clistate/local_state_lock_windows.go @@ -1,6 +1,6 @@ // +build windows -package state +package clistate import ( "math" diff --git a/command/clistate/state.go b/command/clistate/state.go index 881377d4d..7e5d32e60 100644 --- a/command/clistate/state.go +++ b/command/clistate/state.go @@ -14,7 +14,6 @@ import ( "github.com/hashicorp/errwrap" multierror "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform/helper/slowmessage" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states/statemgr" "github.com/mitchellh/cli" "github.com/mitchellh/colorstring" @@ -51,15 +50,15 @@ that no one else is holding a lock. ` ) -// Locker allows for more convenient usage of the lower-level state.Locker +// Locker allows for more convenient usage of the lower-level statemgr.Locker // implementations. -// The state.Locker API requires passing in a state.LockInfo struct. Locker +// The statemgr.Locker API requires passing in a statemgr.LockInfo struct. Locker // implementations are expected to create the required LockInfo struct when // Lock is called, populate the Operation field with the "reason" string -// provided, and pass that on to the underlying state.Locker. +// provided, and pass that on to the underlying statemgr.Locker. // Locker implementations are also expected to store any state required to call // Unlock, which is at a minimum the LockID string returned by the -// state.Locker. +// statemgr.Locker. type Locker interface { // Lock the provided state manager, storing the reason string in the LockInfo. Lock(s statemgr.Locker, reason string) error @@ -110,7 +109,7 @@ func (l *locker) Lock(s statemgr.Locker, reason string) error { ctx, cancel := context.WithTimeout(l.ctx, l.timeout) defer cancel() - lockInfo := state.NewLockInfo() + lockInfo := statemgr.NewLockInfo() lockInfo.Operation = reason err := slowmessage.Do(LockThreshold, func() error { diff --git a/command/init_test.go b/command/init_test.go index 38b6a4344..d132e67b8 100644 --- a/command/init_test.go +++ b/command/init_test.go @@ -17,12 +17,10 @@ import ( "github.com/zclconf/go-cty/cty" "github.com/hashicorp/terraform/addrs" - "github.com/hashicorp/terraform/backend/local" "github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/helper/copy" "github.com/hashicorp/terraform/internal/getproviders" "github.com/hashicorp/terraform/internal/providercache" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" @@ -878,12 +876,7 @@ func TestInit_getProvider(t *testing.T) { // state. s := terraform.NewState() s.TFVersion = "100.1.0" - local := &state.LocalState{ - Path: local.DefaultStateFilename, - } - if err := local.WriteState(s); err != nil { - t.Fatal(err) - } + testStateFileDefault(t, s) ui := new(cli.MockUi) m.Ui = ui diff --git a/command/meta_backend.go b/command/meta_backend.go index 650d4a26e..ac8371ea1 100644 --- a/command/meta_backend.go +++ b/command/meta_backend.go @@ -20,7 +20,7 @@ import ( "github.com/hashicorp/terraform/command/clistate" "github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/plans" - "github.com/hashicorp/terraform/state" + "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/tfdiags" "github.com/zclconf/go-cty/cty" @@ -439,7 +439,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di // if we're using a remote backend. This may not yet exist which means // we haven't used a non-local backend before. That is okay. statePath := filepath.Join(m.DataDir(), DefaultStateFilename) - sMgr := &state.LocalState{Path: statePath} + sMgr := &clistate.LocalState{Path: statePath} if err := sMgr.RefreshState(); err != nil { diags = diags.Append(fmt.Errorf("Failed to load state: %s", err)) return nil, diags @@ -572,7 +572,7 @@ func (m *Meta) backendFromState() (backend.Backend, tfdiags.Diagnostics) { // if we're using a remote backend. This may not yet exist which means // we haven't used a non-local backend before. That is okay. statePath := filepath.Join(m.DataDir(), DefaultStateFilename) - sMgr := &state.LocalState{Path: statePath} + sMgr := &clistate.LocalState{Path: statePath} if err := sMgr.RefreshState(); err != nil { diags = diags.Append(fmt.Errorf("Failed to load state: %s", err)) return nil, diags @@ -649,7 +649,7 @@ func (m *Meta) backendFromState() (backend.Backend, tfdiags.Diagnostics) { //------------------------------------------------------------------- // Unconfiguring a backend (moving from backend => local). -func (m *Meta) backend_c_r_S(c *configs.Backend, cHash int, sMgr *state.LocalState, output bool) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_c_r_S(c *configs.Backend, cHash int, sMgr *clistate.LocalState, output bool) (backend.Backend, tfdiags.Diagnostics) { s := sMgr.State() // Get the backend type for output @@ -704,7 +704,7 @@ func (m *Meta) backend_c_r_S(c *configs.Backend, cHash int, sMgr *state.LocalSta } // Legacy remote state -func (m *Meta) backend_c_R_s(c *configs.Backend, sMgr *state.LocalState) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_c_R_s(c *configs.Backend, sMgr *clistate.LocalState) (backend.Backend, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics m.Ui.Error(strings.TrimSpace(errBackendLegacy) + "\n") @@ -714,7 +714,7 @@ func (m *Meta) backend_c_R_s(c *configs.Backend, sMgr *state.LocalState) (backen } // Unsetting backend, saved backend, legacy remote state -func (m *Meta) backend_c_R_S(c *configs.Backend, cHash int, sMgr *state.LocalState) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_c_R_S(c *configs.Backend, cHash int, sMgr *clistate.LocalState) (backend.Backend, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics m.Ui.Error(strings.TrimSpace(errBackendLegacy) + "\n") @@ -724,7 +724,7 @@ func (m *Meta) backend_c_R_S(c *configs.Backend, cHash int, sMgr *state.LocalSta } // Configuring a backend for the first time with legacy remote state. -func (m *Meta) backend_C_R_s(c *configs.Backend, sMgr *state.LocalState) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_C_R_s(c *configs.Backend, sMgr *clistate.LocalState) (backend.Backend, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics m.Ui.Error(strings.TrimSpace(errBackendLegacy) + "\n") @@ -734,7 +734,7 @@ func (m *Meta) backend_C_R_s(c *configs.Backend, sMgr *state.LocalState) (backen } // Configuring a backend for the first time. -func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *state.LocalState) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.LocalState) (backend.Backend, tfdiags.Diagnostics) { // Get the backend b, configVal, diags := m.backendInitFromConfig(c) if diags.HasErrors() { @@ -754,7 +754,7 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *state.LocalSta return nil, diags } - var localStates []state.State + var localStates []statemgr.Full for _, workspace := range workspaces { localState, err := localB.StateMgr(workspace) if err != nil { @@ -861,7 +861,7 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *state.LocalSta } // Changing a previously saved backend. -func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *state.LocalState, output bool) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clistate.LocalState, output bool) (backend.Backend, tfdiags.Diagnostics) { if output { // Notify the user m.Ui.Output(m.Colorize().Color(fmt.Sprintf( @@ -946,7 +946,7 @@ func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *state. } // Initiailizing an unchanged saved backend -func (m *Meta) backend_C_r_S_unchanged(c *configs.Backend, cHash int, sMgr *state.LocalState) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_C_r_S_unchanged(c *configs.Backend, cHash int, sMgr *clistate.LocalState) (backend.Backend, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics s := sMgr.State() @@ -1001,7 +1001,7 @@ func (m *Meta) backend_C_r_S_unchanged(c *configs.Backend, cHash int, sMgr *stat } // Initiailizing a changed saved backend with legacy remote state. -func (m *Meta) backend_C_R_S_changed(c *configs.Backend, sMgr *state.LocalState) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_C_R_S_changed(c *configs.Backend, sMgr *clistate.LocalState) (backend.Backend, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics m.Ui.Error(strings.TrimSpace(errBackendLegacy) + "\n") @@ -1011,7 +1011,7 @@ func (m *Meta) backend_C_R_S_changed(c *configs.Backend, sMgr *state.LocalState) } // Initiailizing an unchanged saved backend with legacy remote state. -func (m *Meta) backend_C_R_S_unchanged(c *configs.Backend, sMgr *state.LocalState, output bool) (backend.Backend, tfdiags.Diagnostics) { +func (m *Meta) backend_C_R_S_unchanged(c *configs.Backend, sMgr *clistate.LocalState, output bool) (backend.Backend, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics m.Ui.Error(strings.TrimSpace(errBackendLegacy) + "\n") diff --git a/command/meta_backend_migrate.go b/command/meta_backend_migrate.go index 9227844a1..2d4fcba20 100644 --- a/command/meta_backend_migrate.go +++ b/command/meta_backend_migrate.go @@ -13,7 +13,6 @@ import ( "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/command/clistate" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" @@ -336,7 +335,7 @@ func (m *Meta) backendMigrateState_s_s(opts *backendMigrateOpts) error { two = stateTwo.State() } - var confirmFunc func(state.State, state.State, *backendMigrateOpts) (bool, error) + var confirmFunc func(statemgr.Full, statemgr.Full, *backendMigrateOpts) (bool, error) switch { // No migration necessary case one.Empty() && two.Empty(): @@ -401,7 +400,7 @@ func (m *Meta) backendMigrateState_s_s(opts *backendMigrateOpts) error { return nil } -func (m *Meta) backendMigrateEmptyConfirm(one, two state.State, opts *backendMigrateOpts) (bool, error) { +func (m *Meta) backendMigrateEmptyConfirm(one, two statemgr.Full, opts *backendMigrateOpts) (bool, error) { inputOpts := &terraform.InputOpts{ Id: "backend-migrate-copy-to-empty", Query: "Do you want to copy existing state to the new backend?", @@ -414,7 +413,7 @@ func (m *Meta) backendMigrateEmptyConfirm(one, two state.State, opts *backendMig } func (m *Meta) backendMigrateNonEmptyConfirm( - stateOne, stateTwo state.State, opts *backendMigrateOpts) (bool, error) { + stateOne, stateTwo statemgr.Full, opts *backendMigrateOpts) (bool, error) { // We need to grab both states so we can write them to a file one := stateOne.State() two := stateTwo.State() diff --git a/command/meta_backend_test.go b/command/meta_backend_test.go index 4889413b1..7dfbedc82 100644 --- a/command/meta_backend_test.go +++ b/command/meta_backend_test.go @@ -12,7 +12,6 @@ import ( "github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/helper/copy" "github.com/hashicorp/terraform/plans" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statefile" "github.com/hashicorp/terraform/states/statemgr" @@ -1795,10 +1794,7 @@ func TestMetaBackend_localDoesNotDeleteLocal(t *testing.T) { }, } - err := (&state.LocalState{Path: DefaultStateFilename}).WriteState(orig) - if err != nil { - t.Fatal(err) - } + testStateFileDefault(t, orig) m := testMetaBackend(t, nil) m.forceInitCopy = true diff --git a/command/state_meta.go b/command/state_meta.go index ef7bdb826..e245dbcfd 100644 --- a/command/state_meta.go +++ b/command/state_meta.go @@ -6,7 +6,6 @@ import ( "time" "github.com/hashicorp/terraform/addrs" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/tfdiags" @@ -23,8 +22,8 @@ type StateMeta struct { // the backend, but changes the way that backups are done. This configures // backups to be timestamped rather than just the original state path plus a // backup path. -func (c *StateMeta) State() (state.State, error) { - var realState state.State +func (c *StateMeta) State() (statemgr.Full, error) { + var realState statemgr.Full backupPath := c.backupPath stateOutPath := c.statePath diff --git a/command/testdata/statelocker.go b/command/testdata/statelocker.go index e3a7f678f..98e13a23a 100644 --- a/command/testdata/statelocker.go +++ b/command/testdata/statelocker.go @@ -11,7 +11,8 @@ import ( "syscall" "time" - "github.com/hashicorp/terraform/state" + "github.com/hashicorp/terraform/command/clistate" + "github.com/hashicorp/terraform/states/statemgr" ) func main() { @@ -19,11 +20,11 @@ func main() { log.Fatal(os.Args[0], "statefile") } - s := &state.LocalState{ + s := &clistate.LocalState{ Path: os.Args[1], } - info := state.NewLockInfo() + info := statemgr.NewLockInfo() info.Operation = "test" info.Info = "state locker" diff --git a/command/workspace_command_test.go b/command/workspace_command_test.go index aefa0e159..267745423 100644 --- a/command/workspace_command_test.go +++ b/command/workspace_command_test.go @@ -12,7 +12,6 @@ import ( "github.com/hashicorp/terraform/backend/local" "github.com/hashicorp/terraform/backend/remote-state/inmem" "github.com/hashicorp/terraform/helper/copy" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" @@ -265,7 +264,7 @@ func TestWorkspace_createWithState(t *testing.T) { } newPath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename) - envState := state.LocalState{Path: newPath} + envState := statemgr.NewFilesystem(newPath) err = envState.RefreshState() if err != nil { t.Fatal(err) @@ -364,11 +363,14 @@ func TestWorkspace_deleteWithState(t *testing.T) { }, } - envStatePath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename) - err := (&state.LocalState{Path: envStatePath}).WriteState(originalState) + f, err := os.Create(filepath.Join(local.DefaultWorkspaceDir, "test", "terraform.tfstate")) if err != nil { t.Fatal(err) } + defer f.Close() + if err := terraform.WriteState(originalState, f); err != nil { + t.Fatal(err) + } ui := new(cli.MockUi) delCmd := &WorkspaceDeleteCommand{ diff --git a/state/backup.go b/state/backup.go deleted file mode 100644 index 0cac3b6cf..000000000 --- a/state/backup.go +++ /dev/null @@ -1,86 +0,0 @@ -package state - -import ( - "sync" - - "github.com/hashicorp/terraform/states" - "github.com/hashicorp/terraform/states/statemgr" -) - -// BackupState wraps a State that backs up the state on the first time that -// a WriteState or PersistState is called. -// -// If Path exists, it will be overwritten. -type BackupState struct { - mu sync.Mutex - Real State - Path string - - done bool -} - -func (s *BackupState) State() *states.State { - return s.Real.State() -} - -func (s *BackupState) RefreshState() error { - return s.Real.RefreshState() -} - -func (s *BackupState) WriteState(state *states.State) error { - s.mu.Lock() - defer s.mu.Unlock() - - if !s.done { - if err := s.backup(); err != nil { - return err - } - } - - return s.Real.WriteState(state) -} - -func (s *BackupState) PersistState() error { - s.mu.Lock() - defer s.mu.Unlock() - - if !s.done { - if err := s.backup(); err != nil { - return err - } - } - - return s.Real.PersistState() -} - -func (s *BackupState) Lock(info *LockInfo) (string, error) { - return s.Real.Lock(info) -} - -func (s *BackupState) Unlock(id string) error { - return s.Real.Unlock(id) -} - -func (s *BackupState) backup() error { - state := s.Real.State() - if state == nil { - if err := s.Real.RefreshState(); err != nil { - return err - } - - state = s.Real.State() - } - - // LocalState.WriteState ensures that a file always exists for locking - // purposes, but we don't need a backup or lock if the state is empty, so - // skip this with a nil state. - if state != nil { - ls := statemgr.NewFilesystem(s.Path) - if err := ls.WriteState(state); err != nil { - return err - } - } - - s.done = true - return nil -} diff --git a/state/inmem.go b/state/inmem.go deleted file mode 100644 index 36fa34147..000000000 --- a/state/inmem.go +++ /dev/null @@ -1,108 +0,0 @@ -package state - -import ( - "errors" - "sync" - "time" - - "github.com/hashicorp/terraform/terraform" -) - -// InmemState is an in-memory state storage. -type InmemState struct { - mu sync.Mutex - state *terraform.State -} - -func (s *InmemState) State() *terraform.State { - s.mu.Lock() - defer s.mu.Unlock() - - return s.state.DeepCopy() -} - -func (s *InmemState) RefreshState() error { - s.mu.Lock() - defer s.mu.Unlock() - - return nil -} - -func (s *InmemState) WriteState(state *terraform.State) error { - s.mu.Lock() - defer s.mu.Unlock() - - state = state.DeepCopy() - - if s.state != nil { - state.Serial = s.state.Serial - - if !s.state.MarshalEqual(state) { - state.Serial++ - } - } - - s.state = state - - return nil -} - -func (s *InmemState) PersistState() error { - return nil -} - -func (s *InmemState) Lock(*LockInfo) (string, error) { - return "", nil -} - -func (s *InmemState) Unlock(string) error { - return nil -} - -// inmemLocker is an in-memory State implementation for testing locks. -type inmemLocker struct { - *InmemState - - mu sync.Mutex - lockInfo *LockInfo - // count the calls to Lock - lockCounter int -} - -func (s *inmemLocker) Lock(info *LockInfo) (string, error) { - s.mu.Lock() - defer s.mu.Unlock() - s.lockCounter++ - - lockErr := &LockError{ - Info: &LockInfo{}, - } - - if s.lockInfo != nil { - lockErr.Err = errors.New("state locked") - *lockErr.Info = *s.lockInfo - return "", lockErr - } - - info.Created = time.Now().UTC() - s.lockInfo = info - return s.lockInfo.ID, nil -} - -func (s *inmemLocker) Unlock(id string) error { - s.mu.Lock() - defer s.mu.Unlock() - - lockErr := &LockError{ - Info: &LockInfo{}, - } - - if id != s.lockInfo.ID { - lockErr.Err = errors.New("invalid lock id") - *lockErr.Info = *s.lockInfo - return lockErr - } - - s.lockInfo = nil - return nil -} diff --git a/state/state.go b/state/state.go deleted file mode 100644 index 21cd90387..000000000 --- a/state/state.go +++ /dev/null @@ -1,104 +0,0 @@ -package state - -import ( - "context" - "fmt" - "os" - "os/user" - "time" - - uuid "github.com/hashicorp/go-uuid" - - "github.com/hashicorp/terraform/states/statemgr" - "github.com/hashicorp/terraform/version" -) - -// State is a deprecated alias for statemgr.Full -type State = statemgr.Full - -// StateReader is a deprecated alias for statemgr.Reader -type StateReader = statemgr.Reader - -// StateWriter is a deprecated alias for statemgr.Writer -type StateWriter = statemgr.Writer - -// StateRefresher is a deprecated alias for statemgr.Refresher -type StateRefresher = statemgr.Refresher - -// StatePersister is a deprecated alias for statemgr.Persister -type StatePersister = statemgr.Persister - -// Locker is a deprecated alias for statemgr.Locker -type Locker = statemgr.Locker - -// test hook to verify that LockWithContext has attempted a lock -var postLockHook func() - -// Lock the state, using the provided context for timeout and cancellation. -// This backs off slightly to an upper limit. -func LockWithContext(ctx context.Context, s State, info *LockInfo) (string, error) { - delay := time.Second - maxDelay := 16 * time.Second - for { - id, err := s.Lock(info) - if err == nil { - return id, nil - } - - le, ok := err.(*LockError) - if !ok { - // not a lock error, so we can't retry - return "", err - } - - if le == nil || le.Info == nil || le.Info.ID == "" { - // If we dont' have a complete LockError, there's something wrong with the lock - return "", err - } - - if postLockHook != nil { - postLockHook() - } - - // there's an existing lock, wait and try again - select { - case <-ctx.Done(): - // return the last lock error with the info - return "", err - case <-time.After(delay): - if delay < maxDelay { - delay *= 2 - } - } - } -} - -// Generate a LockInfo structure, populating the required fields. -func NewLockInfo() *LockInfo { - id, err := uuid.GenerateUUID() - if err != nil { - // this of course shouldn't happen - panic(err) - } - - // don't error out on user and hostname, as we don't require them - userName := "" - if userInfo, err := user.Current(); err == nil { - userName = userInfo.Username - } - host, _ := os.Hostname() - - info := &LockInfo{ - ID: id, - Who: fmt.Sprintf("%s@%s", userName, host), - Version: version.Version, - Created: time.Now().UTC(), - } - return info -} - -// LockInfo is a deprecated lias for statemgr.LockInfo -type LockInfo = statemgr.LockInfo - -// LockError is a deprecated alias for statemgr.LockError -type LockError = statemgr.LockError diff --git a/state/state_test.go b/state/state_test.go deleted file mode 100644 index e93f5680a..000000000 --- a/state/state_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package state - -import ( - "encoding/json" - "flag" - "io/ioutil" - "log" - "os" - "testing" - - "github.com/hashicorp/terraform/helper/logging" -) - -func TestMain(m *testing.M) { - flag.Parse() - if testing.Verbose() { - // if we're verbose, use the logging requested by TF_LOG - logging.SetOutput() - } else { - // otherwise silence all logs - log.SetOutput(ioutil.Discard) - } - os.Exit(m.Run()) -} - -func TestNewLockInfo(t *testing.T) { - info1 := NewLockInfo() - info2 := NewLockInfo() - - if info1.ID == "" { - t.Fatal("LockInfo missing ID") - } - - if info1.Version == "" { - t.Fatal("LockInfo missing version") - } - - if info1.Created.IsZero() { - t.Fatal("LockInfo missing Created") - } - - if info1.ID == info2.ID { - t.Fatal("multiple LockInfo with identical IDs") - } - - // test the JSON output is valid - newInfo := &LockInfo{} - err := json.Unmarshal(info1.Marshal(), newInfo) - if err != nil { - t.Fatal(err) - } -} diff --git a/state/testdata/lockstate.go b/state/testdata/lockstate.go deleted file mode 100644 index ced62c232..000000000 --- a/state/testdata/lockstate.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "io" - "log" - "os" - - "github.com/hashicorp/terraform/state" -) - -// Attempt to open and lock a terraform state file. -// Lock failure exits with 0 and writes "lock failed" to stderr. -func main() { - if len(os.Args) != 2 { - log.Fatal(os.Args[0], "statefile") - } - - s := &state.LocalState{ - Path: os.Args[1], - } - - info := state.NewLockInfo() - info.Operation = "test" - info.Info = "state locker" - - _, err := s.Lock(info) - if err != nil { - io.WriteString(os.Stderr, "lock failed") - - } - - return -} diff --git a/state/testing.go b/state/testing.go deleted file mode 100644 index c0c1fbbc4..000000000 --- a/state/testing.go +++ /dev/null @@ -1,22 +0,0 @@ -package state - -import ( - "testing" - - "github.com/hashicorp/terraform/states" - "github.com/hashicorp/terraform/states/statemgr" -) - -// TestState is a helper for testing state implementations. It is expected -// that the given implementation is pre-loaded with the TestStateInitial -// state. -func TestState(t *testing.T, s State) { - t.Helper() - statemgr.TestFull(t, s) -} - -// TestStateInitial is the initial state that a State should have -// for TestState. -func TestStateInitial() *states.State { - return statemgr.TestFullInitialState() -} diff --git a/state/remote/remote.go b/states/remote/remote.go similarity index 95% rename from state/remote/remote.go rename to states/remote/remote.go index f9947bac7..d3d3f7b2b 100644 --- a/state/remote/remote.go +++ b/states/remote/remote.go @@ -3,7 +3,7 @@ package remote import ( "fmt" - "github.com/hashicorp/terraform/state" + "github.com/hashicorp/terraform/states/statemgr" ) // Client is the interface that must be implemented for a remote state @@ -27,7 +27,7 @@ type ClientForcePusher interface { // backend to enable state lock/unlock. type ClientLocker interface { Client - state.Locker + statemgr.Locker } // Payload is the return value from the remote state storage. diff --git a/state/remote/remote_test.go b/states/remote/remote_test.go similarity index 96% rename from state/remote/remote_test.go rename to states/remote/remote_test.go index b88766c85..bbd73ae5f 100644 --- a/state/remote/remote_test.go +++ b/states/remote/remote_test.go @@ -6,14 +6,14 @@ import ( "encoding/json" "testing" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states/statefile" + "github.com/hashicorp/terraform/states/statemgr" ) // testClient is a generic function to test any client. func testClient(t *testing.T, c Client) { var buf bytes.Buffer - s := state.TestStateInitial() + s := statemgr.TestFullInitialState() sf := &statefile.File{State: s} if err := statefile.Write(sf, &buf); err != nil { t.Fatalf("err: %s", err) diff --git a/state/remote/state.go b/states/remote/state.go similarity index 98% rename from state/remote/state.go rename to states/remote/state.go index 3069aeb89..bd9494f53 100644 --- a/state/remote/state.go +++ b/states/remote/state.go @@ -6,7 +6,6 @@ import ( "sync" uuid "github.com/hashicorp/go-uuid" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statefile" "github.com/hashicorp/terraform/states/statemgr" @@ -196,7 +195,7 @@ func (s *State) PersistState() error { } // Lock calls the Client's Lock method if it's implemented. -func (s *State) Lock(info *state.LockInfo) (string, error) { +func (s *State) Lock(info *statemgr.LockInfo) (string, error) { s.mu.Lock() defer s.mu.Unlock() diff --git a/state/remote/state_test.go b/states/remote/state_test.go similarity index 100% rename from state/remote/state_test.go rename to states/remote/state_test.go diff --git a/state/remote/testing.go b/states/remote/testing.go similarity index 85% rename from state/remote/testing.go rename to states/remote/testing.go index 002f50387..7d69d9a41 100644 --- a/state/remote/testing.go +++ b/states/remote/testing.go @@ -4,14 +4,14 @@ import ( "bytes" "testing" - "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/states/statefile" + "github.com/hashicorp/terraform/states/statemgr" ) // TestClient is a generic function to test any client. func TestClient(t *testing.T, c Client) { var buf bytes.Buffer - s := state.TestStateInitial() + s := statemgr.TestFullInitialState() sf := statefile.New(s, "stub-lineage", 2) err := statefile.Write(sf, &buf) if err != nil { @@ -49,21 +49,21 @@ func TestClient(t *testing.T, c Client) { // clients since some implementations may tie the client to the lock, or may // have reentrant locks. func TestRemoteLocks(t *testing.T, a, b Client) { - lockerA, ok := a.(state.Locker) + lockerA, ok := a.(statemgr.Locker) if !ok { - t.Fatal("client A not a state.Locker") + t.Fatal("client A not a statemgr.Locker") } - lockerB, ok := b.(state.Locker) + lockerB, ok := b.(statemgr.Locker) if !ok { - t.Fatal("client B not a state.Locker") + t.Fatal("client B not a statemgr.Locker") } - infoA := state.NewLockInfo() + infoA := statemgr.NewLockInfo() infoA.Operation = "test" infoA.Who = "clientA" - infoB := state.NewLockInfo() + infoB := statemgr.NewLockInfo() infoB.Operation = "test" infoB.Who = "clientB" diff --git a/states/statemgr/filesystem.go b/states/statemgr/filesystem.go index 541108dde..138e57dae 100644 --- a/states/statemgr/filesystem.go +++ b/states/statemgr/filesystem.go @@ -44,7 +44,7 @@ type Filesystem struct { stateFileOut *os.File // While the stateFileOut will correspond to the lock directly, - // store and check the lock ID to maintain a strict state.Locker + // store and check the lock ID to maintain a strict statemgr.Locker // implementation. lockID string diff --git a/state/lock.go b/states/statemgr/lock.go similarity index 91% rename from state/lock.go rename to states/statemgr/lock.go index 4839df2a7..b64f76503 100644 --- a/state/lock.go +++ b/states/statemgr/lock.go @@ -1,8 +1,6 @@ -package state +package statemgr -import ( - "github.com/hashicorp/terraform/states" -) +import "github.com/hashicorp/terraform/states" // LockDisabled implements State and Locker but disables state locking. // If State doesn't support locking, this is a no-op. This is useful for @@ -10,7 +8,7 @@ import ( type LockDisabled struct { // We can't embed State directly since Go dislikes that a field is // State and State interface has a method State - Inner State + Inner Full } func (s *LockDisabled) State() *states.State { diff --git a/state/lock_test.go b/states/statemgr/lock_test.go similarity index 67% rename from state/lock_test.go rename to states/statemgr/lock_test.go index d7246ac9d..326252b5c 100644 --- a/state/lock_test.go +++ b/states/statemgr/lock_test.go @@ -1,10 +1,10 @@ -package state +package statemgr import ( "testing" ) func TestLockDisabled_impl(t *testing.T) { - var _ State = new(LockDisabled) + var _ Full = new(LockDisabled) var _ Locker = new(LockDisabled) }