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

Запретить поварскому рецепту выполнить ранее выполненное действие?

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

execute "test" do
  command "sh test.sh && touch /opt/myapp/done.log"
  only_if {File.exists?("/opt/myapp/done.log")}
end

Есть ли способ лучше? Это рекомендуемый способ?

Есть несколько способов сохранить execute от запуска несколько раз на узле:

  • С помощью not_if, only_if заявления.
  • С помощью action :nothing а затем уведомив об этом execute ресурс для запуска из другого ресурса. (только если вам нужно запускать его каждый раз при изменении первого ресурса)
  • С помощью creates [some/file] (Chef запустит его, только если файл не существует, эквивалентно not_if { ::File.exists? '[some/file]' }

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

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

Обычно я использую этот метод, особенно если команда, которую вы выполняете, приводит к созданию файла в качестве побочного эффекта. Например, отключение или включение сайтов в пакете Debian apache2 удаляет или создает ссылки в /etc/apache2 который вы можете протестировать на использование File.exists?.

Уловка заключается в том, чтобы установить атрибут после запуска исполняемого ресурса:

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

Обратите внимание, что ресурс выполнения по-прежнему может запускаться дважды в некоторых ситуациях, поэтому этот метод не идеален, но теперь вы можете использовать поиск с ножом, чтобы определить, какие узлы выполнили выполнение.