Допустим, у меня есть кулинарная книга, в которой настраивается и устанавливается волшебный деамон:
магический-деамон / рецепты / default.rb:
template "/etc/magical-deamon/magical.conf" do
source "magical.conf"
mode 0644
notifies :restart, resources(:service => "magical-deamon")
end
магический-деамон / атрибуты / default.rb:
default['magical-deamon']['memory'] = 1024
магический-деамон / шаблоны / по умолчанию / magical.conf.erb:
memory = <%= node['magical-deamon']['memory'] %>
Как я понял Chef, я бы использовал атрибуты узла для установки значения памяти, например:
{
"normal": {
"tags": [],
"magical-deamon": {
"memory": 256
}
},
"name": "server.example.com",
"chef_environment": "production",
"run_list": [
"role[base]"
]
}
Или через роль:
{
"name": "base",
"default_attributes": {
"magical-deamon": {
"memory": 756
}
},
"json_class": "Chef::Role",
"env_run_lists": {
},
"run_list": [
],
"description": "base role applied to all nodes",
"chef_type": "role",
"override_attributes": {
},
}
}
Или окружение:
{
"name": "production",
"default_attributes": {
"magical-deamon": {
"memory": 756
}
},
"json_class": "Chef::Environment",
"description": "",
"cookbook_versions": {
},
"override_attributes": {
},
"chef_type": "environment"
}
Все идет нормально...
Теперь у меня возникла глупая идея установить «память» на конкретное динамическое значение узла.
Допустим, наш волшебный демон должен потреблять 75% всей памяти, которой обладает узел.
value = total_memory * 0.75
Исходя из опыта программиста, я предпочитаю исключать эти знания из поваренной книги, потому что мне нравится, что моя поваренная книга может быть использована другими людьми.
Я подумал, что правильное место будет где-то, где устанавливаются атрибуты. Но выполнить такой расчет в json или ruby dsl невозможно.
Итак, мои вопросы:
Я не очень увлечен идеей total_memory, это несколько косвенное количество. Возможно, это имеет больше смысла в контексте того, чем является магический демон.
Для настраиваемых атрибутов, таких как общая память, я бы в значительной степени сделал то, что вы изложили в вопросе, добавив разумное значение по умолчанию в attributes / default.rb (сокращает вопросы поддержки, когда кто-то забывает явно установить значение) и переопределить с помощью при необходимости, значения, специфичные для среды, роли или узла.
Внутри файла ERB можно выполнять арифметические операции следующим образом:
memory = <%= (node['memory']['total'][0..-3].to_i / 1024) *
node['magical-daemon']['memory'] %>
Охай предоставляет статистику из free (1), которая включает общий объем памяти в килобайтах. node ['memory'] ['total'] = '12312432kB' на моей рабочей станции.
Я также стараюсь использовать атрибуты с самым низким приоритетом, насколько это возможно, т.е. предпочитаю атрибуты по умолчанию обычным атрибутам, а обычные атрибуты переопределяют атрибуты. Так,
Увидеть приоритет атрибута ссылку в вики Chef), чтобы узнать порядок, в котором атрибуты перекрывают друг друга.
Использование атрибутов по умолчанию с самым низким приоритетом там, где это возможно, позволяет вам установить значение атрибута в зависимости от среды, роли и узла, но освобождает верхние уровни приоритета, когда вам нужно сделать что-то сложное.