LoginSignup
3
2

More than 5 years have passed since last update.

chef の include_recipe で同じレシピを2度実行する reinclude_recipe

Last updated at Posted at 2015-02-06

課題

chef の include_recipe は2度呼んでも1度しか実行してくれない。深遠な理由があってなんとかして2回実行したい。

レシピサンプルはこんなかんじ

recipes/include_recipe.rb
node['log'] = 'foo1'
include_recipe "foo::log"
node['log'] = 'foo2'
include_recipe "foo::log"
recipes/log.rb
log node['log'] do
  level :fatal
end

log リソースが1度目の include_recipe でしか実行されない

$ chef-solo -c solo.rb -o foo::include_recipe
Compiling Cookbooks...
Converging 1 resources
Recipe: foo::log
  * log[foo1] action write[2015-02-06T04:04:38+09:00] FATAL: foo1

やりかた

libraries として次のような monkey patch を定義する。

libraries/reload_recipe.rb
require 'chef/dsl/include_recipe'

class Chef
  module DSL
    module IncludeRecipe
      def reinclude_recipe(*recipe_names)
        recipe_names.each {|recipe_name| run_context.instance_variable_get(:@loaded_recipes).delete(recipe_name) }
        run_context.load_recipe(*recipe_names)
      end
    end
  end
end

include_recipe の代わりにここで定義した reinclude_recipe を使えば2度呼べるようになる (本当は ruby にあわせて load という名前にしたかったのだが、すでに使われていたので reinclude にした)

レシピサンプルはこんなかんじ

recipes/reinclude_recipe.rb
node['log'] = 'foo1'
reinclude_recipe "foo::log"
node['log'] = 'foo2'
reinclude_recipe "foo::log"
recipes/log.rb
log node['log'] do
  level :fatal
end

2度呼ばれてる

$ chef-solo -c solo.rb -o foo::reinclude_recipe
Compiling Cookbooks...
Converging 2 resources
Recipe: foo::log
  * log[foo1] action write[2015-02-06T04:04:10+09:00] FATAL: foo1
  * log[foo2] action write[2015-02-06T04:04:10+09:00] FATAL: foo2

おわりに

2回実行したいようなものは、レシピではなく definitions として定義するのが本筋。なので、良い子の皆は真似しないほうが良い。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2