| // statelocker use used for testing command with a locked state. |
| // This will lock the state file at a given path, then wait for a sigal. On |
| // SIGINT and SIGTERM the state will be Unlocked before exit. |
| package main |
| |
| import ( |
| "io" |
| "log" |
| "os" |
| "os/signal" |
| "syscall" |
| "time" |
| |
| "github.com/hashicorp/terraform/internal/command/clistate" |
| "github.com/hashicorp/terraform/internal/states/statemgr" |
| ) |
| |
| func main() { |
| if len(os.Args) != 2 { |
| log.Fatal(os.Args[0], "statefile") |
| } |
| |
| s := &clistate.LocalState{ |
| Path: os.Args[1], |
| } |
| |
| info := statemgr.NewLockInfo() |
| info.Operation = "test" |
| info.Info = "state locker" |
| |
| lockID, err := s.Lock(info) |
| if err != nil { |
| io.WriteString(os.Stderr, err.Error()) |
| return |
| } |
| |
| // signal to the caller that we're locked |
| io.WriteString(os.Stdout, "LOCKID "+lockID) |
| |
| defer func() { |
| if err := s.Unlock(lockID); err != nil { |
| io.WriteString(os.Stderr, err.Error()) |
| } |
| }() |
| |
| c := make(chan os.Signal, 1) |
| signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) |
| |
| // timeout after 10 second in case we don't get cleaned up by the test |
| select { |
| case <-time.After(10 * time.Second): |
| case <-c: |
| } |
| } |