Конфигурация моего рецепта выглядит так:
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 выполняется в два этапа. Во время первого запускается весь ваш код рецепта, а ресурсы помещаются в массив для последующей оценки. На втором этапе эти ресурсы используются для фактического выполнения работы. Что происходит в вашем случае, как упоминал Стивен Кинг, так это:
remote_directory
block запускается и помещает в шаблон ресурс для загрузки этого удаленного каталога. Dir.foreach
цикл выполняется, но поскольку ресурс для # 1 все еще находится в массиве (еще не был выполнен), в /var/service
каталог. Таким образом, цикл проходит по 0 элементам и завершается.chef-client
, тогда у вас есть значения в /var/service
так что цикл отлично работает.Если вам не НУЖНО добиться полного схождения всего за один раз, у вас действительно нет проблем. Просто убедитесь, что вы используете not_if
и only_if
операторы, чтобы гарантировать, что каждый ресурс запускается только при необходимости. Однако, если вам нужно сделать все за один прогон, придется взломать решение. Самый простой вариант - заставить немедленную оценку вашего remote_directory
ресурс, сделав что-то вроде этого:
remote_directory "/var/service/" do
source "#{node['site-scribe']['cluster']}"
end.run_action(:create)
Это заставит действие фактически выполняться на первом этапе выполнения повара, и тогда ваш цикл будет работать.