Spec-Zone.ru › Chef 16

О рецептах

[редактировать на GitHub]

Рецепт — это самый базовый элемент конфигурации в системе. Рецепт:

  • Написан на языке Ruby, который разработан для предсказуемого чтения и поведения
  • В основном представляет собой набор ресурсов, определенных с использованием шаблонов (имена ресурсов, пары атрибут-значение и действия); вспомогательный код добавляется вокруг этого кода Ruby, при необходимости
  • Должен определять все необходимое для конфигурации части системы
  • Должен храниться в кулинарной книге
  • Может быть включен в другой рецепт
  • Может использовать результаты запроса поиска и читать содержимое мешка данных (включая зашифрованный мешок данных)
  • Может иметь зависимость от одного (или нескольких) рецептов
  • Должен быть добавлен в список выполнения перед использованием Chef Infra Client
  • Всегда выполняется в том же порядке, что и в списке выполнения

Атрибуты рецепта

Атрибут может быть определен в кулинарной книге (или рецепте) и затем использоваться для переопределения значений по умолчанию на узле. Когда кулинарная книга загружается во время выполнения Chef Infra Client, эти атрибуты сравниваются с атрибутами, уже существующими на узле. Атрибуты, определенные в файлах атрибутов, загружаются в первую очередь в соответствии с порядком кулинарных книг. Для каждой кулинарной книги атрибуты в файле default.rb загружаются в первую очередь, а затем дополнительные файлы атрибутов (если они есть) загружаются в лексикографическом порядке. Когда атрибуты кулинарной книги имеют приоритет над атрибутами по умолчанию, Chef Infra Client применяет эти новые настройки и значения во время выполнения Chef Infra Client на узле.

Примечание

Атрибуты могут быть настроены в кулинарных книгах (файлах атрибутов и рецептах), ролях и средах. Кроме того, Ohai собирает данные об атрибутах каждого узла в начале выполнения Chef Infra Client. Более подробную информацию о том, как все эти атрибуты взаимодействуют, см. в разделе Атрибуты.

Типы атрибутов

Chef Infra Client использует шесть типов атрибутов для определения значения, применяемого к узлу во время выполнения Chef Infra Client. Кроме того, Chef Infra Client собирает значения атрибутов из до пяти источников. Сочетание типов атрибутов и источников образует до 15 различных конкурирующих значений, доступных во время выполнения Chef Infra Client:

Тип атрибута Описание
default Атрибут default автоматически сбрасывается в начале каждого выполнения Chef Infra Client и имеет наименьший приоритет атрибутов. Используйте атрибуты default как можно чаще в кулинарных книгах.
force_default Используйте атрибут force_default для обеспечения того, чтобы атрибут, определенный в кулинарной книге (файлом атрибутов или рецептом), имел приоритет над атрибутом default, заданным ролью или средой.
normal Атрибут normal — это настройка, которая сохраняется в объекте узла. Атрибут normal имеет более высокий приоритет атрибутов, чем атрибут default.
override Атрибут override автоматически сбрасывается в начале каждого выполнения Chef Infra Client и имеет более высокий приоритет, чем атрибуты default, force_default, и normal. Атрибут override чаще всего указывается в рецепте, но может быть указан в файле атрибутов, для роли и/или среды. Кулинарная книга должна быть написана таким образом, чтобы использовать атрибуты override только по мере необходимости.
force_override Используйте атрибут force_override для обеспечения того, чтобы атрибут, определенный в кулинарной книге (файлом атрибутов или рецептом), имел приоритет над атрибутом override, заданным ролью или средой.
automatic Атрибут automatic содержит данные, определенные Ohai в начале каждого выполнения Chef Infra Client. Атрибут automatic не может быть изменён и всегда имеет наивысший приоритет атрибутов.

Сохранение атрибутов

Все атрибуты, кроме обычных атрибутов, сбрасываются в начале выполнения Chef Infra Client. Атрибуты, заданные с помощью chef-client -j с файлом JSON, имеют обычный приоритет и сохраняются между выполнениями Chef Infra Client. Chef Infra Client перестраивает эти атрибуты, используя автоматически собранные Ohai атрибуты в начале каждого выполнения Chef Infra Client, а затем использует атрибуты по умолчанию и переопределяющие атрибуты, которые указаны в кулинарных книгах, ролях, средах и Policyfiles. Все атрибуты затем объединяются и применяются к узлу в соответствии с приоритетом атрибутов. Применённые к узлу атрибуты сохраняются на Chef Infra Server в качестве части объекта узла по завершении каждого выполнения Chef Infra Client.

