Make sure CBD is correct during apply, and saved

The resource apply nodes need to be GraphNodeDestroyerCBD in order to
correctly inherit create_before_destroy. While the plan will have
recorded this to create the correct deposed nodes, the edges still need
to be transformed correctly.

We also need create_before_destroy to be saved to state for nodes that
inherited it, so that if they are removed from state the destroy will
happen in the correct order.
This commit is contained in:
James Bardin 2020-05-14 14:10:17 -04:00
parent cf9b6de03e
commit 7731441beb
4 changed files with 46 additions and 33 deletions

View File

@ -22,17 +22,18 @@ import (
// EvalApply is an EvalNode implementation that writes the diff to
// the full diff.
type EvalApply struct {
Addr addrs.ResourceInstance
Config *configs.Resource
State **states.ResourceInstanceObject
Change **plans.ResourceInstanceChange
ProviderAddr addrs.AbsProviderConfig
Provider *providers.Interface
ProviderMetas map[addrs.Provider]*configs.ProviderMeta
ProviderSchema **ProviderSchema
Output **states.ResourceInstanceObject
CreateNew *bool
Error *error
Addr addrs.ResourceInstance
Config *configs.Resource
State **states.ResourceInstanceObject
Change **plans.ResourceInstanceChange
ProviderAddr addrs.AbsProviderConfig
Provider *providers.Interface
ProviderMetas map[addrs.Provider]*configs.ProviderMeta
ProviderSchema **ProviderSchema
Output **states.ResourceInstanceObject
CreateNew *bool
Error *error
CreateBeforeDestroy bool
}
// TODO: test
@ -308,7 +309,7 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) {
Status: newStatus,
Value: newVal,
Private: resp.Private,
CreateBeforeDestroy: n.Config.Managed.CreateBeforeDestroy,
CreateBeforeDestroy: n.CreateBeforeDestroy,
}
}

View File

@ -119,6 +119,7 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) {
newState.Value = resp.NewState
newState.Private = resp.Private
newState.Dependencies = state.Dependencies
newState.CreateBeforeDestroy = state.CreateBeforeDestroy
// Call post-refresh hook
err = ctx.Hook(func(h Hook) (HookAction, error) {

View File

@ -228,7 +228,6 @@ func (n *EvalWriteState) Eval(ctx EvalContext) (interface{}, error) {
log.Printf("[TRACE] EvalWriteState: removing state object for %s", absAddr)
return nil, nil
}
fmt.Printf("OBJ: %#v\n", obj)
// store the new deps in the state
if n.Dependencies != nil {

View File

@ -25,6 +25,10 @@ type NodeApplyableResourceInstance struct {
destroyNode GraphNodeDestroyerCBD
graphNodeDeposer // implementation of GraphNodeDeposerConfig
// If this node is forced to be CreateBeforeDestroy, we need to record that
// in the state to.
ForceCreateBeforeDestroy bool
}
var (
@ -42,20 +46,27 @@ func (n *NodeApplyableResourceInstance) AttachDestroyNode(d GraphNodeDestroyerCB
n.destroyNode = d
}
// createBeforeDestroy checks this nodes config status and the status af any
// CreateBeforeDestroy checks this nodes config status and the status af any
// companion destroy node for CreateBeforeDestroy.
func (n *NodeApplyableResourceInstance) createBeforeDestroy() bool {
cbd := false
func (n *NodeApplyableResourceInstance) CreateBeforeDestroy() bool {
if n.ForceCreateBeforeDestroy {
return n.ForceCreateBeforeDestroy
}
if n.Config != nil && n.Config.Managed != nil {
cbd = n.Config.Managed.CreateBeforeDestroy
return n.Config.Managed.CreateBeforeDestroy
}
if n.destroyNode != nil {
cbd = cbd || n.destroyNode.CreateBeforeDestroy()
return n.destroyNode.CreateBeforeDestroy()
}
return cbd
return false
}
func (n *NodeApplyableResourceInstance) ModifyCreateBeforeDestroy(v bool) error {
n.ForceCreateBeforeDestroy = v
return nil
}
// GraphNodeCreator
@ -78,7 +89,7 @@ func (n *NodeApplyableResourceInstance) References() []*addrs.Reference {
// would create a dependency cycle. We make a compromise here of requiring
// changes to be updated across two applies in this case, since the first
// plan will use the old values.
if !n.createBeforeDestroy() {
if !n.CreateBeforeDestroy() {
for _, ref := range ret {
switch tr := ref.Subject.(type) {
case addrs.ResourceInstance:
@ -254,7 +265,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
if diffApply != nil {
destroy = (diffApply.Action == plans.Delete || diffApply.Action.IsReplace())
}
if destroy && n.createBeforeDestroy() {
if destroy && n.CreateBeforeDestroy() {
createBeforeDestroyEnabled = true
}
return createBeforeDestroyEnabled, nil
@ -346,17 +357,18 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
Change: &diffApply,
},
&EvalApply{
Addr: addr.Resource,
Config: n.Config,
State: &state,
Change: &diffApply,
Provider: &provider,
ProviderAddr: n.ResolvedProvider,
ProviderMetas: n.ProviderMetas,
ProviderSchema: &providerSchema,
Output: &state,
Error: &err,
CreateNew: &createNew,
Addr: addr.Resource,
Config: n.Config,
State: &state,
Change: &diffApply,
Provider: &provider,
ProviderAddr: n.ResolvedProvider,
ProviderMetas: n.ProviderMetas,
ProviderSchema: &providerSchema,
Output: &state,
Error: &err,
CreateNew: &createNew,
CreateBeforeDestroy: n.CreateBeforeDestroy(),
},
&EvalMaybeTainted{
Addr: addr.Resource,
@ -411,7 +423,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
if !diff.Action.IsReplace() {
return true, nil
}
if !n.createBeforeDestroy() {
if !n.CreateBeforeDestroy() {
return true, nil
}
return false, nil