command/state: update and fix the state push and pull
This commit is contained in:
parent
17b883f592
commit
7fbd93b5cd
|
@ -1,9 +1,12 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/states/statefile"
|
||||||
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -34,37 +37,34 @@ func (c *StatePullCommand) Run(args []string) int {
|
||||||
|
|
||||||
// Get the state
|
// Get the state
|
||||||
env := c.Workspace()
|
env := c.Workspace()
|
||||||
state, err := b.StateMgr(env)
|
stateMgr, err := b.StateMgr(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
if err := state.RefreshState(); err != nil {
|
if err := stateMgr.RefreshState(); err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
s := state.State()
|
state := stateMgr.State()
|
||||||
if s == nil {
|
if state == nil {
|
||||||
// Output on "error" so it shows up on stderr
|
// Output on "error" so it shows up on stderr
|
||||||
c.Ui.Error("Empty state (no state)")
|
c.Ui.Error("Empty state (no state)")
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Ui.Error("state pull not yet updated for new state types")
|
// Get the state file.
|
||||||
return 1
|
stateFile := statemgr.StateFile(stateMgr, state)
|
||||||
|
|
||||||
/*
|
var buf bytes.Buffer
|
||||||
var buf bytes.Buffer
|
err = statefile.Write(stateFile, &buf)
|
||||||
if err := terraform.WriteState(s, &buf); err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Ui.Output(buf.String())
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
c.Ui.Output(buf.String())
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/copy"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestStatePull(t *testing.T) {
|
func TestStatePull(t *testing.T) {
|
||||||
tmp, cwd := testCwd(t)
|
// Create a temporary working directory that is empty
|
||||||
defer testFixCwd(t, tmp, cwd)
|
td := tempDir(t)
|
||||||
|
copy.CopyDir(testFixturePath("state-pull-backend"), td)
|
||||||
|
defer os.RemoveAll(td)
|
||||||
|
defer testChdir(t, td)()
|
||||||
|
|
||||||
// Create some legacy remote state
|
expected, err := ioutil.ReadFile("local-state.tfstate")
|
||||||
legacyState := testState()
|
if err != nil {
|
||||||
backendState, srv := testRemoteState(t, legacyState, 200)
|
t.Fatalf("error reading state: %v", err)
|
||||||
defer srv.Close()
|
}
|
||||||
testStateFileRemote(t, backendState)
|
|
||||||
|
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
@ -31,9 +36,8 @@ func TestStatePull(t *testing.T) {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "test_instance.foo"
|
actual := ui.OutputWriter.Bytes()
|
||||||
actual := ui.OutputWriter.String()
|
if bytes.Equal(actual, expected) {
|
||||||
if !strings.Contains(actual, expected) {
|
|
||||||
t.Fatalf("expected:\n%s\n\nto include: %q", actual, expected)
|
t.Fatalf("expected:\n%s\n\nto include: %q", actual, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/states/statefile"
|
||||||
|
"github.com/hashicorp/terraform/states/statemgr"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -31,86 +36,76 @@ func (c *StatePushCommand) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Ui.Error("state push not yet updated for new state types")
|
// Determine our reader for the input state. This is the filepath
|
||||||
return 1
|
// or stdin if "-" is given.
|
||||||
|
var r io.Reader = os.Stdin
|
||||||
/*
|
if args[0] != "-" {
|
||||||
// Determine our reader for the input state. This is the filepath
|
f, err := os.Open(args[0])
|
||||||
// or stdin if "-" is given.
|
|
||||||
var r io.Reader = os.Stdin
|
|
||||||
if args[0] != "-" {
|
|
||||||
f, err := os.Open(args[0])
|
|
||||||
if err != nil {
|
|
||||||
c.Ui.Error(err.Error())
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: we don't need to defer a Close here because we do a close
|
|
||||||
// automatically below directly after the read.
|
|
||||||
|
|
||||||
r = f
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the state
|
|
||||||
sourceState, err := terraform.ReadState(r)
|
|
||||||
if c, ok := r.(io.Closer); ok {
|
|
||||||
// Close the reader if possible right now since we're done with it.
|
|
||||||
c.Close()
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Error reading source state %q: %s", args[0], err))
|
c.Ui.Error(err.Error())
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the backend
|
// Note: we don't need to defer a Close here because we do a close
|
||||||
b, backendDiags := c.Backend(nil)
|
// automatically below directly after the read.
|
||||||
if backendDiags.HasErrors() {
|
|
||||||
c.showDiagnostics(backendDiags)
|
r = f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the state
|
||||||
|
srcStateFile, err := statefile.Read(r)
|
||||||
|
if c, ok := r.(io.Closer); ok {
|
||||||
|
// Close the reader if possible right now since we're done with it.
|
||||||
|
c.Close()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Error reading source state %q: %s", args[0], err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the backend
|
||||||
|
b, backendDiags := c.Backend(nil)
|
||||||
|
if backendDiags.HasErrors() {
|
||||||
|
c.showDiagnostics(backendDiags)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the state
|
||||||
|
env := c.Workspace()
|
||||||
|
stateMgr, err := b.StateMgr(env)
|
||||||
|
if err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if err := stateMgr.RefreshState(); err != nil {
|
||||||
|
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
dstState := stateMgr.State()
|
||||||
|
|
||||||
|
// If we're not forcing, then perform safety checks
|
||||||
|
if !flagForce && !dstState.Empty() {
|
||||||
|
dstStateFile := statemgr.StateFile(stateMgr, dstState)
|
||||||
|
|
||||||
|
if dstStateFile.Lineage != srcStateFile.Lineage {
|
||||||
|
c.Ui.Error(strings.TrimSpace(errStatePushLineage))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
if dstStateFile.Serial > srcStateFile.Serial {
|
||||||
// Get the state
|
c.Ui.Error(strings.TrimSpace(errStatePushSerialNewer))
|
||||||
env := c.Workspace()
|
|
||||||
state, err := b.StateMgr(env)
|
|
||||||
if err != nil {
|
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
if err := state.RefreshState(); err != nil {
|
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dstState := state.State()
|
// Overwrite it
|
||||||
|
if err := stateMgr.WriteState(srcStateFile.State); err != nil {
|
||||||
// If we're not forcing, then perform safety checks
|
c.Ui.Error(fmt.Sprintf("Failed to write state: %s", err))
|
||||||
if !flagForce && !dstState.Empty() {
|
return 1
|
||||||
if !dstState.SameLineage(sourceState) {
|
}
|
||||||
c.Ui.Error(strings.TrimSpace(errStatePushLineage))
|
if err := stateMgr.PersistState(); err != nil {
|
||||||
return 1
|
c.Ui.Error(fmt.Sprintf("Failed to write state: %s", err))
|
||||||
}
|
return 1
|
||||||
|
}
|
||||||
age, err := dstState.CompareAges(sourceState)
|
|
||||||
if err != nil {
|
|
||||||
c.Ui.Error(err.Error())
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
if age == terraform.StateAgeReceiverNewer {
|
|
||||||
c.Ui.Error(strings.TrimSpace(errStatePushSerialNewer))
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overwrite it
|
|
||||||
if err := state.WriteState(sourceState); err != nil {
|
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to write state: %s", err))
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
if err := state.PersistState(); err != nil {
|
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to write state: %s", err))
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ func TestStatePush_replaceMatchStdin(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
args := []string{"-"}
|
args := []string{"-force", "-"}
|
||||||
if code := c.Run(args); code != 0 {
|
if code := c.Run(args); code != 0 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ func TestStatePush_serialNewer(t *testing.T) {
|
||||||
|
|
||||||
args := []string{"replace.tfstate"}
|
args := []string{"replace.tfstate"}
|
||||||
if code := c.Run(args); code != 1 {
|
if code := c.Run(args); code != 1 {
|
||||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
t.Fatalf("bad: %d", code)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual := testStateRead(t, "local-state.tfstate")
|
actual := testStateRead(t, "local-state.tfstate")
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"serial": 0,
|
||||||
|
"lineage": "666f9301-7e65-4b19-ae23-71184bb19b03",
|
||||||
|
"backend": {
|
||||||
|
"type": "local",
|
||||||
|
"config": {
|
||||||
|
"path": "local-state.tfstate",
|
||||||
|
"workspace_dir": null
|
||||||
|
},
|
||||||
|
"hash": 4282859327
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
{
|
||||||
|
"path": [
|
||||||
|
"root"
|
||||||
|
],
|
||||||
|
"outputs": {},
|
||||||
|
"resources": {},
|
||||||
|
"depends_on": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"version": 4,
|
||||||
|
"terraform_version": "0.12.0",
|
||||||
|
"serial": 7,
|
||||||
|
"lineage": "configuredUnchanged",
|
||||||
|
"outputs": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "null_resource",
|
||||||
|
"name": "a",
|
||||||
|
"provider": "provider.null",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"id": "8521602373864259745",
|
||||||
|
"triggers": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
terraform {
|
||||||
|
backend "local" {
|
||||||
|
path = "local-state.tfstate"
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,9 +5,10 @@
|
||||||
"backend": {
|
"backend": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"config": {
|
"config": {
|
||||||
"path": "local-state.tfstate"
|
"path": "local-state.tfstate",
|
||||||
|
"workspace_dir": null
|
||||||
},
|
},
|
||||||
"hash": 9073424445967744180
|
"hash": 4282859327
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
{
|
{
|
||||||
"version": 3,
|
"version": 4,
|
||||||
"serial": 0,
|
"serial": 0,
|
||||||
"lineage": "hello"
|
"lineage": "hello",
|
||||||
|
"outputs": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "null_resource",
|
||||||
|
"name": "b",
|
||||||
|
"provider": "provider.null",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"id": "9051675049789185374",
|
||||||
|
"triggers": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
"backend": {
|
"backend": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"config": {
|
"config": {
|
||||||
"path": "local-state.tfstate"
|
"path": "local-state.tfstate",
|
||||||
|
"workspace_dir": null
|
||||||
},
|
},
|
||||||
"hash": 9073424445967744180
|
"hash": 4282859327
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
{
|
{
|
||||||
"version": 3,
|
"version": 4,
|
||||||
"serial": 1,
|
"serial": 1,
|
||||||
"lineage": "hello"
|
"lineage": "hello",
|
||||||
|
"outputs": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "null_resource",
|
||||||
|
"name": "a",
|
||||||
|
"provider": "provider.null",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"id": "8521602373864259745",
|
||||||
|
"triggers": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
{
|
{
|
||||||
"version": 3,
|
"version": 4,
|
||||||
"serial": 2,
|
"serial": 2,
|
||||||
"lineage": "hello"
|
"lineage": "hello",
|
||||||
|
"outputs": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "null_resource",
|
||||||
|
"name": "b",
|
||||||
|
"provider": "provider.null",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"id": "9051675049789185374",
|
||||||
|
"triggers": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
"backend": {
|
"backend": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"config": {
|
"config": {
|
||||||
"path": "local-state.tfstate"
|
"path": "local-state.tfstate",
|
||||||
|
"workspace_dir": null
|
||||||
},
|
},
|
||||||
"hash": 9073424445967744180
|
"hash": 4282859327
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
{
|
{
|
||||||
"version": 3,
|
"version": 4,
|
||||||
"serial": 3,
|
"serial": 3,
|
||||||
"lineage": "hello"
|
"lineage": "hello",
|
||||||
|
"outputs": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "null_resource",
|
||||||
|
"name": "a",
|
||||||
|
"provider": "provider.null",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"id": "8521602373864259745",
|
||||||
|
"triggers": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
{
|
{
|
||||||
"version": 3,
|
"version": 4,
|
||||||
"serial": 2,
|
"serial": 2,
|
||||||
"lineage": "hello"
|
"lineage": "hello",
|
||||||
|
"outputs": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "null_resource",
|
||||||
|
"name": "b",
|
||||||
|
"provider": "provider.null",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"id": "9051675049789185374",
|
||||||
|
"triggers": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
"backend": {
|
"backend": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"config": {
|
"config": {
|
||||||
"path": "local-state.tfstate"
|
"path": "local-state.tfstate",
|
||||||
|
"workspace_dir": null
|
||||||
},
|
},
|
||||||
"hash": 9073424445967744180
|
"hash": 4282859327
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
{
|
{
|
||||||
"version": 3,
|
"version": 4,
|
||||||
"serial": 1,
|
"serial": 1,
|
||||||
"lineage": "hello"
|
"lineage": "hello",
|
||||||
|
"outputs": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "null_resource",
|
||||||
|
"name": "a",
|
||||||
|
"provider": "provider.null",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"id": "8521602373864259745",
|
||||||
|
"triggers": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
{
|
{
|
||||||
"version": 3,
|
"version": 4,
|
||||||
"serial": 2,
|
"serial": 2,
|
||||||
"lineage": "hello"
|
"lineage": "hello",
|
||||||
|
"outputs": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "null_resource",
|
||||||
|
"name": "b",
|
||||||
|
"provider": "provider.null",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"id": "9051675049789185374",
|
||||||
|
"triggers": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,38 @@ package statemgr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/terraform/states"
|
"github.com/hashicorp/terraform/states"
|
||||||
|
"github.com/hashicorp/terraform/states/statefile"
|
||||||
|
"github.com/hashicorp/terraform/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewStateFile creates a new statefile.File object, with a newly-minted
|
||||||
|
// lineage identifier and serial 0, and returns a pointer to it.
|
||||||
|
func NewStateFile() *statefile.File {
|
||||||
|
return &statefile.File{
|
||||||
|
Lineage: NewLineage(),
|
||||||
|
TerraformVersion: version.SemVer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateFile is a special helper to obtain a statefile representation
|
||||||
|
// of a state snapshot that can be written later by a call
|
||||||
|
func StateFile(mgr Storage, state *states.State) *statefile.File {
|
||||||
|
ret := &statefile.File{
|
||||||
|
State: state.DeepCopy(),
|
||||||
|
TerraformVersion: version.SemVer,
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the given manager uses snapshot metadata then we'll save that
|
||||||
|
// in our file so we can check it again during WritePlannedStateUpdate.
|
||||||
|
if mr, ok := mgr.(PersistentMeta); ok {
|
||||||
|
m := mr.StateSnapshotMeta()
|
||||||
|
ret.Lineage = m.Lineage
|
||||||
|
ret.Serial = m.Serial
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
// RefreshAndRead refreshes the persistent snapshot in the given state manager
|
// RefreshAndRead refreshes the persistent snapshot in the given state manager
|
||||||
// and then returns it.
|
// and then returns it.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
package statemgr
|
|
|
@ -4,9 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
uuid "github.com/hashicorp/go-uuid"
|
uuid "github.com/hashicorp/go-uuid"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/states/statefile"
|
|
||||||
"github.com/hashicorp/terraform/version"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewLineage generates a new lineage identifier string. A lineage identifier
|
// NewLineage generates a new lineage identifier string. A lineage identifier
|
||||||
|
@ -21,12 +18,3 @@ func NewLineage() string {
|
||||||
}
|
}
|
||||||
return lineage
|
return lineage
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStateFile creates a new statefile.File object, with a newly-minted
|
|
||||||
// lineage identifier and serial 0, and returns a pointer to it.
|
|
||||||
func NewStateFile() *statefile.File {
|
|
||||||
return &statefile.File{
|
|
||||||
Lineage: NewLineage(),
|
|
||||||
TerraformVersion: version.SemVer,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue