Предотвратить рецепт шеф-повара от выполнения ранее выполненного действия?

У меня есть простой рецепт, подобный следующему, и в настоящее время я использую локальный файл, чтобы указать, была ли команда выполнена или нет

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]' }

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

За исключением того, что код, который вы предоставили, будет фактически работать, если файл существует. Но я полагаю, что это опечатка.

Другие вопросы по тегам