Назад | Перейти на главную страницу

Выполнение поваренной книги шеф-повара не работает, шаг за шагом

Конфигурация моего рецепта выглядит так:

package "scribe" do
  action :install
end

package "supervise-scripts" do
   action :install
end

remote_directory "/var/service/" do
   source "#{node['site-scribe']['cluster']}"
end

Dir.foreach('/var/service') do |dir|
next if dir == '..'|| dir == '.'
  execute "svc_add_#{dir}" do
    command "/usr/bin/svc-add #{dir}"
    not_if { ::Dir.exists?("/var/service/#{dir}/supervise") }
  end

  execute "svc_restart_#{dir}" do
    command "/usr/bin/svc-restart #{dir}"
  end
end

И теперь у меня странное поведение .. при первом запуске chef-client на сервере его единственное выполнение remote_directory блокировать и не запускать Dir.foreach петля. При втором запуске он выполняет Dir.foreach обычно (всегда когда remote_directory не был скачан). Почему моя петля Dir.foreach не запускается, если remote_directory блок был выполнен?

Такое же поведение, когда я удаляю это not_if.

// голозианский

Петля Dir.foreach выполняется до того, как действительно произойдет действие удаленного каталога. Chef выполняется в два этапа. Во время первого запускается весь ваш код рецепта, а ресурсы помещаются в массив для последующей оценки. На втором этапе эти ресурсы используются для фактического выполнения работы. Что происходит в вашем случае, как упоминал Стивен Кинг, так это:

  1. ваш remote_directory block запускается и помещает в шаблон ресурс для загрузки этого удаленного каталога.
  2. ваш Dir.foreach цикл выполняется, но поскольку ресурс для # 1 все еще находится в массиве (еще не был выполнен), в /var/service каталог. Таким образом, цикл проходит по 0 элементам и завершается.
  3. Во второй раз chef-client, тогда у вас есть значения в /var/service так что цикл отлично работает.

Если вам не НУЖНО добиться полного схождения всего за один раз, у вас действительно нет проблем. Просто убедитесь, что вы используете not_if и only_if операторы, чтобы гарантировать, что каждый ресурс запускается только при необходимости. Однако, если вам нужно сделать все за один прогон, придется взломать решение. Самый простой вариант - заставить немедленную оценку вашего remote_directory ресурс, сделав что-то вроде этого:

remote_directory "/var/service/" do
   source "#{node['site-scribe']['cluster']}"
end.run_action(:create)

Это заставит действие фактически выполняться на первом этапе выполнения повара, и тогда ваш цикл будет работать.