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

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

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

3 ответов


default.nginx_upstreams это то же самое, что default[:nginx_upstreams] и default['nginx_upstreams'] - конвенция должна использовать 1 из последних двух. И поскольку вы используете строки дальше, используйте их и здесь.

как вы init nginx_upstreams в файле атрибутов то же самое, что делать это следующим образом:

default['nginx_upstreams']['service1'] = ['service1.server.com']
default['nginx_upstreams']['service2'] = ['service2.server.com']

и вам не нужно init default['nginx_upstreams'] = {} до этого. Это не хэши, а атрибуты, и они намного умнее. :)

изменение атрибутов изнутри рецепта выполняется как что:

node.default['nginx_upstreams']['service3'] = ['service3.server.com']

можно использовать set или override вместо default здесь, Если вам нужно изменить приоритет. Опустить имя приоритета (node['nginx_upstreams'] или node.nginx_upstreams) будет использовать set верх. Но это устарело и скоро будет удалено - вот что такое предупреждение. Проверьте страница руководства об атрибутах, потому что все это на самом деле есть.


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

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

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

  • переопределить
  • по умолчанию
  • обычный (или набор, где set-псевдоним для normal)
  • _unless
  • ?

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

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

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

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

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

Примечание: при условии, важные детали от шеф-повара docs для атрибуты в интересах пользователей. Потому что иногда URL-адрес будет перемещен или недействителен.


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

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

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

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