terraform: cbd works!

This commit is contained in:
Mitchell Hashimoto 2016-09-22 11:03:03 -07:00
parent 23665790f3
commit c1664d2eaa
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
7 changed files with 65 additions and 16 deletions

View File

@ -2297,6 +2297,7 @@ func TestContext2Apply_multiDepose_createBeforeDestroy(t *testing.T) {
checkStateString(t, state, ` checkStateString(t, state, `
aws_instance.web: (1 deposed) aws_instance.web: (1 deposed)
ID = bar ID = bar
provider = aws
Deposed ID 1 = foo Deposed ID 1 = foo
`) `)
@ -2321,6 +2322,7 @@ aws_instance.web: (1 deposed)
checkStateString(t, state, ` checkStateString(t, state, `
aws_instance.web: (2 deposed) aws_instance.web: (2 deposed)
ID = baz ID = baz
provider = aws
Deposed ID 1 = foo Deposed ID 1 = foo
Deposed ID 2 = bar Deposed ID 2 = bar
`) `)
@ -2348,6 +2350,7 @@ aws_instance.web: (2 deposed)
checkStateString(t, state, ` checkStateString(t, state, `
aws_instance.web: (1 deposed) aws_instance.web: (1 deposed)
ID = qux ID = qux
provider = aws
Deposed ID 1 = bar Deposed ID 1 = bar
`) `)
@ -2369,6 +2372,7 @@ aws_instance.web: (1 deposed)
checkStateString(t, state, ` checkStateString(t, state, `
aws_instance.web: aws_instance.web:
ID = quux ID = quux
provider = aws
`) `)
} }
@ -4746,8 +4750,10 @@ func TestContext2Apply_createBefore_depends(t *testing.T) {
State: state, State: state,
}) })
if _, err := ctx.Plan(); err != nil { if p, err := ctx.Plan(); err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} else {
t.Logf("plan: %s", p)
} }
h.Active = true h.Active = true
@ -4764,7 +4770,7 @@ func TestContext2Apply_createBefore_depends(t *testing.T) {
actual := strings.TrimSpace(state.String()) actual := strings.TrimSpace(state.String())
expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr) expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
if actual != expected { if actual != expected {
t.Fatalf("bad: \n%s\n%s", actual, expected) t.Fatalf("bad: \n%s\n\n%s", actual, expected)
} }
// Test that things were managed _in the right order_ // Test that things were managed _in the right order_

View File

@ -263,12 +263,13 @@ func (g *Graph) walk(walker GraphWalker) error {
rerr = err rerr = err
return return
} }
if g != nil {
// Walk the subgraph // Walk the subgraph
if rerr = g.walk(walker); rerr != nil { if rerr = g.walk(walker); rerr != nil {
return return
} }
} }
}
// If the node has a subgraph, then walk the subgraph // If the node has a subgraph, then walk the subgraph
if sn, ok := v.(GraphNodeSubgraph); ok { if sn, ok := v.(GraphNodeSubgraph); ok {

View File

@ -27,6 +27,9 @@ type ApplyGraphBuilder struct {
// Provisioners is the list of provisioners supported. // Provisioners is the list of provisioners supported.
Provisioners []string Provisioners []string
// DisableReduce, if true, will not reduce the graph. Great for testing.
DisableReduce bool
} }
// See GraphBuilder // See GraphBuilder
@ -103,10 +106,12 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
// Single root // Single root
&RootTransformer{}, &RootTransformer{},
}
if !b.DisableReduce {
// Perform the transitive reduction to make our graph a bit // Perform the transitive reduction to make our graph a bit
// more sane if possible (it usually is possible). // more sane if possible (it usually is possible).
&TransitiveReductionTransformer{}, steps = append(steps, &TransitiveReductionTransformer{})
} }
return steps return steps

View File

