我对 Puppet 还比较陌生,但到目前为止我认为它是一个非常强大的工具。
举一个简单的例子,假设我有一个模块“ntp”,在模块ntp中我有三个类:
- class ntp - 从发行版软件包提供商处安装软件包,设置启动服务的信息等
- class ntp::client - 创建配置文件以使用我的本地 ntp 服务器,停止 ntp,强制执行 ntpupdate,并启动 ntp 服务
- class ntp::server - 创建配置文件以创建我的本地 ntp 服务器,停止 ntp,强制执行 ntpupdate(在初始配置时),并启动 ntp 服务
我不确定使 ntp 类中的服务定义可供 ntp::client 和 ntp::server 类使用的正确方法。
我使用事实来区分不同的操作系统以及软件包和服务名称。为了避免混乱,我省略了这些内容。
而不是在每个类中都有如下内容:
service{ 'ntp':
name => $ntpservice,
ensure => running,
subscribe => File['ntpconf'],
}
package{ 'ntp':
(etc - I think the point has been communicated)
我认为在 ntp 类中定义服务并从 ntp::client 和 ntp::server 类中调用 ntp 类中的该服务会更简洁、更简单。基本上,由于存在多个平台(基于 RHEL 和 Debian),因此软件包和服务的定义可能略有不同。
我希望 ntp::client 和 ntp::server 中拥有如下内容:
file{ 'ntpconf':
source => 'puppet:///modules/ntp/ntp.conf',
owner => 'root',
group => 'root',
mode => '0644',
notify => Service[**CALL TO class ntp SERVICE**],
require => Package[**CALL TO class ntp PACKAGE**],
}
我似乎记得以前在文档中看到过可以这样做,但我似乎再也找不到了。我收藏了所有的东西,却没有收藏这个!
非常感谢任何建议。提前致谢。
编辑此外,我使用事实和大小写来按操作系统设置软件包名称和服务名称的参数。我没有在示例代码中包含该信息,因为它运行良好,而且看起来有点不必要的混乱。
答案1
我就是这么做的。使用 ENC 或 Hiera 根据服务器名称或角色进行查找并决定是否包含 ntp::server 或其他内容可能会更简洁一些,但这相当简单,不需要额外的软件或设置。
请记住,Puppet 的继承模型并不正常。除非您的使用非常简单,否则您将遇到麻烦。我不会在任何模块中继承超过一次。
class ntp {
include ntp::install, ntp::config, ntp::sevice
Class['ntp::install'] -> Class['ntp::config'] ~> Class['ntp::service']
}
class ntp::config {
file { 'ntp.conf':
ensure => present,
content => template('ntp/ntp.erb'),
}
}
class ntp::config::server inherits ntp::config {
File['ntp.conf'] { content => template('ntp/ntp.conf.server.erb'), }
}
node basenode {
include ntp
}
node /^ntp\d+/ inherits basenode {
include ntp::config::server
}
答案2
我偶然发现了 Puppet 自己认为正确的解决方案。
我读到过应该避免继承,但有一个例外,即模块内的类 - 根据在以下位置找到的文档Puppet 风格指南——类继承
由于这些人编写了软件,我认为这是最好的解决方案。
基本上,如果我在 ntp 类中有上述包和服务定义,那么当我定义 ntp::server 类时,我会执行以下操作:
class ntp::server inherits ntp {
这将提供我所需要的并解决问题。
谢谢大家!