При управлении конфигурацией при помощи Chef, особенно в самом начале использования, возникает необходимость на свеже-введённой в работу системе установить необходимые наборы пакетов. Например, если привычка диктует что на системе должен быть htop и mc. Добавим сложности, нам надо что бы пакеты были из конкретного репозитария. Как можно решить такую задачу средствами Chef?
Вариант первый. Всё в кучу
На Communuty Site много примеров кукбуков с одним единственным рецептом, который делает исключительно установку одного пакета. Даже без настройки. Часто ставят не один пакет, а несколько, но это только ухудшает ситуацию потому что кукбук становится менее универсальным.
В таких рецептах добавление репозитария обычно происходит «на баше» и обычно только для одного дистрибутива или платформы.
При всей простоте и очевидности такое решение лишено универсальности и практически не имеет шансов на повторное использование, особенно вне инфраструктуры для которой было порождено. Придётся во-первых разбухает run_list, во-вторых при желании поставить ещё один пакет надо создавать ещё один кукбук и ещё сильнее тот же run_list увеличивать, а в-третьих не очевидно что делать если хочется некоторые пакеты поставить из своего репозитария. Плохо, это вариант для неленивых. Попробуем улучшить ситуацию.
Вариант второй. Ролевые игры.
В прошлом подходе явно хочется вынести список пакетов для установки в какое-то общее место и в самом рецепте в цикле иди по этому списку. На Community Cookbooks уже есть готовое решение — platform_packages. Кукбук позволяет установить на систему средствами штатной системы управления пакетами список, заданный в атрибутах или в датабэге. Почему до сих пор появляются новые рецепты из одного действия, которые не имеют почти никакой пользы, для меня остаётся загадкой.
Теперь решение выглядит уже приятнее, списки необходимых пакетов можно задать в базовой роли. В дополнительных ролях этот список можно уточнять и Chef сам сделает слияние этих списков. Более того, в настройках среды можно будет переопределить необходимое, например, если для тестовой среды нужно установить сборки со включённой отладочной информацией. Что у нас осталось улучшить очевидного от первого варианта? Настройка репозитория.
Вариант третий. Выносим из рецептов репозитарии.
Как можно сделать нашу настройку репозитария «на баше» более универсальной? Всё в тех же community рецептах есть готовый ресурс для манипуляций с APT репозитариями. Кстати, им пользуется сам Opscode, но прямо в рецепте, непосредственно перед установкой пакетов. Есть прекрасный кукбук для управления Yum, есть для Solaris, но если озаботиться настройкой своего репозитария непосредственно в рецепте и для всех платформ, то получится плохо читаемое нагромождение if-ов, а нам хочется красоты и изящества. Одновременно с этим хочется иметь возможность в тестовой и в продакшен средах использовать разные репозитарии, а это значит что надо использовать либо атрибуты, либо датабэги. Мы уже начали играть в ролевые игры, так что будем продолжать с атрибутами.
Предварительный поиск подходящего готового решения успехом не увенчался, так что будем делать свой велосипед на квадратных колёсах.
Пример роли в простейшем виде:
run_list(
"recipe[repos::percona]",
"recipe[repos::opscode-chef-10]",
"recipe[platform_packages]")
override_attributes(
"platform_packages" => {
"pkgs" =>
[ { "name" => "chef",
"action" => "upgrade"},
{ "name" => "percona-server-client"}
]})
Каждый рецепт в кукбуке будет настраивать один репозитарий под максимальное количество платформ. Для простоты пока есть только apt, может быть в будущем добрые люди добавят yum и прочие варианты.
Автор: realloc