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:
parent
adf5cde180
commit
6621501ae3
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
|
@ -1,6 +1,6 @@
|
|||
// +build !windows
|
||||
|
||||
package state
|
||||
package clistate
|
||||
|
||||
import (
|
||||
"io"
|
|
@ -1,6 +1,6 @@
|
|||
// +build windows
|
||||
|
||||
package state
|
||||
package clistate
|
||||
|
||||
import (
|
||||
"math"
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
}
|
108
state/inmem.go
108
state/inmem.go
|
@ -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
|
||||
}
|
104
state/state.go
104
state/state.go
|
@ -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
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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.
|
|
@ -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)
|
|
@ -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()
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue