terraform: handle logical dependencies during a delete
This commit is contained in:
parent
cb8e581731
commit
af3c55096c
|
@ -360,20 +360,10 @@ func graphAddDiff(g *depgraph.Graph, d *Diff) error {
|
||||||
Name: fmt.Sprintf("%s (destroy)", newNode.Resource.Id),
|
Name: fmt.Sprintf("%s (destroy)", newNode.Resource.Id),
|
||||||
Meta: newNode,
|
Meta: newNode,
|
||||||
}
|
}
|
||||||
newN.Deps = make([]*depgraph.Dependency, 0, len(n.Deps))
|
newN.Deps = make([]*depgraph.Dependency, len(n.Deps))
|
||||||
for _, d := range n.Deps {
|
|
||||||
// We don't want to copy any resource dependencies
|
|
||||||
if _, ok := d.Target.Meta.(*GraphNodeResource); ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// TODO: Maybe GraphNodeResourceMeta should be omitted?
|
|
||||||
|
|
||||||
newN.Deps = append(newN.Deps, &depgraph.Dependency{
|
// Copy all the dependencies and do a fixup later
|
||||||
Name: d.Name,
|
copy(newN.Deps, n.Deps)
|
||||||
Source: newN,
|
|
||||||
Target: d.Target,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append it to the list so we handle it later
|
// Append it to the list so we handle it later
|
||||||
nlist = append(nlist, newN)
|
nlist = append(nlist, newN)
|
||||||
|
@ -409,34 +399,54 @@ func graphAddDiff(g *depgraph.Graph, d *Diff) error {
|
||||||
// Go through each noun and make sure we calculate all the dependencies
|
// Go through each noun and make sure we calculate all the dependencies
|
||||||
// properly.
|
// properly.
|
||||||
for _, n := range nlist {
|
for _, n := range nlist {
|
||||||
rn := n.Meta.(*GraphNodeResource)
|
deps := n.Deps
|
||||||
|
num := len(deps)
|
||||||
// If we have no dependencies, then just continue
|
for i := 0; i < num; i++ {
|
||||||
deps := rn.Resource.State.Dependencies
|
dep := deps[i]
|
||||||
if len(deps) == 0 {
|
switch target := dep.Target.Meta.(type) {
|
||||||
continue
|
case *GraphNodeResource:
|
||||||
}
|
// If the other node is also being deleted,
|
||||||
|
// we must be deleted first. E.g. if A -> B,
|
||||||
// We have dependencies. We must be destroyed BEFORE those
|
// then when we create, B is created first then A.
|
||||||
// dependencies. Look to see if they're managed.
|
// On teardown, A is destroyed first, then B.
|
||||||
|
// Thus we must flip our depedency and instead inject
|
||||||
|
// it on B.
|
||||||
for _, n2 := range nlist {
|
for _, n2 := range nlist {
|
||||||
// Don't ever depend on ourselves
|
|
||||||
if n2.Name == n.Name {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, dep := range deps {
|
|
||||||
rn2 := n2.Meta.(*GraphNodeResource)
|
rn2 := n2.Meta.(*GraphNodeResource)
|
||||||
if rn2.Resource.Id == dep {
|
if target.Resource.Id == rn2.Resource.Id {
|
||||||
n2.Deps = append(n2.Deps, &depgraph.Dependency{
|
n2.Deps = append(n2.Deps, &depgraph.Dependency{
|
||||||
Name: n.Name,
|
Name: n.Name,
|
||||||
Source: n2,
|
Source: n2,
|
||||||
Target: n,
|
Target: n,
|
||||||
})
|
})
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drop the dependency. We may have created
|
||||||
|
// an inverse depedency if the dependent resource
|
||||||
|
// is also being deleted, but this dependence is
|
||||||
|
// no longer required.
|
||||||
|
deps[i], deps[num-1] = deps[num-1], nil
|
||||||
|
num--
|
||||||
|
i--
|
||||||
|
|
||||||
|
case *GraphNodeResourceMeta:
|
||||||
|
// Drop the dependency, since there is
|
||||||
|
// nothing that needs to be done for a meta
|
||||||
|
// resource on destroy.
|
||||||
|
deps[i], deps[num-1] = deps[num-1], nil
|
||||||
|
num--
|
||||||
|
i--
|
||||||
|
|
||||||
|
case *GraphNodeResourceProvider:
|
||||||
|
// Keep these around
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("Unhandled depedency type: %#v", dep.Meta))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
n.Deps = deps[:num]
|
||||||
|
}
|
||||||
|
|
||||||
// Add the nouns to the graph
|
// Add the nouns to the graph
|
||||||
g.Nouns = append(g.Nouns, nlist...)
|
g.Nouns = append(g.Nouns, nlist...)
|
||||||
|
|
Loading…
Reference in New Issue