@ -69,6 +69,7 @@ func TestApplyGraphBuilder(t *testing.T) {
Diff: diff, Diff: diff,
Providers: []string{"aws"}, Providers: []string{"aws"},
Provisioners: []string{"exec"}, Provisioners: []string{"exec"},
DisableReduce: true,
} }
g, err := b.Build(RootModulePath) g, err := b.Build(RootModulePath)
@ -93,6 +94,14 @@ aws_instance.create
aws_instance.other aws_instance.other
aws_instance.create aws_instance.create
provider.aws provider.aws
meta.count-boundary (count boundary fixup)
aws_instance.create
aws_instance.other
module.child.aws_instance.create
module.child.aws_instance.other
module.child.provider.aws
provider.aws
provisioner.exec
module.child.aws_instance.create module.child.aws_instance.create
module.child.provider.aws module.child.provider.aws
provisioner.exec provisioner.exec
@ -103,7 +112,4 @@ module.child.provider.aws
provider.aws provider.aws
provider.aws provider.aws
provisioner.exec provisioner.exec
root
aws_instance.other
module.child.aws_instance.other
` `

View File

@ -6,7 +6,7 @@ import (
// NodeDestroyResource represents a resource that is to be destroyed. // NodeDestroyResource represents a resource that is to be destroyed.
type NodeDestroyResource struct { type NodeDestroyResource struct {
*NodeAbstractResource NodeAbstractResource
} }
func (n *NodeDestroyResource) Name() string { func (n *NodeDestroyResource) Name() string {
@ -38,6 +38,34 @@ func (n *NodeDestroyResource) References() []string {
return nil return nil
} }
// GraphNodeDynamicExpandable
func (n *NodeDestroyResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
// If we have no config we do nothing
if n.Config == nil {
return nil, nil
}
state, lock := ctx.State()
lock.RLock()
defer lock.RUnlock()
// Start creating the steps
steps := make([]GraphTransformer, 0, 5)
// We want deposed resources in the state to be destroyed
steps = append(steps, &DeposedTransformer{
State: state,
View: n.Config.Id(),
})
// Always end with the root being added
steps = append(steps, &RootTransformer{})
// Build the graph
b := &BasicGraphBuilder{Steps: steps}
return b.Build(ctx.Path())
}
// GraphNodeEvalable // GraphNodeEvalable
func (n *NodeDestroyResource) EvalTree() EvalNode { func (n *NodeDestroyResource) EvalTree() EvalNode {
// stateId is the ID to put into the state // stateId is the ID to put into the state

View File

@ -298,6 +298,7 @@ aws_instance.lb:
aws_instance.web aws_instance.web
aws_instance.web: aws_instance.web:
ID = foo ID = foo
provider = aws
require_new = ami-new require_new = ami-new
type = aws_instance type = aws_instance
` `
@ -305,6 +306,7 @@ aws_instance.web:
const testTerraformApplyCreateBeforeStr = ` const testTerraformApplyCreateBeforeStr = `
aws_instance.bar: aws_instance.bar:
ID = foo ID = foo
provider = aws
require_new = xyz require_new = xyz
type = aws_instance type = aws_instance
` `
@ -591,6 +593,7 @@ aws_instance.bar:
const testTerraformApplyErrorDestroyCreateBeforeDestroyStr = ` const testTerraformApplyErrorDestroyCreateBeforeDestroyStr = `
aws_instance.bar: (1 deposed) aws_instance.bar: (1 deposed)
ID = foo ID = foo
provider = aws
Deposed ID 1 = bar Deposed ID 1 = bar
` `

View File

@ -59,7 +59,7 @@ func (t *DiffTransformer) Transform(g *Graph) error {
// If we're destroying, add the destroy node // If we're destroying, add the destroy node
if inst.Destroy { if inst.Destroy {
abstract := &NodeAbstractResource{Addr: addr} abstract := NodeAbstractResource{Addr: addr}
g.Add(&NodeDestroyResource{NodeAbstractResource: abstract}) g.Add(&NodeDestroyResource{NodeAbstractResource: abstract})
} }