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

Переопределение атрибутов в рецепте

Скажем, у меня есть атрибут по умолчанию в поваренной книге:

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(), и могу ли я сказать ему приоритет, с которым я хочу объединиться?

4b9b3361

Ответ 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.setnode.normal) следует использовать только для создания пароля для базы данных при первом запуске chef-client, после чего его запоминают (а не сохраняются). Даже этого случая следует избегать, так как использование пакета данных является рекомендуемым способом хранения данных этого типа.