木偶:如何覆盖/重新定义外部子类(详细的用例和示例)

我试图说明的用例是什么时候声明某个项目(eq mysqld服务)与默认configuration,可以包含在每个节点(class stripdown在这个例子中,basenode),仍然能够覆盖这个相同的项目一些特定的类(例如mysql :: server),被特定的节点(如myserver.local)

我用下面的例子说明了这个用例,我想在所有节点上禁用mysql服务,但是在特定的节点上激活它。 但是当然,Puppetparsing失败,因为Service [mysql]包含两次。 当然,mysql :: server类没有任何关系,可以作为剥离类的子类

有没有办法来覆盖服务[“MySQL”],或将其标记为主要的,或者其他? 我正在考虑虚拟物品和实现function,但它只允许多次应用物品,而不是重新定义或覆盖。

# 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 } 

去这个:

 # 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 } 

这当然伴随着你已经在其他地方定义了Package [“mysql-server”]的警告,因为你的require语句,它会被写入没有它。

我发现的另一个错误是,在选项之后你有太多的空间。 在节中的选项必须alignment不超过1个空间大于最长的选项名称。

每当你发现自己说“我希望这个组件在一个节点上运行一种方式,而在另一个节点上运行的方式不同”时,你可能需要查看由variables驱动的定义,无论是通过类定义中的条件还是replace在模板中。

不幸的是,你的例子显示了你试图使用inheritance,这在puppet中是非常糟糕的,并且会在这里引起你很多的悲痛,因为它中断的一件事是节点中的variables重定义。

更新:旧的答案细节已经过时

2.7中所做的是确保一个类所使用的所有variables根本不是全局variables,而是确定具有合理默认值的参数。 你仍然不想使用内build在Puppet中的inheritance,但是你现在可以直接从节点定义中覆盖特定的variables,而且你甚至可以通过一个类获取variables,然后把它们传递给调用另一个类。 例如,您将在您的节点定义中:

 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的漂亮新function,它允许您将默认值卸载到单独的数据结构中,如果您有Puppet 3.2,则应该查看它。 不幸的是,许多Linux发行版仍然以2.6或2.7的版本发布,所以这可能还不是您的select。

以前的答案细节保存在下面

我通常处理这样的事情的方式是创build一个“default_parameters.pp”文件,其中没有任何内容,但是对于一长串variables默认赋值,所以在这种情况下,它将包含一行,如$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是否为true,如果是,请在enable使用select器并ensure

如果节点myserver.localinheritance任何东西,这会立即中断,因为这会在inheritance时lockingvariables的值,并且节点定义内部的进一步更改将不起作用,否则我会在整个地方使用此技术以获得单个组件行为不同而不产生多个类。

如果绝对必须inheritance,但启用了mysql的机器列表很小,则可以采用替代路由:不是在节点定义中设置variables,而是从$fqdn构buildselect器,默认情况下为禁用,并selectfqdns启用。

给一下去

 # 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/VirtualResourcesfind

当然,另一种方法是简单地为每个不运行mysql的主机创build节点对象,然后在那里加载剥离的类。