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

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

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(), кроме этой страницы, которая также указывает, что вы можете установить в рецепте как обычные атрибуты, так и атрибуты переопределения, но не говорит, как это сделать.

Итак... как правильно установить атрибуты (которые сливаются вместе со всем остальным) внутри рецепта? Что на самом деле делает вызов node.set(), и могу ли я указать ему приоритет, с которым я хочу выполнить слияние?


person Igor Serebryany    schedule 31.01.2013    source источник
comment
быстрый ответ, предоставленный @Draco Ater, node.default["key"] = "value", node.set["key"] = "value" и node.override["key"] = "value" для приоритета по умолчанию, нормального и переопределения соответственно.   -  person Igor Serebryany    schedule 01.02.2013


Ответы (3)


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. Но это устарело и скоро будет удалено — вот о чем предупреждение. Ознакомьтесь с страницей руководства по атрибутам, потому что на самом деле там все есть.

person Draco Ater    schedule 31.01.2013

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

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

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

  • отменить
  • По умолчанию
  • нормальный (или набор, где набор является псевдонимом для нормального)
  • _пока не
  • атрибут?

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

Атрибуты всегда применяются шеф-клиентом в следующем порядке:

  1. Атрибут по умолчанию, расположенный в файле атрибутов поваренной книги.
  2. Атрибут по умолчанию, расположенный в рецепте
  3. Атрибут по умолчанию, расположенный в среде
  4. Атрибут по умолчанию, расположенный в роли
  5. Атрибут force_default, расположенный в файле атрибутов поваренной книги.
  6. Атрибут force_default, расположенный в рецепте
  7. Обычный атрибут, расположенный в файле атрибутов поваренной книги.
  8. Обычный атрибут, расположенный в рецепте
  9. Атрибут переопределения, расположенный в файле атрибутов поваренной книги.
  10. Атрибут переопределения, расположенный в рецепте
  11. Атрибут переопределения, расположенный в роли
  12. Атрибут переопределения, расположенный в среде
  13. Атрибут force_override, расположенный в файле атрибутов поваренной книги.
  14. Атрибут force_override, расположенный в рецепте
  15. Автоматический атрибут, определяемый Ohai в начале запуска шеф-клиента.

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

Это означает, что атрибут OHAI будет иметь наивысший приоритет, тогда как атрибут по умолчанию в файле атрибутов поваренной книги будет иметь самый низкий приоритет.

Примечание. Для удобства пользователей предоставлены важные сведения из документации Chef для атрибутов. Потому что иногда URL-адрес будет перемещен или недействителен.

person Saravanan G    schedule 19.11.2015

Итак, покопавшись, я нашел ответ:

node.set
Используйте node.default (или, возможно, node.override) вместо node.set, потому что node.set — это псевдоним для node.normal. Обычные данные сохраняются в объекте узла. Следовательно, использование node.set сохранит данные в объекте узла. Если код, использующий node.set, впоследствии будет удален, если эти данные уже были установлены на узле, они останутся.

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

node.setnode.normal) следует использовать только для чего-то вроде создания пароля для базы данных при первом запуске шеф-клиента, после чего он запоминается (вместо сохранения). Даже этого случая следует избегать, так как использование пакета данных является рекомендуемым способом хранения данных такого типа.

person AngryChef    schedule 17.04.2015