0

This is an attempt to understand more about how the chef resource collection works and more importantly how to manipulate it with ruby code.

Chef has two phases, a compile and an execute phase. During the compile phase everything that calls a resource gets its own resource collection that is then executed sequentially. The built in methods for controlling the placement in a collection are :delayed, :immediately, :notifies and :subscribes.

A delayed resource will be placed at the end of its resource collection, immediately will be placed sequentially, a notifies will place the notified resource after the notifying resource and a subscribed resource will be placed after the resource it subscribes to.

The meat of the question is how can we override this behavior to place a resource on a resource collection that does not belong to what called the resource in the first place.

In other words, if recipe foo calls resource bar which includes resource oof how can we place resource oof onto the resource collection of recipe foo.

I don't expect a simple answer to this question and breadcrumbs are fully acceptable to me.

JackChance
  • 520
  • 3
  • 11
  • Sorry for the unhelpful comment but I'd move this to serverfault. – squarism Nov 09 '15 at 20:39
  • 1
    I disagree, it is totally about code. – StephenKing Nov 09 '15 at 21:01
  • In your example, the `bar` resource is declaring `oof`at runtime, right? So probably `oof` is in the resource collection, but not until bar's action actually runs. Have you tried running the `bar` resource's actions at compile time? Otherwise you're probably out of luck if you're trying to reference the resource in recipe `foo` -- because the resource doesn't exist yet when the `foo` recipe is running. I'd refer you to @StephenKing's answer, as it really is the breadcrumb you're looking for. – Martin Nov 10 '15 at 01:49

1 Answers1

2

You have some misunderstanding about how it works.

  1. During the compile phase, recipes are evaluated, the ruby code is them is run and a resource collection is build in the order the resources appear.
  2. At converge time, chef iterate on the resource collection, calling the action code for this resource.
  3. If a resource is updated and there's a notify or subscribe, then there's 2 options (I'll talk only about notify, subscire is just the pendant to the target)
    • :immediately -> the action method given in notify for target is called immediately
    • :delayed -> The action is queued up to be executed at end of run.

Note that for the 3. The resource collection is never changed during converge pgase, there's a separate queue created to run the :delayed notifications at end of run.


In other words, if recipe foo calls resource bar which includes resource oof how can we place resource oof onto the resource collection of recipe foo.

If I correctly understand what you mean, you wish the inner resource from a LWRP to show up in the run resource collection.

What happens with a LWRP is that the LWRP resource is added to the resource collection of the run at compile time. Once in converge time and at the call of this LWRP, an 'inner' chef is launched which will evaluated the provider code as a recipe, this inner run has no idea of what is in parent resource collection, so you can't notify an external resource within it.

This behavior is controled by use_inline_resource parameter.

Since chef 12.5 the new custom_resource model change the way LWRP are done and aim at simplifying theyr writing, the old syntax is announced to be deprecated.

Disabling the use_inline_resource in your LWRP sounds then a bad idea, what do you really try to achieve ? I've the feeling you're asking for a XY problem which maybe can be solved differently than your actual thinking.

Tensibai
  • 15,557
  • 1
  • 37
  • 57
  • Thanks for your answer. In this particular instance I was trying to add a restart resource that would run at the end of the entire run. Obviously the workaround is anytime the resource that needs the restart is called in a recipe the restart resource is notified delayed in the context of the recipe. My larger goal was to better understand resource timings which you helped with. – JackChance Nov 10 '15 at 18:41