Приоритет атрибутов

Атрибуты всегда применяются Chef Infra Client в следующем порядке:

  1. Атрибут default в файле атрибутов кулинарной книги
  2. Атрибут default в рецепте
  3. Атрибут default в среде
  4. Атрибут default в роли
  5. Атрибут force_default в файле атрибутов кулинарной книги
  6. Атрибут force_default в рецепте
  7. Атрибут normal в файле JSON, переданном через chef-client -j
  8. Атрибут normal в файле атрибутов кулинарной книги
  9. Атрибут normal в рецепте
  10. Атрибут override в файле атрибутов кулинарной книги
  11. Атрибут override в рецепте
  12. Атрибут override в роли
  13. Атрибут override в среде
  14. Атрибут force_override в файле атрибутов кулинарной книги
  15. Атрибут force_override в рецепте
  16. Атрибут automatic, определённый Ohai в начале выполнения Chef Infra Client

где последний атрибут в списке — тот, который применяется к узлу.

Примечание

Порядок приоритета атрибутов для ролей и сред инвертирован для атрибутов default и override. Порядок приоритета атрибутов default — среда, затем роль. Порядок приоритета атрибутов override — роль, затем среда. Применение атрибутов среды override после атрибутов роли override позволяет использовать одну и ту же роль в нескольких средах, но при этом обеспечивает возможность установки значений, специфичных для каждой среды (при необходимости). Например, роль сервера приложений может существовать во всех средах, но в одной среде может использоваться сервер базы данных, отличающийся от других сред.

Приоритет атрибутов, рассматриваемый с точки зрения диаграммы обзора, где номера на диаграмме соответствуют порядку приоритета атрибутов:

image

Приоритет атрибутов, представленный в виде таблицы:

image

Атрибуты списка исключений

Предупреждение

При использовании настроек списка исключений для атрибутов, любой атрибут, определенный в списке исключений, не будет сохранён на Chef Infra Server, а любой атрибут, не определённый в списке исключений, будет сохранён. Каждый тип атрибута должен быть исключён независимо от других типов атрибутов. Например, если blocked_automatic_attributes определяет атрибуты, которые не будут сохранены, но blocked_normal_attributes, blocked_default_attributes, и blocked_override_attributes не определены, то все обычные атрибуты, атрибуты по умолчанию и переопределяющие атрибуты будут сохранены, а также автоматические атрибуты, которые не были специально исключены из списка.

Атрибуты, которые не должны сохраняться узлом, могут быть исключены в файле client.rb. Список исключений представляет собой хеш ключей, которые указывают каждый атрибут для фильтрации.

Атрибуты исключаются по типу атрибута, при этом каждый тип атрибута исключается независимо. Каждый тип атрибута — automatic, default, normal, и override — может определять списки исключений, используя следующие настройки в файле client.rb:

Настройка Описание
blocked_automatic_attributes Хеш, исключающий атрибуты automatic, предотвращая сохранение исключённых атрибутов. Например: ['network/interfaces/eth0']. Значение по умолчанию: nil, все атрибуты сохраняются. Если массив пустой, все атрибуты сохраняются.
blocked_default_attributes Хеш, исключающий атрибуты default, предотвращая сохранение исключённых атрибутов. Например: ['filesystem/dev/disk0s2/size']. Значение по умолчанию: nil, все атрибуты сохраняются. Если массив пустой, все атрибуты сохраняются.
blocked_normal_attributes Хеш, исключающий атрибуты normal, предотвращая сохранение исключённых атрибутов. Например: ['filesystem/dev/disk0s2/size']. Значение по умолчанию: nil, все атрибуты сохраняются. Если массив пустой, все атрибуты сохраняются.
blocked_override_attributes Хеш, исключающий атрибуты override, предотвращая сохранение исключённых атрибутов. Например: ['map - autohome/size']. Значение по умолчанию: nil, все атрибуты сохраняются. Если массив пустой, все атрибуты сохраняются.

Исключение атрибутов Ohai (автоматических)

