command/state: helpers for UX with lock/unlock state
This commit is contained in:
parent
2124135287
commit
34f438b635
|
@ -0,0 +1,83 @@
|
|||
// Package state exposes common helpers for working with state from the CLI.
|
||||
//
|
||||
// This is a separate package so that backends can use this for consistent
|
||||
// messaging without creating a circular reference to the command package.
|
||||
package message
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/slowmessage"
|
||||
"github.com/hashicorp/terraform/state"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/mitchellh/colorstring"
|
||||
)
|
||||
|
||||
const (
|
||||
LockThreshold = 250 * time.Millisecond
|
||||
LockMessage = "Acquiring state lock. This may take a few moments..."
|
||||
UnlockMessage = "Releasing state lock. This may take a few moments..."
|
||||
|
||||
UnlockErrorMessage = `
|
||||
[reset][bold][red]Error releasing the state lock![reset][red]
|
||||
|
||||
Error message: %s
|
||||
|
||||
Terraform acquires a lock when accessing your state to prevent others
|
||||
running Terraform to potentially modify the state at the same time. An
|
||||
error occurred while releasing this lock. This could mean that the lock
|
||||
did or did not release properly. If the lock didn't release properly,
|
||||
Terraform may not be able to run future commands since it'll appear as if
|
||||
the lock is held.
|
||||
|
||||
In this scenario, please call the "force-unlock" command to unlock the
|
||||
state manually. This is a very dangerous operation since if it is done
|
||||
erroneously it could result in two people modifying state at the same time.
|
||||
Only call this command if you're certain that the unlock above failed and
|
||||
that no one else is holding a lock.
|
||||
`
|
||||
)
|
||||
|
||||
// Lock locks the given state and outputs to the user if locking
|
||||
// is taking longer than the threshold.
|
||||
func Lock(s state.State, info string, ui cli.Ui, color *colorstring.Colorize) error {
|
||||
sl, ok := s.(state.Locker)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return slowmessage.Do(LockThreshold, func() error {
|
||||
return sl.Lock(info)
|
||||
}, func() {
|
||||
if ui != nil {
|
||||
ui.Output(color.Color(LockMessage))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Unlock unlocks the given state and outputs to the user if the
|
||||
// unlock fails what can be done.
|
||||
func Unlock(s state.State, ui cli.Ui, color *colorstring.Colorize) error {
|
||||
sl, ok := s.(state.Locker)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := slowmessage.Do(LockThreshold, sl.Unlock, func() {
|
||||
if ui != nil {
|
||||
ui.Output(color.Color(UnlockMessage))
|
||||
}
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
ui.Output(color.Color(fmt.Sprintf(
|
||||
"\n"+strings.TrimSpace(UnlockErrorMessage)+"\n", err)))
|
||||
|
||||
err = fmt.Errorf(
|
||||
"Error releasing the state lock. Please see the longer error message above.")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
Loading…
Reference in New Issue