Вариант использования, который я пытаюсь проиллюстрировать, - это когда объявлять какой-либо элемент (службу eq mysqld) с конфигурацией по умолчанию, которая может быть включена на каждый узел (разделение классов в примере для базового узла), и при этом иметь возможность переопределить этот же элемент в некоторый конкретный класс (например, mysql :: server), который должен быть включен конкретными узлами (например, myserver.local)
Я проиллюстрировал этот вариант использования приведенным ниже примером, где я хочу отключить службу mysql на всех узлах, но активировать ее на определенном узле. Но, конечно, анализ Puppet не выполняется, потому что служба [mysql] включается дважды. И, конечно же, класс mysql :: server не имеет отношения к дочернему классу stripdown.
Есть ли способ переопределить Сервис ["mysql"], или пометить его как основной, или что-то еще? Я думал о виртуальных элементах и функции реализации, но она позволяет применять элемент только несколько раз, а не переопределять или отменять.
# In stripdown.pp :
class stripdown {
service {"mysql": enable => "false", ensure => "stopped" }
}
# In mysql.pp :
class mysql::server {
service { mysqld:
enable => true,
ensure => running,
hasrestart => true,
hasstatus => true,
path => "/etc/init.d/mysql",
require => Package["mysql-server"],
}
}
# Then nodes in nodes.pp :
node basenode {
include stripdown
}
node myserver.local inherits basenode {
include mysql::server` # BOOM, fails here because of Service["mysql"] redefinition
}
Всякий раз, когда вы обнаруживаете, что говорите: «Я хочу, чтобы этот компонент вел себя одним способом в одном узле, но другим - в другом узле», вам, вероятно, придется смотреть на определение, управляемое переменными, либо через условные выражения в определении класса, либо через подстановки. в шаблоне.
К сожалению, ваш пример показывает, что вы пытаетесь использовать наследование, которое довольно сильно нарушено в марионетке и причинит вам много огорчений, потому что одна из вещей, которые он нарушает, - это переопределение переменных в узлах.
ОБНОВЛЕНИЕ: старые детали ответа устарели
Что я делаю начиная с версии 2.7, так это то, что все переменные, используемые классом, вообще не являются глобальными переменными, а являются параметрами с разумными значениями по умолчанию. Вы по-прежнему не хотите использовать наследование, встроенное в Puppet, но теперь вы можете переопределить определенные переменные непосредственно из определения узла, и вы даже можете иметь примитивную форму наследования вручную, если один класс принимает переменные, а затем передает их вызову другой класс. Например, в определениях ваших узлов должны быть:
node experimental_server {
# This will still call class 'databases', but will install Postgresql and not Mysql
# as a default. You can still override it the same way as with 'databases'
class { 'mydept::nextgeneration': },
}
node server_with_mysql {
class { 'databases':
mysql_enabled => true,
}
}
node server_with_no_db {
class { 'databases': # this installs only the clients }
}
class databases (
# By default, install no servers, just clients
$pgsql_enabled => false,
$mysql_enabled => false
)
{
...
}
class mydept::nextgeneration (
# If not explicitly overridden, an undef value passed as a parameter to a class
# assumes the default value in that class
$mysql_enabled => undef,
$pgsql_enabled => true
)
{
class { 'databases':
mysql_enabled => $mysql_enabled,
pgsql_enabled => $pgsql_enabled,
}
}
Как отметил комментатор, теперь есть отличная новая функция под названием Hiera, которая позволяет выгрузить значения по умолчанию в отдельную структуру данных, и вы должны изучить ее, если у вас есть Puppet 3.2. К сожалению, многие дистрибутивы Linux по-прежнему поставляются с версиями 2.6 или 2.7, так что это еще не вариант для вас.
Детали предыдущего ответа сохранены ниже
Обычно я обрабатываю что-то подобное: создаю файл default_parameters.pp, в котором нет ничего, кроме назначений по умолчанию для длинного списка переменных, поэтому в этом случае он будет содержать строку вроде $mysql_enabled = false
. Затем этот файл включается в файл init.pp модуля. Тогда файл определений узлов будет выглядеть примерно так:
import "mymodule"
node myserver.local { # NOTE: no inheritance!
$mysql_enabled = true
include mysql::server
}
node otherserver.local {
include mysql::server
}
Затем в определении класса для mysql :: server вы проверяете, $mysql_enabled
верно, и если да, используйте селектор на enable
и ensure
.
Это мгновенно прерывается, если node myserver.local наследует что-либо, потому что это заблокирует значение переменных во время наследования, и дальнейшие изменения внутри определения узла не будут иметь никакого эффекта, но в противном случае я использую этот метод повсюду, чтобы иметь отдельные компоненты вести себя по-разному, не создавая нескольких классов.
Если вам абсолютно необходимо иметь наследование, но список машин с включенным mysql невелик, вы можете выбрать альтернативный путь: вместо того, чтобы устанавливать переменную в определении узла, создайте свой селектор из $fqdn
, по умолчанию отключено, а выбранные fqdns включены.
Попробуй это:
# In stripdown.pp :
class stripdown {
service { "mysql":
enable => "false",
ensure => "stopped"
}
}
# In mysql.pp :
class mysql::server {
if defined(Service["mysql"]) {
Service["mysql"] {
enable => true,
ensure => running,
hasrestart => true,
hasstatus => true,
path => "/etc/init.d/mysql",
require => Package["mysql-server"],
}
} else {
service { "mysql":
enable => true,
ensure => running,
hasrestart => true,
hasstatus => true,
path => "/etc/init.d/mysql",
require => Package["mysql-server"],
}
}
}
# Then nodes in nodes.pp :
node basenode {
include stripdown
}
node myserver.local inherits basenode {
include mysql::server
}
Это, конечно, связано с предупреждением о том, что у вас уже есть пакет ["mysql-server"], определенный в другом месте, и он не будет работать, как написано без него, из-за вашего require
заявления.
Другая обнаруженная мной ошибка заключалась в том, что после параметров было слишком много пробелов. Параметры в строфе должны быть выровнены не более чем на 1 пробел больше, чем самое длинное имя параметра.
Дай этому уйти
# In stripdown.pp :
class stripdown {
service { "mysql":
enable => "false",
ensure => "stopped"
}
}
# In mysql.pp :
class mysql::server inherits stripdown {
Service["mysqld"] {
enable => true,
ensure => running,
hasrestart => true,
hasstatus => true,
path => "/etc/init.d/mysql",
require => Package["mysql-server"],
}
}
# Then nodes in nodes.pp :
node basenode {
include stripdown
}
node myserver.local inherits basenode {
include mysql::server
}
Одна вещь, на которую вы можете захотеть взглянуть, - это виртуальные ресурсы, чтобы обойти множественное определение ресурсов. Документацию по этой теме можно найти: http://reductivelabs.com/trac/puppet/wiki/VirtualResources
Конечно, другим способом было бы просто создать объекты узла для каждого хоста, который не запускает mysql, а затем загрузить туда разделенный класс.