Рекомендуется использовать blocked_automatic_attributes для исключения атрибутов, заполненных с помощью сбора информации о системе Ohai. Ohai собирает большое количество атрибутов, которые могут занимать значительное место на Chef Infra Server. Многие из этих атрибутов могут быть ценными, а другие можно исключить без каких-либо последствий для доступных данных поиска. Обычные, атрибуты по умолчанию и переопределяющие атрибуты, как правило, более важны для использования в кулинарных книгах и, скорее всего, вызовут проблемы, если они будут неправильно исключены.

Например, автоматические данные атрибутов, похожие на:

{
  "filesystem" => {
    "/dev/disk0s2" => {
      "size" => "10mb"
    },
    "map - autohome" => {
      "size" => "10mb"
    }
  },
  "network" => {
    "interfaces" => {
      "eth0" => {...},
      "eth1" => {...},
    }
  }
}

Чтобы добавить filesystem атрибуты в список запрещённых и разрешить сохранение остальных атрибутов, обновите файл client.rb:

blocked_automatic_attributes ['filesystem']

При определении списка запрещённых атрибутов, любой атрибут данного типа, не указанный в этом списке, будет сохранён. Поэтому, основываясь на предыдущем списке запрещённых атрибутов для автоматических атрибутов, атрибуты filesystem и map - autohome не будут сохранены, а атрибуты network — будут.

Для атрибутов, содержащих косые черты (/) в значении атрибута, например, для атрибута filesystem '/dev/diskos2', используйте массив. Например:

blocked_automatic_attributes [['filesystem', '/dev/diskos2']]

Список запрещённых атрибутов

Предупреждение

При использовании настроек разрешённых атрибутов, будут сохранены только атрибуты, определённые в списке разрешённых атрибутов, а любые атрибуты, не определённые в списке, не будут сохранены. Каждый тип атрибутов разрешается независимо от других типов. Например, если automatic_attribute_allowlist определяет атрибуты для сохранения, но normal_attribute_allowlist, default_attribute_allowlist, и override_attribute_allowlist не определены, тогда все обычные атрибуты, атрибуты по умолчанию и переопределённые атрибуты будут сохранены, а также автоматические атрибуты, которые были включены в список разрешённых.

Атрибуты, которые должны быть сохранены узлом, могут быть включены в список разрешённых в файле client.rb. Список разрешённых атрибутов представляет собой хеш ключей, которые указывают каждый атрибут для сохранения.

Атрибуты разрешаются по типу атрибута, при этом каждый тип атрибутов разрешается независимо. Каждый тип атрибутов — automatic, default, normal, и override — может определять разрешённые списки, используя следующие настройки в файле client.rb:

Настройка Описание
allowed_automatic_attributes Хеш, который разрешает automatic атрибуты, предотвращая сохранение атрибутов, не включённых в список разрешённых. Например: ['network/interfaces/eth0']. Значение по умолчанию: nil, все атрибуты сохраняются. Если хеш пустой, атрибуты не сохраняются.
allowed_default_attributes Хеш, который разрешает default атрибуты, предотвращая сохранение атрибутов, не включённых в список разрешённых. Например: ['filesystem/dev/disk0s2/size']. Значение по умолчанию: nil, все атрибуты сохраняются. Если хеш пустой, атрибуты не сохраняются.
allowed_normal_attributes Хеш, который разрешает normal атрибуты, предотвращая сохранение атрибутов, не включённых в список разрешённых. Например: ['filesystem/dev/disk0s2/size']. Значение по умолчанию: nil, все атрибуты сохраняются. Если хеш пустой, атрибуты не сохраняются.
allowed_override_attributes Хеш, который разрешает override атрибуты, предотвращая сохранение атрибутов, не включённых в список разрешённых. Например: ['map - autohome/size']. Значение по умолчанию: nil, все атрибуты сохраняются. Если хеш пустой, атрибуты не сохраняются.

Разрешение атрибутов Ohai (автоматических)

Рекомендуется использовать allowed_automatic_attributes для разрешения конкретных атрибутов, заполняемых сборкой системной информации Ohai. Ohai собирает большое количество атрибутов, которые могут занимать значительное место на сервере Chef Infra. Многие из этих атрибутов могут быть очень ценными, а другие можно пропустить без ущерба для доступных данных в поиске. Обычные, стандартные и переопределённые атрибуты обычно являются гораздо более важными атрибутами, используемыми в кулинариях, и, скорее всего, вызовут проблемы, если их неправильно исключить из списка разрешённых.

Например, автоматические данные атрибутов, подобные:

{
  "filesystem" => {
    "/dev/disk0s2" => {
      "size" => "10mb"
    },
    "map - autohome" => {
      "size" => "10mb"
    }
  },
  "network" => {
    "interfaces" => {
      "eth0" => {...},
      "eth1" => {...},
    }
  }
}

Чтобы добавить network атрибуты в список разрешённых и запретить сохранение других атрибутов, обновите файл client.rb:

allowed_automatic_attributes ['network/interfaces/']

При определении списка разрешённых атрибутов, любой атрибут данного типа, не указанный в этом списке, не будет сохранён. Поэтому, основываясь на предыдущем списке разрешённых атрибутов для автоматических атрибутов, атрибуты filesystem и map - autohome не будут сохранены, а атрибуты network — будут.

Оставьте значение пустым, чтобы предотвратить сохранение всех атрибутов данного типа:

allowed_automatic_attributes []

Для атрибутов, содержащих косые черты (/) в значении атрибута, например, для атрибута filesystem '/dev/diskos2', используйте массив. Например:

allowed_automatic_attributes [['filesystem', '/dev/diskos2']]

Методы работы с файлами

Используйте следующие методы в файле атрибутов для кулинарии или в рецепте. Эти методы соответствуют типу атрибутов с тем же названием:

  • override
  • default
  • normal
  • _unless

Переменные среды

В UNIX, среда процесса — это набор пар «ключ-значение», предоставляемых процессу. Программы ожидают, что их среда будет содержать информацию, необходимую для работы программы. Подробности о том, как получить доступ к этим парам «ключ-значение», зависят от API используемого языка.

Если процессы запускаются с помощью ресурсов execute или script (или любых ресурсов, основанных на этих двух ресурсах, таких как bash), используйте атрибут environment для изменения среды, которая будет передана процессу.

bash 'env_test' do
  code <<-EOF
  echo $FOO
EOF
  environment ({ 'FOO' => 'bar' })
end

Изменяется только среда, передаваемая дочернему процессу, запущенному ресурсом bash. Это не повлияет на среду Chef Infra Client или дочерние процессы.

Работа с рецептами

В следующих разделах показаны подходы к работе с рецептами.

Использование пакетов данных

Пакеты данных хранят глобальные переменные как данные JSON. Пакеты данных индексированы для поиска и могут быть загружены кулинарией или использованы во время поиска.

Содержимое пакета данных можно загрузить в рецепт. Например, пакет данных под названием apps и элемент пакета данных под названием my_app:

{
  "id": "my_app",
  "repository": "git://github.com/company/my_app.git"
}

можно получить доступ в рецепте, так:

my_bag = data_bag_item('apps', 'my_app')

Ключи и значения элемента пакета данных можно получить с помощью хеша:

my_bag['repository'] #=> 'git://github.com/company/my_app.git'

Секретные ключи

Шифрование элемента пакета данных требует секретного ключа. Секретный ключ можно создать множеством способов. Например, OpenSSL можно использовать для генерации случайного числа, которое затем можно использовать в качестве секретного ключа:

openssl rand -base64 512 | tr -d '\r\n' > encrypted_data_bag_secret

где encrypted_data_bag_secret — имя файла, который будет содержать секретный ключ. Например, чтобы создать секретный ключ под названием «my_secret_key»:

openssl rand -base64 512 | tr -d '\r\n' > my_secret_key

Команда tr удаляет любые завершающие символы новой строки. Это предотвращает повреждение ключа при передаче файла между платформами с разными окончаниями строк.

Хранение ключей на узлах

Ключ шифрования также можно хранить в альтернативном файле на узлах, которые его используют, и указать путь к файлу в атрибуте; однако, EncryptedDataBagItem.load ожидает увидеть фактический секрет в качестве третьего аргумента, а не путь к файлу секрета. В этом случае можно использовать EncryptedDataBagItem.load_secret для загрузки содержимого файла секрета, а затем передать его:

