puppet - 如何在木偶清单中懒惰地定义一个类
问题描述
我有一个具有不同角色的系统,AB C。有一个类daemon::conf
定义了 conf 并连接了所有类参数的配置,例如
class daemon::conf (
global_config = {}
a_config = {}
b_config = {}
c_config = {}
) {
concat::fragment {...}
}
所以当我这样做时:
class hg_mysystem::mycluster::hybrid {
include daemon::A
include daemon::B
}
我希望有:
$ cat /etc/mysystem/config
[Global]
...
[A]
...
[B]
...
每个守护进程都定义为daemon::A, daemon::B, daemon::C
,但它们使用继承人自己的参数调用,这些参数要么在清单文件daemon::conf
内的 hiera 中定义。.pp
现在我需要创建一个具有 2 或 3 个角色(写作include daemon::A;include daemon::B
等)的节点,但我遇到了类重新定义的问题,因为 daemon::conf 是在所有 AB 和 C 中定义的。
我的第一个想法是在一个节点上定义类并添加if defined(Class['daemon::conf']) {add argument to the defined class} else {class{'daemon::conf'...}}
,但我不知道如何从清单创建动态分层变量,或者如何从清单进行分层样式分配。我还在搜索如何使用这些虚拟资源对类进行惰性初始化,但我不明白这有什么帮助,当实现不覆盖参数但实现时你只这样做realise Class['daemon::conf']
而不是realise Class['daemon::conf'] {b_config={...}}
。有什么方法可以daemon::conf
用子类进行重组,通知另一个基于类的数据构建 conf 的类。
编辑:
我遵循第二种方法并拆分daemon::conf
为daemon::conf
, daemon::conf::A
,daemon::conf::B
class daemon::conf (...) {
concat { '/etc/daemon/conf':
owner => 'root',
group => 'root',
mode => '0664',
require => Package['daemon'],
}
Concat::Fragment <<| target == '/etc/daemon/config' |>>
concat::fragment { 'daemon.conf':
tag => "daemon.conf",
target => '/etc/daemon/config',
order => '01',
content => template('daemon/daemon.conf.erb'),
}
}
define daemon::conf::A (...) {
include ::daemon::conf
@@concat::fragment { "${::hostname}.daemon.conf":
tag => "daemon.conf",
target => '/etc/daemon/config',
order => '20',
content => template('daemon/daemon.conf-A.erb'),
}
}
class daemon::conf::B (...) {
include ::daemon::conf
concat::fragment { $::hostname:
tag => "daemon.conf",
target => '/etc/daemon/config',
order => '10',
content => template('daemon/daemon.conf-B.erb'),
}
}
class daemon::A (
$A_addr,
$port,
) {
include ::daemon::conf
daemon::conf::A { $::hostname:
addr => $A_addr,
port => $port,
}
}
class daemon::B (
$B_rack_loc,
) {
include ::daemon::conf
class {'::daemon::conf::B':
B_config => {
B_rack_location => $B_rack_loc,
}
}
}
在同一主机组中的 3 个节点上运行 puppet 我应该得到:
[user@hostname1: ~]$ cat /etc/daemon/config
[Global]
...
[B]
loc = row RO, rack RA, host hostname1
[A/hostname1 ip]
addr=...
port=...
[A/hostname2 ip]
addr=...
port=...
[A/hostname3 ip]
addr=...
port=...
但相反,我得到了角色 B 的多个配置以及所有 3 个主机。我会犯什么错误以及如何解决?谢谢。是否应该更改“<<| |>>”语句?
解决方案
任何解决方案都需要适应这样一个事实,即在第一次评估该类的声明时确定所有给定类的参数的值,无论该声明是类资源的还是类包含的。仅当所有在第一次评估后使用类包含形式之一时才允许多个声明,这也是在大多数情况下应避免使用类资源类声明的原因之一。
有多种方法可以考虑这些因素。一种是颠倒逻辑:不是让所有每个daemon::X
类都声明daemon::conf
,而是集中声明一次,然后传递给它一个要配置的角色列表。然后让它daemon::conf::X
根据角色列表声明适当的类:
class daemon::conf (
$global_config = {}
$roles = []
) {
concat { ... }
concat::fragment {...}
$roles.each { |$role|
contain "daemon::conf::${role}"
}
}
另一种方法是完全免除中心daemon::conf
类声明每个角色配置的责任。这是可能的,因为您使用 Concat 从片段构建配置。puppetlabs::concat 的关键特性之一是concat::fragment
s 可以相互独立地声明,也可以声明concat
它们贡献的文件:
class daemon::conf (
$global_config = {}
) {
concat { ... }
concat::fragment {...} # general configuration only
}
class daemon::a::conf (...) {
concat::fragment {...} # daemon A configs
}
class daemon::b::conf (...) {
concat::fragment {...} # daemon B configs
}
class daemon::a (...) {
include daemon::conf # (maybe)
contain daemon::a::conf
# ...
}
class daemon::b (...) {
include daemon::conf # (maybe)
contain daemon::b::conf
# ...
}
...
推荐阅读
- python - 在 python 3.7 上安装 pyqt4
- python - 如何在 Tensorflow DNNClassifier 估计器中打印训练进度?
- c - 对于 x86_64,Sum Array Rows 或 Sum Array Cols 哪个更快?
- python - Pip 不适用于 Python3.6(Ubuntu 14)
- git - git如何合并与master冲突的分支
- akka - 如何在 CQRS akka 持久性中的写入和读取之间共享 EntityModel
- context-free-grammar - 如何以某种形式显示每种上下文无关语言?
- python - 为什么我不能跳出while循环?
- java - 如何知道一个类是用 openjdk 还是 sunjdk 编译的?
- r - R Lattice - 堆积条形图的 log10 缩放问题