Как вы прерываете / заканчиваете запуск шеф-повара?


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

каков наилучший способ сделать это?

5 51

5 ответов:

для читателей, приходящих к этому вопросу и ответу в будущем, которые могут быть не знакомы с Chef, Chef run "сходится" с узлом или приводит его в соответствие с политикой, объявленной в рецепте(рецептах), который он работает. Это также называется " конвергенцией."Это имеет две фазы, "компиляция" и " выполнение."Этап компиляции - это когда шеф-повар оценивает ("компилирует") код Ruby рецептов, ища ресурсы для добавления в коллекцию ресурсов. Как только это будет завершено, он "выполняет" действия для каждого ресурс для приведения его в нужное состояние. Системные команды выполняются, и т. д.

Эрик Холленсбе написал отлично пешком через как это работает в.

вот ответ:

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

если ваша цель состоит в том, чтобы остановить обработку рецепта на основе условие, но продолжить с остальной частью запуска, а затем использовать return ключевое слово Ruby. Например:

file '/tmp/ponies' do
  action :create
end

return if node['platform'] == 'windows'

package 'bunnies-and-flowers' do
  action :install
end

мы предполагаем, что если система Windows, она не имеет менеджера пакетов, который может установить пакет кроликов и цветов, поэтому мы возвращаемся.

если вы хотите, чтобы прервать шеф-повар запустить полностью

есть еще пара вещей, которые вы можете сделать. Шеф-повар выходит, если он сталкивается с необработанным исключением в любом месте запуска шеф-повара. Для например, если ресурс шаблона не может найти свой исходный файл или если у пользователя под управлением Chef нет разрешения на создание каталога. Вот почему с помощью raise работает, чтобы закончить запуск.

куда ты положил raise вопросы. Если вы используете его в ruby_block ресурс, он будет подниматься только на этапе выполнения в конвергенции. Если вы используете его за пределами ресурса, как return пример выше, это произойдет на этапе компиляции.

file '/tmp/ponies' do
  action :create
end

raise if node['platform'] == 'windows'

package 'bunnies-and-flowers' do
  action :install
end

возможно, мы есть менеджер пакетов для Windows, и мы хотим, чтобы этот пакет установлен. Повышение приведет к тому, что шеф-повар фатально выйдет и даст трассировку стека.

другой подход заключается в использовании Chef::Application.fatal!. Это журналы fatal сообщение к регистратору шеф-повара и STDERR, и выходит из приложения. Вы также можете дать ему код возврата (может быть, у вас есть скрипт, который проверяет их?).

Chef::Application.fatal!("Didn't expect the Spanish Inquistion", 42) if spanish_inquisition

(конечно spanish_inquisition обычно равен нулю, так как никто этого не ожидает... Я отступать...)

это приведет к выходу Chef, отправленному сообщению журнала и коду возврата 42 из процесса.

Примечание: это приводит к выходу всего приложения, то есть если оно работает как демонизированная служба, оно завершится, и в зависимости от того, как служба управляется, она может или не может запускаться снова. Например,init.d служба не перезапустится, но a runit сервис.

так как рецепты рубиновые, вы также можете изящно обрабатывать условия ошибок с помощью begin..rescue блок.

begin
  dater = data_bag_item(:basket, "flowers")
rescue Net::HTTPServerException
  # maybe some retry code here?
  raise "Couldn't find flowers in the basket, need those to continue!"
end

data_bag_item делает HTTP-запрос для пакета данных на сервере Chef и возвращает Net::HTTPServerException если есть проблема с сервера (404 не найден, 403 несанкционированного и т. д.). Мы могли бы попытаться повторить или сделать другую обработку, а затем вернуться к raise.

Сообщения Об Ошибках

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

введите отчет шеф-повара / функция обработчика исключений. Вы можете использовать обработчик для вашего шеф-повара работает. Все обработчики отчетов выполняются в конце выполнения Chef. Обработчики исключений выполняются в конце прерванного запуска Chef. Состояние выполнения отслеживается и может быть проверено в обработчик, поэтому вы можете написать тот, который обрабатывает оба вида запуска (успешный/завершенный или неудачный/прерванный).

The документация расскажет вам, как написать. Он также включает в себя список имеющихся обработчики с открытым исходным кодом что можно использовать для различных услуг, в том числе:

  • электронная почта через SMTP
  • IRC
  • графит
  • HipChat

и еще несколько.

рекомендуемый способ прервать или изменить запуск Chef-это создать исключение. Вот пример:

ruby_block "some tricky operation" do
  block do
    OperationFoo
    raise "Operation Foo Failed" if some_condition
  end
end

Шеф-Повар::Приложения.фатально! должен делать то, что вы ищете. Вот пример из нашей базы кода, который может быть полезен.

cipher = case key.length
    when 16 then "AES-128-ECB"
    when 24 then "AES-192-ECB"
    when 32 then "AES-256-ECB"
else
    Chef::Application.fatal!("AES Key must be 16, 24, or 32 characters in length but key #{key} has length of #{key.length}")
end

просто используйте ниже заявление, когда вы хотите chef чтобы закончить после некоторого действия:

throw :end_client_run_early

он выйдет без каких-либо ошибок.

чтобы сделать нечистый выход во время шеф-Соло запуска, попробуйте следующее:

bash 'exit' do
    code 'killall -9 chef-solo'
end