# inside your attribute file:
# default[:mysql][:secretpath] = 'C:\\chef\\any_secret_filename'
#
# inside your recipe:
# look for secret in file pointed to by mysql attribute :secretpath
mysql_secret = Chef::EncryptedDataBagItem.load_secret('#{node['mysql']['secretpath']}')
mysql_creds = Chef::EncryptedDataBagItem.load('passwords', 'mysql', mysql_secret)
mysql_creds['pass'] # will be decrypted

Назначение зависимостей

Если кулинария зависит от рецепта, расположенного в другой кулинарии, эта зависимость должна быть объявлена в файле metadata.rb для этой кулинарии с использованием ключевого слова depends.

Примечание

Объявление зависимостей кулинарий не требуется с chef-solo.

Например, если следующий рецепт включён в кулинарию под названием my_app:

include_recipe 'apache2::mod_ssl'

Тогда файл metadata.rb для этой кулинарии будет содержать:

depends 'apache2'

Включение рецептов

Рецепт может включать один (или несколько) рецептов из кулинарий с использованием метода include_recipe. При включении рецепта, ресурсы, найденные в этом рецепте, будут вставлены (в том же самом порядке) в том месте, где расположено ключевое слово include_recipe.

Синтаксис включения рецепта выглядит так:

include_recipe 'recipe'

Например:

include_recipe 'apache2::mod_ssl'

В рецепте можно включить несколько рецептов. Например:

include_recipe 'cookbook::setup'
include_recipe 'cookbook::install'
include_recipe 'cookbook::configure'

Если определённый рецепт включён более одного раза с помощью метода include_recipe или где-либо в run_list непосредственно, обрабатывается только первый экземпляр, а последующие включения игнорируются.

Перезагрузка атрибутов

Иногда атрибуты зависят от действий, выполняемых в рецептах, поэтому может потребоваться перезагрузить заданный атрибут в рецепте. Например:

ruby_block 'some_code' do
  block do
    node.from_file(run_context.resolve_attribute('COOKBOOK_NAME', 'ATTR_FILE'))
  end
  action :nothing
end

Использование Ruby

Любое действие, которое можно выполнить с Ruby, можно использовать в рецепте, например, выражения (if, unless и т. д.), операторы case, операторы цикла, массивы, хеши и переменные. В Ruby условные операторы nil и false ложные; все остальные условные операторы true.

Назначение значения

Переменная использует знак равенства (=) для назначения значения.

Чтобы присвоить значение переменной:

package_name = 'apache2'

Использование оператора case

Оператор case может использоваться для сравнения выражения и затем выполнения соответствующего кода.

Чтобы выбрать имя пакета в зависимости от платформы:

package 'apache2' do
  case node['platform']
  when 'centos', 'redhat', 'fedora', 'suse'
    package_name 'httpd'
  when 'debian', 'ubuntu'
    package_name 'apache2'
  when 'arch'
    package_name 'apache'
  end
  action :install
end

Проверка условий

Выражение if может использоваться для проверки условий (истина или ложь).

Чтобы проверить условие только для платформ Debian и Ubuntu:

if platform?('debian', 'ubuntu')
  # do something if node['platform'] is debian or ubuntu
else
  # do other stuff
end

Выполнение условий

Выражение unless может использоваться для выполнения кода, когда условие возвращает ложное значение (по сути, выражение unless — это противоположность оператору if).

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

unless node['platform_version'] == '5.0'
  # do stuff on everything but 5.0
end

Перебор массива

Оператор цикла используется для выполнения блока кода один (или несколько) раз. Оператор цикла создается, когда .each добавляется к выражению, определяющему массив или хеш. Массив — это индексируемая целыми числами коллекция объектов. Каждый элемент в массиве может быть связан с индексом и ссылаться на него.

Чтобы перебрать массив имён пакетов по платформам:

['apache2', 'apache2-mpm'].each do |p|
  package p
end

Перебор хеша

Хеш — это коллекция пар ключ-значение. Индексация хеша выполняется с помощью произвольных ключей любого объекта (в отличие от индексации, выполняемой массивом). Синтаксис хеша: key => "value".

Чтобы перебрать хеш имён пакетов gem:

{ 'fog' => '0.6.0', 'highline' => '1.6.0' }.each do |g, v|
  gem_package g do
    version v
  end
end

Применение к списку выполнения

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

cookbooks/
  apache2/
    recipes/
      default.rb
      mod_ssl.rb

