Skip to content

Commit

Permalink
Merge pull request #19939 from hashicorp/svh/b-state-cmds
Browse files Browse the repository at this point in the history
command/state: add proper locking
  • Loading branch information
Sander van Harmelen authored Jan 8, 2019
2 parents f7bcf2a + c3802bd commit 3c4ddfb
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
32 changes: 29 additions & 3 deletions command/state_mv.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package command

import (
"context"
"fmt"
"strings"

"github.com/hashicorp/terraform/command/clistate"
"github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/cli"
)
Expand All @@ -24,8 +26,10 @@ func (c *StateMvCommand) Run(args []string) int {

cmdFlags := c.Meta.flagSet("state mv")
cmdFlags.StringVar(&c.backupPath, "backup", "-", "backup")
cmdFlags.StringVar(&c.statePath, "state", "", "path")
cmdFlags.StringVar(&backupPathOut, "backup-out", "-", "backup")
cmdFlags.BoolVar(&c.Meta.stateLock, "lock", true, "lock state")
cmdFlags.DurationVar(&c.Meta.stateLockTimeout, "lock-timeout", 0, "lock timeout")
cmdFlags.StringVar(&c.statePath, "state", "", "path")
cmdFlags.StringVar(&statePathOut, "state-out", "", "path")
if err := cmdFlags.Parse(args); err != nil {
return cli.RunResultHelp
Expand All @@ -43,8 +47,17 @@ func (c *StateMvCommand) Run(args []string) int {
return 1
}

if c.stateLock {
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
if err := stateLocker.Lock(stateFrom, "state-mv"); err != nil {
c.Ui.Error(fmt.Sprintf("Error locking source state: %s", err))
return 1
}
defer stateLocker.Unlock(nil)
}

if err := stateFrom.RefreshState(); err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
c.Ui.Error(fmt.Sprintf("Failed to load source state: %s", err))
return 1
}

Expand All @@ -67,8 +80,17 @@ func (c *StateMvCommand) Run(args []string) int {
return 1
}

if c.stateLock {
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
if err := stateLocker.Lock(stateTo, "state-mv"); err != nil {
c.Ui.Error(fmt.Sprintf("Error locking destination state: %s", err))
return 1
}
defer stateLocker.Unlock(nil)
}

if err := stateTo.RefreshState(); err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))
return 1
}

Expand Down Expand Up @@ -215,6 +237,10 @@ Options:
to be specified if -state-out is set to a different path
than -state.
-lock=true Lock the state file when locking is supported.
-lock-timeout=0s Duration to retry a state lock.
-state=PATH Path to the source state file. Defaults to the configured
backend, or "terraform.tfstate"
Expand Down
18 changes: 18 additions & 0 deletions command/state_push.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package command

import (
"context"
"fmt"
"io"
"os"
"strings"

"github.com/hashicorp/terraform/command/clistate"
"github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/cli"
)
Expand All @@ -25,6 +27,8 @@ func (c *StatePushCommand) Run(args []string) int {
var flagForce bool
cmdFlags := c.Meta.flagSet("state push")
cmdFlags.BoolVar(&flagForce, "force", false, "")
cmdFlags.BoolVar(&c.Meta.stateLock, "lock", true, "lock state")
cmdFlags.DurationVar(&c.Meta.stateLockTimeout, "lock-timeout", 0, "lock timeout")
if err := cmdFlags.Parse(args); err != nil {
return cli.RunResultHelp
}
Expand Down Expand Up @@ -76,6 +80,16 @@ func (c *StatePushCommand) Run(args []string) int {
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))
return 1
}

if c.stateLock {
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
if err := stateLocker.Lock(state, "state-push"); err != nil {
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
return 1
}
defer stateLocker.Unlock(nil)
}

if err := state.RefreshState(); err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))
return 1
Expand Down Expand Up @@ -136,6 +150,10 @@ Options:
-force Write the state even if lineages don't match or the
remote serial is higher.
-lock=true Lock the state file when locking is supported.
-lock-timeout=0s Duration to retry a state lock.
`
return strings.TrimSpace(helpText)
}
Expand Down
18 changes: 18 additions & 0 deletions command/state_rm.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package command

import (
"context"
"fmt"
"strings"

"github.com/hashicorp/terraform/command/clistate"
"github.com/mitchellh/cli"
)

Expand All @@ -20,6 +22,8 @@ func (c *StateRmCommand) Run(args []string) int {

cmdFlags := c.Meta.flagSet("state show")
cmdFlags.StringVar(&c.backupPath, "backup", "-", "backup")
cmdFlags.BoolVar(&c.Meta.stateLock, "lock", true, "lock state")
cmdFlags.DurationVar(&c.Meta.stateLockTimeout, "lock-timeout", 0, "lock timeout")
cmdFlags.StringVar(&c.statePath, "state", "", "path")
if err := cmdFlags.Parse(args); err != nil {
return cli.RunResultHelp
Expand All @@ -36,6 +40,16 @@ func (c *StateRmCommand) Run(args []string) int {
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
return 1
}

if c.stateLock {
stateLocker := clistate.NewLocker(context.Background(), c.stateLockTimeout, c.Ui, c.Colorize())
if err := stateLocker.Lock(state, "state-rm"); err != nil {
c.Ui.Error(fmt.Sprintf("Error locking state: %s", err))
return 1
}
defer stateLocker.Unlock(nil)
}

if err := state.RefreshState(); err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
return 1
Expand Down Expand Up @@ -89,6 +103,10 @@ Options:
will write it to the same path as the statefile with
a backup extension.
-lock=true Lock the state file when locking is supported.
-lock-timeout=0s Duration to retry a state lock.
-state=PATH Path to the source state file. Defaults to the configured
backend, or "terraform.tfstate"
Expand Down

0 comments on commit 3c4ddfb

Please sign in to comment.