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
|
||||
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 {
|
||||
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 {
|
||||
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
|
||||
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 {
|
||||
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
|
||||
s := sMgr.State()
|
||||
|
@ -1091,11 +1100,14 @@ func (m *Meta) backend_C_r_S_changed(
|
|||
}
|
||||
|
||||
// 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 {
|
||||
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
|
||||
s = sMgr.State()
|
||||
|
@ -1249,11 +1261,15 @@ func (m *Meta) backend_C_R_S_unchanged(
|
|||
}
|
||||
|
||||
// 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 {
|
||||
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
|
||||
s = sMgr.State()
|
||||
|
|
|
@ -24,17 +24,25 @@ import (
|
|||
//
|
||||
// This will attempt to lock both states for the migration.
|
||||
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 {
|
||||
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 {
|
||||
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()
|
||||
two := opts.Two.State()
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strings"
|
||||
|
||||
clistate "github.com/hashicorp/terraform/command/state"
|
||||
"github.com/hashicorp/terraform/state"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
|
@ -73,13 +74,16 @@ func (c *TaintCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
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 {
|
||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
defer clistate.Unlock(st, c.Ui, c.Colorize())
|
||||
defer clistate.Unlock(st, lockID, c.Ui, c.Colorize())
|
||||
}
|
||||
|
||||
// Get the actual state structure
|
||||
|
|
|
@ -23,7 +23,7 @@ func main() {
|
|||
Path: os.Args[1],
|
||||
}
|
||||
|
||||
err := s.Lock("command test")
|
||||
lockID, err := s.Lock(&state.LockInfo{Operation: "test", Info: "state locker"})
|
||||
if err != nil {
|
||||
io.WriteString(os.Stderr, err.Error())
|
||||
return
|
||||
|
@ -33,7 +33,7 @@ func main() {
|
|||
io.WriteString(os.Stdout, "LOCKED")
|
||||
|
||||
defer func() {
|
||||
if err := s.Unlock(); err != nil {
|
||||
if err := s.Unlock(lockID); err != nil {
|
||||
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))
|
||||
return 1
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strings"
|
||||
|
||||
clistate "github.com/hashicorp/terraform/command/state"
|
||||
"github.com/hashicorp/terraform/state"
|
||||
)
|
||||
|
||||
// UntaintCommand is a cli.Command implementation that manually untaints
|
||||
|
@ -61,13 +62,16 @@ func (c *UntaintCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
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 {
|
||||
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
defer clistate.Unlock(st, c.Ui, c.Colorize())
|
||||
defer clistate.Unlock(st, lockID, c.Ui, c.Colorize())
|
||||
}
|
||||
|
||||
// Get the actual state structure
|
||||
|
|
|
@ -134,25 +134,25 @@ func (s *LocalState) RefreshState() error {
|
|||
}
|
||||
|
||||
// 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 err := s.createStateFiles(); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.lock(); 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
|
||||
if s.stateFileOut == nil {
|
||||
return nil
|
||||
|
@ -232,18 +232,14 @@ func (s *LocalState) lockInfo() (*LockInfo, error) {
|
|||
}
|
||||
|
||||
// write a new lock info file
|
||||
func (s *LocalState) writeLockInfo(info string) error {
|
||||
func (s *LocalState) writeLockInfo(info *LockInfo) error {
|
||||
path := s.lockInfoPath()
|
||||
info.Path = s.Path
|
||||
info.Created = time.Now().UTC()
|
||||
|
||||
lockInfo := &LockInfo{
|
||||
Path: s.Path,
|
||||
Created: time.Now().UTC(),
|
||||
Info: info,
|
||||
}
|
||||
|
||||
infoData, err := json.Marshal(lockInfo)
|
||||
infoData, err := json.Marshal(info)
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue