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