state: remove deprecated state package (#25490)

Most of the state package has been deprecated by the states package.
This PR replaces all the references to the old state package that
can be done simply - the low-hanging fruit.

* states: move state.Locker to statemgr

The state.Locker interface was a wrapper around a statemgr.Full, so
moving this was relatively straightforward.

* command: remove unnecessary use of state package for writing local terraform state files

* move state.LocalState into terraform package

state.LocalState is responsible for managing terraform.States, so it
made sense (to me) to move it into the terraform package.

* slight change of heart: move state.LocalState into clistate instead of
terraform
This commit is contained in:
Kristin Laemmert 2020-08-11 11:43:01 -04:00 committed by GitHub
parent adf5cde180
commit 6621501ae3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 296 additions and 719 deletions

View File

@ -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
}

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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
}

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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 {

View File

@ -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 {

View File

@ -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"
)

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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"
)

View File

@ -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
}

View File

@ -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
}

View File

@ -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.

View File

@ -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"
)

View File

@ -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 {

View File

@ -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

View File

@ -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)

View File

@ -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 {

View File

@ -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 (

View File

@ -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
}

View File

@ -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
}

View File

@ -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")

View File

@ -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) {

View File

@ -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 {

View File

@ -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) {

View File

@ -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 {

View File

@ -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) {

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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 {

View File

@ -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

View File

@ -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) {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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"
)

View File

@ -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
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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 (

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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) {

View File

@ -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"

View File

@ -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 {

View File

@ -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"
)

View File

@ -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"

View File

@ -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)

View File

@ -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)
}

View File

@ -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()

View File

@ -1,6 +1,6 @@
// +build !windows
package state
package clistate
import (
"io"

View File

@ -1,6 +1,6 @@
// +build windows
package state
package clistate
import (
"math"

View File

@ -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 {

View File

@ -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

View File

@ -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")

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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{

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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()
}

View File

@ -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.

View File

@ -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)

View File

@ -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()

View File

@ -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"

View File

@ -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

View File

@ -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 {

View File

@ -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)
}