Существуют два рецепта: по умолчанию (имеющий то же имя, что и кулинарная книга) и рецепт с именем mod_ssl. Синтаксис, применяющий рецепт к списку выполнения, аналогичен:

{
  'run_list': [
  'recipe[cookbook_name::default_recipe]',
  'recipe[cookbook_name::recipe_name]'
  ]
}

где ::default_recipe подразумевается (и не нужно указывать). На узле эти рецепты могут быть назначены в список выполнения узла аналогично:

{
  'run_list': [
  'recipe[apache2]',
  'recipe[apache2::mod_ssl]'
  ]
}

Сервер Chef Infra

Используйте knife для добавления рецепта в список выполнения для узла. Например:

knife node run list add NODENAME "recipe[apache2]"

Можно добавить более одного рецепта:

% knife node run list add NODENAME "recipe[apache2],recipe[mysql],role[ssh]"

что создаёт список выполнения, аналогичный:

run_list:
   recipe[apache2]
   recipe[mysql]
   role[ssh]

chef-solo

Используйте файл JSON для передачи деталей списка выполнения в chef-solo, при условии, что кулинарная книга, в которой находится рецепт, доступна на системе, на которой выполняется chef-solo. Например, файл с именем dna.json содержит следующие данные:

{
  "run_list": ["recipe[apache2]"]
}

Чтобы добавить список выполнения на узел, введите следующее:

sudo chef-solo -j /etc/chef/dna.json

Использование результатов поиска

Индексы поиска позволяют выполнять запросы для любого типа данных, индексируемых сервером Chef Infra, включая мешки данных (и элементы мешков данных), среды, узлы и роли. Определённый синтаксис запроса поддерживает шаблоны поиска, такие как точный, с подстановкой символов, диапазон и приблизительный. Поиск — это полнотекстовый запрос, который можно выполнить из нескольких мест, включая рецепт, используя подкоманду search в knife, метод search в DSL-рецептах, поле поиска в консоли управления Chef и используя конечные точки /search или /search/INDEX в API сервера Chef Infra. Поисковая система основана на Elasticsearch и выполняется на сервере Chef Infra.

Результаты запроса поиска можно загрузить в рецепт. Например, очень простой запрос поиска (в рецепте) может выглядеть так:

search(:node, 'attribute:value')

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

webservers = search(:node, 'role:webserver')

template '/tmp/list_of_webservers' do
  source 'list_of_webservers.erb'
  variables(webservers: webservers)
end

Использование тегов

Тег — это пользовательское описание, которое применяется к узлу. Тег, после применения, может быть полезен при управлении узлами с помощью knife или при построении рецептов, предоставляя альтернативные методы группировки похожих типов информации.

Теги можно добавлять и удалять. Можно проверить, есть ли у машины определённый тег. Чтобы использовать теги в вашем рецепте, просто добавьте следующее:

tag('mytag')

Чтобы проверить, помечен ли узел тегом, добавьте следующее:

tagged?('mytag')

чтобы вернуть true или false. tagged? также может использовать массив в качестве аргумента.

Чтобы удалить тег:

untag('mytag')

Например:

tag('machine')

if tagged?('machine')
  Chef::Log.info("Hey I'm #{node['tags']}")
end

untag('machine')

unless tagged?('machine')
  Chef::Log.info('I am not tagged')
end

Вернёт что-то вроде этого:

[Thu, 22 Jul 2010 18:01:45 +0000] INFO: Hey I'm machine
[Thu, 22 Jul 2010 18:01:45 +0000] INFO: I has no tagz

Завершение выполнения клиента Chef Infra

Иногда может потребоваться остановить обработку рецепта и/или весь запуск клиента Chef Infra. Существует несколько способов сделать это:

  • Используйте ключевое слово return для остановки обработки рецепта на основе условия, но продолжайте обработку запуска клиента Chef Infra
  • Используйте ключевое слово raise для остановки запуска клиента Chef Infra, вызвав необработанное исключение
  • Используйте блок rescue в коде Ruby
  • Используйте обработчик исключений

В следующих разделах показаны различные подходы к завершению запуска клиента Chef Infra.

Ключевое слово return

Ключевое слово return можно использовать для остановки обработки рецепта на основе условия, но продолжить обработку запуска клиента Chef Infra. Например:

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

