Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

Эрик Холленсбе написал отличную статью о том, как это работает в 2013 году.

Теперь для ответа:

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

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

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

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

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

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

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

Tl; dr: использовать raise. Рекомендуется прервать запуск программы Chef в случае возникновения ошибки.

Тем не менее, chef-клиент завершает свою работу, если он встречает необработанное исключение в любом месте выполнения. Например, если ресурс шаблона не может найти свой исходный файл, или если пользователь, запускающий chef-client, не имеет разрешения на создание чего-либо вроде создания каталога. Вот почему использование 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! - как написано мной в этом ответе. Времена изменились, и это НЕ РЕКОМЕНДУЕТСЯ. Не делай так больше. Если вы делаете это, переключитесь на raise и, как уже упоминалось, напишите свой собственный обработчик исключений, если ваши потребности сложнее (см. Ниже).

Более изящная обработка ошибок

Поскольку рецепты являются Ruby, вы также можете begin..rescue обрабатывать ошибки с помощью блока 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 Server и возвращает Net::HTTPServerException если возникла проблема с сервером (404 не найден, 403 не авторизован и т.д.). Мы могли бы попытаться повторить попытку или выполнить другую обработку, а затем отступить, чтобы raise.

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

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

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

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

  • Электронная почта через SMTP
  • IRC
  • графитовый
  • HipChat

И многое другое

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

throw :end_client_run_early

Он выйдет без ошибок.

Ответ 5

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

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