Переопределение атрибутов в рецепте
Скажем, у меня есть атрибут по умолчанию в поваренной книге:
default.nginx_upstreams = {
'service1' => ['service1.server.com'],
'service2' => ['service2.server.com'],
}
Затем он становится модифицированным и переопределенным в ролях и средах, пока он, наконец, не доберется до моего рецепта. Там я вычисляю некоторые дополнительные сервисы, которые я хотел бы добавить к атрибуту. Если я сделаю что-то вроде этого:
node.nginx_upstreams.merge! {'service3' => ['service3.server.com']}
то когда я пытаюсь использовать атрибут в своем шаблоне, я получаю undefined method 'each' for nil:NilClass
в моем шаблоне, когда я пытаюсь сделать
<% node.nginx_upstreams.each do |name, servers| %>
Кроме того, я также получаю WARN: Setting attributes without specifying a precedence is deprecated and will be removed in Chef 11.0
. Полезное предупреждение говорит мне, как устанавливать атрибуты при обычном приоритете (видимо, используя node.set["key"] = "value"
, но не говорит мне, как указать атрибуты по умолчанию или переопределить.
Я могу обойти эту проблему, выполнив что-то вроде этого:
upstreams = node.nginx_upstreams.to_hash
upstreams.merge! {'service3' => ['service3.server.com']}
template "nginx_config" do
variables({:upstreams=>upstreams})
end
но это похоже на хак. Я не могу найти документацию на node.set()
за this page, что также указывает, что вы можете установить как нормальные, так и переопределяющие атрибуты в рецепте, но не говорит, как это сделать.
Итак... как вы правильно устанавливаете атрибуты (которые объединяются вместе со всем остальным) изнутри рецепта? Что действительно делает вызов node.set()
, и могу ли я сказать ему приоритет, с которым я хочу объединиться?
Ответы
Ответ 1
default.nginx_upstreams
совпадает с default[:nginx_upstreams]
и default['nginx_upstreams']
- соглашение должно использовать 1 из последних двух. И поскольку вы используете строки далее, используйте их здесь тоже.
Способ инициализации nginx_upstreams
в файле атрибута аналогичен тому, как это делается:
default['nginx_upstreams']['service1'] = ['service1.server.com']
default['nginx_upstreams']['service2'] = ['service2.server.com']
И вам не нужно начинать default['nginx_upstreams'] = {}
до этого. Это не хеши, а атрибуты, и они намного умнее.:)
Изменение атрибутов внутри рецепта выполняется следующим образом:
node.default['nginx_upstreams']['service3'] = ['service3.server.com']
Здесь вы можете использовать set
или override
вместо default
, если вам нужно изменить приоритет. Опущение имени приоритета (node['nginx_upstreams']
или node.nginx_upstreams
) будет использовать приоритет set
. Но это устарело и скоро будет удалено - вот что такое предупреждение.
Ознакомьтесь с справочной страницей об атрибутах, потому что все на самом деле там.
Ответ 2
Просто хотел дать дополнительную информацию о атрибутах Chef, это очень важно для пользователей, которые собираются передать этот вопрос на переопределение атрибута node.
Файловые методы соответствуют атрибутам
Используйте следующие методы в файле атрибутов для поваренной книги или в рецепте. Эти методы соответствуют типу атрибута с тем же именем:
- переопределить
- По умолчанию
- normal (или set, где set является псевдонимом для нормального)
- _unless
- атрибут?
Приоритет атрибута
Атрибуты всегда применяются шеф-клиентом в следующем порядке:
- Атрибут по умолчанию, расположенный в файле атрибута cookbook
- Атрибут по умолчанию, расположенный в рецепте
- Атрибут по умолчанию, расположенный в среде
- Атрибут по умолчанию, расположенный в роли
- Атрибут force_default, расположенный в файле атрибута cookbook
- Атрибут force_default, расположенный в рецепте
- Обычный атрибут, расположенный в файле атрибута cookbook
- Обычный атрибут, расположенный в рецепте
- Атрибут переопределения, расположенный в файле атрибута cookbook
- Атрибут переопределения, расположенный в рецепте
- Атрибут переопределения, расположенный в роли
- Атрибут переопределения, расположенный в среде
- Атрибут force_override, расположенный в файле атрибута cookbook
- Атрибут force_override, расположенный в рецепте
- Автоматический атрибут, идентифицированный Ohai в начале запуска chef-client
где последним атрибутом в списке является тот, который применяется к node.
Это означает, что атрибут OHAI будет иметь наивысший приоритет, когда атрибут по умолчанию в файле атрибута cookbook будет иметь наименьшее приоритет.
Примечание. Предоставлены важные сведения из документов Chef для attributes в интересах пользователей. Потому что иногда URL-адрес будет перемещен или недействителен.
Ответ 3
Итак, после копания, я нашел ответ:
node.set
Используйте node.default
(или, возможно, node.override) вместо node.set, потому что node.set - это псевдоним для node.normal. Нормальные данные сохраняются в объекте node. Поэтому использование node.set будет сохраняться в объекте node. Если код, который использует node.set, будет удален, если эти данные уже установлены на node, он останется.
Нормальные и переопределяемые атрибуты очищаются в начале прогона chef-client и затем перестраиваются как часть прогона на основе кода в кулинарных книгах и рецептах в то время.
node.set
(и node.normal
) следует использовать только для создания пароля для базы данных при первом запуске chef-client, после чего его запоминают (а не сохраняются). Даже этого случая следует избегать, так как использование пакета данных является рекомендуемым способом хранения данных этого типа.