0

I would like to include a recipe based on a conditional branch in another recipe. This is currently planned to be during the execution of a Ruby .each iterator.

The opscode wiki says the following about include_recipe, "...subsequent calls to include_recipe for the same recipe will have no effect."

I am assuming that this means one may not use include_recipe for the same recipe multiple times during a run. However, does this apply if it's being called during execution of an iterator?

Thanks!

UPDATE for Clarification:

So, just to clarify. recipe_1 is the main recipe. In recipe_1, I iterate through apps on the node and I want to include recipe_2 if Application_2 is on the node or recipe_3 if App_3 is on the node. If I have both Apps on the node, I want to make sure that the first iteration that includes recipe_2 is not still included in recipe_1 when the next iteration starts to run for App_3. Again, I'm wary of the documentation that states: The included recipe's resources will be inserted in order, at the point where include_recipe was called.

kries
  • 5
  • 1
  • 3
  • So the include_recipe for recipe_2 and recipe_3 occurs inside an if statement and you're worried about the order in which the resources in recipe_2 and recipe_3 will be executed? – Tim Potter Jan 17 '13 at 04:08
  • I'm actually more concerned that if, after recipe_2 is loaded during the first iteration, it will be part of recipe_1 during the iteration that should only include recipe_3. The way I read the documentation is that recipes are "inserted in order, at the point where include_recipe was called", so I'm concerned that the 2nd iteration will sort of re-read recipe_2 when it should only be including recipe_3. Put another way, I'm concerned that the "insert" of the included recipes is "cumulative". – kries Jan 17 '13 at 06:02

2 Answers2

4

Your suspicion is correct. include_recipe is cumulative within a RunContext (chef-client run). Pasted below is RunContext#load_recipe which is called by IncludeRecipe#load_recipe.

# Evaluates the recipe +recipe_name+. Used by DSL::IncludeRecipe
def load_recipe(recipe_name)
  Chef::Log.debug("Loading Recipe #{recipe_name} via include_recipe")

  cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name)
  if loaded_fully_qualified_recipe?(cookbook_name, recipe_short_name)
    Chef::Log.debug("I am not loading #{recipe_name}, because I have already seen it.")
    false
  else
    loaded_recipe(cookbook_name, recipe_short_name)

    cookbook = cookbook_collection[cookbook_name]
    cookbook.load_recipe(recipe_short_name, self)
  end
end
Sahil Muthoo
  • 156
  • 3
0

You may use include_recipe for the same recipe as much as you like (for example in an iterator) and it won't generate any errors or anything like that if you do include it multiple times.

The documentation is trying to say, and I've observed this in practice, is that the resources in the included recipe are updated once when the recipe is first included. Subsequent calls to include_recipe make no changes to the node.

Tim Potter
  • 1,764
  • 15
  • 15
  • Thanks Tim! After reading your other answers, I was hoping you'd see this. Anyhow - I just updated the question w/ a clarification and am hoping you can take another quick look! – kries Jan 17 '13 at 03:15