return if platform?('windows')

package 'name_of_package' do
  action :install
end

где platform?('windows') — это условие, установленное для ключевого слова return. При выполнении условия, остановите обработку рецепта. Этот подход полезен, когда нет необходимости продолжать обработку, например, когда пакет не может быть установлен. В этой ситуации приемлемо, чтобы рецепт остановил обработку.

Ключевое слово raise

В некоторых ситуациях может быть полезно полностью остановить запуск клиента Chef Infra, используя необработанное исключение. Ключевое слово raise можно использовать для остановки запуска клиента Chef Infra как в фазе компиляции, так и в фазе выполнения.

Примечание

Вы также можете увидеть код, использующий ключевое слово fail, которое работает аналогично, но не рекомендуется и приведёт к предупреждениям Cookstyle.

Используйте эти ключевые слова в рецепте (но вне любых блоков ресурсов) для вызова необработанного исключения во время фазы компиляции. Например:

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

raise "message" if platform?('windows')

package 'name_of_package' do
  action :install
end

где platform?('windows') — это условие, которое вызовет необработанное исключение.

Используйте эти ключевые слова в ресурсе ruby_block для вызова необработанного исключения во время фазы выполнения. Например:

ruby_block "name" do
  block do
    # Ruby code with a condition, e.g. if ::File.exist?(::File.join(path, "/tmp"))
    raise "message"  # e.g. "Ordering issue with file path, expected foo"
  end
end

Используйте эти ключевые слова в классе. Например:

class CustomError < StandardError; end

а затем позже:

def custom_error
  raise CustomError, "error message"
end

или:

def custom_error
  raise CustomError, "error message"
end

Блоки rescue

Поскольку рецепты написаны на Ruby, их можно написать так, чтобы они пытались обрабатывать ситуации с ошибками, используя блок rescue.

Например:

begin
  dater = data_bag_item(:basket, 'flowers')
rescue Net::HTTPClientException
  # maybe some retry code here?
  raise 'message_to_be_raised'
end

где data_bag_item делает HTTP-запрос к серверу Chef Infra для получения элемента мешка данных с именем flowers. Если возникнет проблема, запрос вернёт Net::HTTPClientException. Блок rescue можно использовать для попытки повтора или обработки ситуации. Если блок rescue не может обработать ситуацию, то ключевое слово raise используется для указания сообщения, которое должно быть поднято.

node.run_state

Используйте node.run_state для хранения временных данных во время запуска клиента Chef Infra. Эти данные могут передаваться между ресурсами и затем оцениваться в фазе выполнения. run_state — это пустой хеш, который всегда отбрасывается в конце запуска клиента Chef Infra.

Например, следующий рецепт установит веб-сервер Apache, случайным образом выберет PHP или Perl в качестве языка сценариев и затем установит выбранный язык:

package 'httpd' do
  action :install
end

ruby_block 'randomly_choose_language' do
  block do
    if Random.rand > 0.5
      node.run_state['scripting_language'] = 'php'
    else
      node.run_state['scripting_language'] = 'perl'
    end
  end
end

package 'scripting_language' do
  package_name lazy { node.run_state['scripting_language'] }
  action :install
end

где:

  • Ресурс ruby_block объявляет block кода Ruby, который выполняется во время фазы выполнения запуска клиента Chef Infra
  • Выражение if случайно выбирает PHP или Perl, сохраняя выбор в node.run_state['scripting_language']
  • Когда ресурс package должен установить пакет для языка сценариев, он ищет язык сценариев и использует тот, который определён в node.run_state['scripting_language']
  • lazy {} гарантирует, что ресурс package оценит это во время фазы выполнения запуска клиента Chef Infra (в отличие от фазы компиляции)

При выполнении этого рецепта клиент Chef Infra выведет что-то вроде следующего:

* ruby_block[randomly_choose_language] action run
 - execute the ruby block randomly_choose_language

* package[scripting_language] action install
 - install version 5.3.3-27.el6_5 of package php

© Chef Software, Inc.
Licensed under the Creative Commons Attribution 3.0 Unported License.
The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/servicemarks of Chef, in the United States and other countries and are used with Chef Inc's permission.
We are not affiliated with, endorsed or sponsored by Chef Inc.
https://docs.chef.io/recipes/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API