Предотвратить рецепт шеф-повара от выполнения ранее выполненного действия?
У меня есть простой рецепт, подобный следующему, и в настоящее время я использую локальный файл, чтобы указать, была ли команда выполнена или нет
execute "test" do
command "sh test.sh && touch /opt/myapp/done.log"
only_if {File.exists?("/opt/myapp/done.log")}
end
Есть ли лучший метод? Это рекомендуемый способ?
2 ответа
Обычно это метод, который я использую, особенно если команда, которую вы принимаете, приводит к созданию файла в качестве побочного эффекта. Например, отключение или включение сайтов в пакете apache2 Debian удаляет или создает ссылки в /etc/apache2
который вы можете проверить для использования File.exists?
,
Хитрость заключается в том, чтобы установить атрибут после запуска ресурса execute:
if !node["did_test"]
execute "test" do
command "touch /tmp/foo"
end
end
ruby_block "did_test" do
block do
node.normal["did_test"] = true
end
end
Обратите внимание, что в некоторых ситуациях ресурс execute все еще может запускаться дважды, поэтому этот метод не идеален, но теперь вы можете использовать поиск ножом, чтобы определить, какие узлы выполнили выполнение.
Есть несколько способов сохранить execute
от запуска несколько раз на узле:
- С помощью
not_if
,only_if
заявления. - С помощью
action :nothing
а затем уведомить об этомexecute
ресурс для запуска из другого ресурса. (только если вам нужно запускать его каждый раз, когда меняется первый ресурс) - С помощью
creates [some/file]
(Chef запустит его, только если файл не существует, эквивалентноnot_if { ::File.exists? '[some/file]' }
Если вы не можете легко определить, был ли ваш скрипт запущен без создания дополнительного файла, тогда это единственный способ. Так что, на самом деле, вы все делаете правильно.
За исключением того, что код, который вы предоставили, будет фактически работать, если файл существует. Но я полагаю, что это опечатка.