Search code examples
rubychef-infralwrp

LWRP compile and converge phase


We found out that ruby code inside a LWRP action (especially a library) is always executed at converge phase (also without a ruby_block resource!). Is this the expected behaviour? We didn't find any specific documentation about that and knowing that ruby code normally gets executed during compile phase confuses us now a little bit. We use Chef 12.0.3.

Here is a mini-example:

in recipes/default.rb:

time = Time.new
puts "Current Time : " + time.inspect

converge_test_my_resource "test_resource" do
  action :install
end

in providers/my_resource.rb:

action :install do
  time = Time.new
  puts "Current Time : " + time.inspect
end

The output in kitchen is:

   Compiling Cookbooks...
   Current Time : 2016-01-18 16:37:52 +0100
   Converging 1 resources
   Recipe: converge_test::default
     * converge_test_my_resource[test_resource] action install
       Current Time : 2016-01-18 16:37:52 +0100
    (up to date)

So you see the first print of the timestamp is during compile phase, but the next print of the timestamp is in converge phase.

Thanks in advance!


Solution

  • You have over-generalized what happens.

    Compile Phase (resource gathering phase)

    Execute recipe code, which adds resources to the resource stack.

    Execute Phase (provider execution phase)

    For each resource on the resource stack create a provider for that resource execute the provider action code specified in the resource declaration ** next

    ** LWRP Providers

    Create a new execution context and treat this lwrp provider action like a recipe running in it's own chef-client run.

    This means that all resources declared outside of the LWRP provider go away and you literally have an independent run of chef inside this new context. That includes both the resource gathering phase and the provider execution phase. When this internal chef run completes, then you throw away all of those resources and exit the LWRP provider.