make command tests pass with new state.Locker
This commit is contained in:
parent
cd233fef6a
commit
4f0c465187
|
@ -533,11 +533,16 @@ func (m *Meta) backendFromPlan(opts *BackendOpts) (backend.Backend, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock the state if we can
|
// Lock the state if we can
|
||||||
err = clistate.Lock(realMgr, "backend from plan", m.Ui, m.Colorize())
|
lockInfo := &state.LockInfo{
|
||||||
|
Operation: "plan",
|
||||||
|
Info: "backend from plan",
|
||||||
|
}
|
||||||
|
|
||||||
|
lockID, err := clistate.Lock(realMgr, lockInfo, m.Ui, m.Colorize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error locking state: %s", err)
|
return nil, fmt.Errorf("Error locking state: %s", err)
|
||||||
}
|
}
|
||||||
defer clistate.Unlock(realMgr, m.Ui, m.Colorize())
|
defer clistate.Unlock(realMgr, lockID, m.Ui, m.Colorize())
|
||||||
|
|
||||||
if err := realMgr.RefreshState(); err != nil {
|
if err := realMgr.RefreshState(); err != nil {
|
||||||
return nil, fmt.Errorf("Error reading state: %s", err)
|
return nil, fmt.Errorf("Error reading state: %s", err)
|
||||||
|
@ -986,11 +991,15 @@ func (m *Meta) backend_C_r_s(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock the state if we can
|
// Lock the state if we can
|
||||||
err = clistate.Lock(sMgr, "backend from config", m.Ui, m.Colorize())
|
lockInfo := &state.LockInfo{
|
||||||
|
Info: "backend from config",
|
||||||
|
}
|
||||||
|
|
||||||
|
lockID, err := clistate.Lock(sMgr, lockInfo, m.Ui, m.Colorize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error locking state: %s", err)
|
return nil, fmt.Errorf("Error locking state: %s", err)
|
||||||
}
|
}
|
||||||
defer clistate.Unlock(sMgr, m.Ui, m.Colorize())
|
defer clistate.Unlock(sMgr, lockID, m.Ui, m.Colorize())
|
||||||
|
|
||||||
// Store the metadata in our saved state location
|
// Store the metadata in our saved state location
|
||||||
s := sMgr.State()
|
s := sMgr.State()
|
||||||
|
@ -1091,11 +1100,14 @@ func (m *Meta) backend_C_r_S_changed(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock the state if we can
|
// Lock the state if we can
|
||||||
err = clistate.Lock(sMgr, "backend from config", m.Ui, m.Colorize())
|
lockInfo := &state.LockInfo{
|
||||||
|
Info: "backend from config",
|
||||||
|
}
|
||||||
|
lockID, err := clistate.Lock(sMgr, lockInfo, m.Ui, m.Colorize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error locking state: %s", err)
|
return nil, fmt.Errorf("Error locking state: %s", err)
|
||||||
}
|
}
|
||||||
defer clistate.Unlock(sMgr, m.Ui, m.Colorize())
|
defer clistate.Unlock(sMgr, lockID, m.Ui, m.Colorize())
|
||||||
|
|
||||||
// Update the backend state
|
// Update the backend state
|
||||||
s = sMgr.State()
|
s = sMgr.State()
|
||||||
|
@ -1249,11 +1261,15 @@ func (m *Meta) backend_C_R_S_unchanged(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock the state if we can
|
// Lock the state if we can
|
||||||
err = clistate.Lock(sMgr, "backend from config", m.Ui, m.Colorize())
|
lockInfo := &state.LockInfo{
|
||||||
|
Info: "backend from config",
|
||||||
|
}
|
||||||
|
|
||||||
|
lockID, err := clistate.Lock(sMgr, lockInfo, m.Ui, m.Colorize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error locking state: %s", err)
|
return nil, fmt.Errorf("Error locking state: %s", err)
|
||||||
}
|
}
|
||||||
defer clistate.Unlock(sMgr, m.Ui, m.Colorize())
|
defer clistate.Unlock(sMgr, lockID, m.Ui, m.Colorize())
|
||||||
|
|
||||||
// Unset the remote state
|
// Unset the remote state
|
||||||
s = sMgr.State()
|
s = sMgr.State()
|
||||||
|
|
|
@ -24,17 +24,25 @@ import (
|
||||||
//
|
//
|
||||||
// This will attempt to lock both states for the migration.
|
// This will attempt to lock both states for the migration.
|
||||||
func (m *Meta) backendMigrateState(opts *backendMigrateOpts) error {
|
func (m *Meta) backendMigrateState(opts *backendMigrateOpts) error {
|
||||||
err := clistate.Lock(opts.One, "migration source state", m.Ui, m.Colorize())
|
lockInfoOne := &state.LockInfo{
|
||||||
|
Info: "migration source state",
|
||||||
|
}
|
||||||
|
|
||||||
|
lockIDOne, err := clistate.Lock(opts.One, lockInfoOne, m.Ui, m.Colorize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error locking source state: %s", err)
|
return fmt.Errorf("Error locking source state: %s", err)
|
||||||
}
|
}
|
||||||
defer clistate.Unlock(opts.One, m.Ui, m.Colorize())
|
defer clistate.Unlock(opts.One, lockIDOne, m.Ui, m.Colorize())
|
||||||
|
|
||||||
err = clistate.Lock(opts.Two, "migration destination state", m.Ui, m.Colorize())
|
lockInfoTwo := &state.LockInfo{
|
||||||
|
Info: "migration source state",
|
||||||
|
}
|
||||||
|
|
||||||
|
lockIDTwo, err := clistate.Lock(opts.Two, lockInfoTwo, m.Ui, m.Colorize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error locking destination state: %s", err)
|
return fmt.Errorf("Error locking destination state: %s", err)
|
||||||
}
|
}
|
||||||
defer clistate.Unlock(opts.Two, m.Ui, m.Colorize())
|
defer clistate.Unlock(opts.Two, lockIDTwo, m.Ui, m.Colorize())
|
||||||
|
|
||||||
one := opts.One.State()
|
one := opts.One.State()
|
||||||
two := opts.Two.State()
|
two := opts.Two.State()
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
clistate "github.com/hashicorp/terraform/command/state"
|
clistate "github.com/hashicorp/terraform/command/state"
|
||||||
|
"github.com/hashicorp/terraform/state"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -73,13 +74,16 @@ func (c *TaintCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Meta.stateLock {
|
if c.Meta.stateLock {
|
||||||
err := clistate.Lock(st, "taint", c.Ui, c.Colorize())
|
lockInfo := &state.LockInfo{
|
||||||
|
Operation: "taint",
|
||||||
|
}
|
||||||
|
lockID, err := clistate.Lock(st, lockInfo, c.Ui, c.Colorize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
defer clistate.Unlock(st, c.Ui, c.Colorize())
|
defer clistate.Unlock(st, lockID, c.Ui, c.Colorize())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the actual state structure
|
// Get the actual state structure
|
||||||
|
|
|
@ -23,7 +23,7 @@ func main() {
|
||||||
Path: os.Args[1],
|
Path: os.Args[1],
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.Lock("command test")
|
lockID, err := s.Lock(&state.LockInfo{Operation: "test", Info: "state locker"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
io.WriteString(os.Stderr, err.Error())
|
io.WriteString(os.Stderr, err.Error())
|
||||||
return
|
return
|
||||||
|
@ -33,7 +33,7 @@ func main() {
|
||||||
io.WriteString(os.Stdout, "LOCKED")
|
io.WriteString(os.Stdout, "LOCKED")
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := s.Unlock(); err != nil {
|
if err := s.Unlock(lockID); err != nil {
|
||||||
io.WriteString(os.Stderr, err.Error())
|
io.WriteString(os.Stderr, err.Error())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -92,7 +92,8 @@ func (c *UnlockCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.Unlock(); err != nil {
|
// FIXME: unlock should require the lock ID
|
||||||
|
if err := s.Unlock(""); err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to unlock state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Failed to unlock state: %s", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
clistate "github.com/hashicorp/terraform/command/state"
|
clistate "github.com/hashicorp/terraform/command/state"
|
||||||
|
"github.com/hashicorp/terraform/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UntaintCommand is a cli.Command implementation that manually untaints
|
// UntaintCommand is a cli.Command implementation that manually untaints
|
||||||
|
@ -61,13 +62,16 @@ func (c *UntaintCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Meta.stateLock {
|
if c.Meta.stateLock {
|
||||||
err := clistate.Lock(st, "untaint", c.Ui, c.Colorize())
|
lockInfo := &state.LockInfo{
|
||||||
|
Operation: "untaint",
|
||||||
|
}
|
||||||
|
lockID, err := clistate.Lock(st, lockInfo, c.Ui, c.Colorize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
defer clistate.Unlock(st, c.Ui, c.Colorize())
|
defer clistate.Unlock(st, lockID, c.Ui, c.Colorize())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the actual state structure
|
// Get the actual state structure
|
||||||
|
|
|
@ -134,25 +134,25 @@ func (s *LocalState) RefreshState() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock implements a local filesystem state.Locker.
|
// Lock implements a local filesystem state.Locker.
|
||||||
func (s *LocalState) Lock(reason string) error {
|
func (s *LocalState) Lock(info *LockInfo) (string, error) {
|
||||||
if s.stateFileOut == nil {
|
if s.stateFileOut == nil {
|
||||||
if err := s.createStateFiles(); err != nil {
|
if err := s.createStateFiles(); err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.lock(); err != nil {
|
if err := s.lock(); err != nil {
|
||||||
if info, err := s.lockInfo(); err == nil {
|
if info, err := s.lockInfo(); err == nil {
|
||||||
return info.Err()
|
return "", info.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("state file %q locked: %s", s.Path, err)
|
return "", fmt.Errorf("state file %q locked: %s", s.Path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.writeLockInfo(reason)
|
return "", s.writeLockInfo(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LocalState) Unlock() error {
|
func (s *LocalState) Unlock(id string) error {
|
||||||
// we can't be locked if we don't have a file
|
// we can't be locked if we don't have a file
|
||||||
if s.stateFileOut == nil {
|
if s.stateFileOut == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -232,18 +232,14 @@ func (s *LocalState) lockInfo() (*LockInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write a new lock info file
|
// write a new lock info file
|
||||||
func (s *LocalState) writeLockInfo(info string) error {
|
func (s *LocalState) writeLockInfo(info *LockInfo) error {
|
||||||
path := s.lockInfoPath()
|
path := s.lockInfoPath()
|
||||||
|
info.Path = s.Path
|
||||||
|
info.Created = time.Now().UTC()
|
||||||
|
|
||||||
lockInfo := &LockInfo{
|
infoData, err := json.Marshal(info)
|
||||||
Path: s.Path,
|
|
||||||
Created: time.Now().UTC(),
|
|
||||||
Info: info,
|
|
||||||
}
|
|
||||||
|
|
||||||
infoData, err := json.Marshal(lockInfo)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("could not marshal lock info: %#v", lockInfo))
|
panic(fmt.Sprintf("could not marshal lock info: %#v", info))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ioutil.WriteFile(path, infoData, 0600)
|
err = ioutil.WriteFile(path, infoData, 0600)
|
||||||
|
|
Loading…
Reference in New Issue