[英]how to lazily define a class in a puppet manifest
I have a system which has different roles, AB C.我有一个具有不同角色的系统,AB C。 There is a class
daemon::conf
that defines the conf and concats the configs of all the classes arguments eg有一个 class
daemon::conf
定义 conf 并连接所有类 arguments 的配置,例如
class daemon::conf (
global_config = {}
a_config = {}
b_config = {}
c_config = {}
) {
concat::fragment {...}
}
So when I do this:所以当我这样做时:
class hg_mysystem::mycluster::hybrid {
include daemon::A
include daemon::B
}
I want to have:我希望有:
$ cat /etc/mysystem/config
[Global]
...
[A]
...
[B]
...
each daemon is defined as daemon::A, daemon::B, daemon::C
, but they call daemon::conf
with heir own parameters that are either defined in hiera on inside the .pp
manifest files.每个守护进程都被定义为
daemon::A, daemon::B, daemon::C
,但它们调用daemon::conf
时使用了自己的参数,这些参数要么在.pp
清单文件中的 hiera 中定义。 Now I need to create a node that has 2 or 3 roles (writing include daemon::A;include daemon::B
etc), but I get a problem with a class redefinition, because daemon::conf is defined in all AB and C.现在我需要创建一个具有 2 或 3 个角色的节点(编写
include daemon::A;include daemon::B
等),但我遇到了 class 重新定义的问题,因为 daemon::conf 在所有 AB 和C。
My first thought was to define the class on one node and add if defined(Class['daemon::conf']) {add argument to the defined class} else {class{'daemon::conf'...}}
but I don't know how to create a dynamic hiera variable from a manifest, or how to do a hiera style assignment from a manifest.我的第一个想法是在一个节点上定义 class 并添加
if defined(Class['daemon::conf']) {add argument to the defined class} else {class{'daemon::conf'...}}
但是我不知道如何从清单创建动态分层变量,或者如何从清单进行分层样式分配。 I was also searching on how to do a lazy init of the class with those virtual resources, but I don't understand how could that help, when realize doesn't override an argument but with realize you only do this realise Class['daemon::conf']
and not realise Class['daemon::conf'] {b_config={...}}
.我还在搜索如何使用这些虚拟资源对 class 进行惰性初始化,但我不明白这有什么帮助,当实现不会覆盖参数但实现时你只这样做
realise Class['daemon::conf']
并没有realise Class['daemon::conf'] {b_config={...}}
。 Is there any way I can restructure daemon::conf
with subclasses that notify another class that builds the conf based on the classes' data.有什么办法可以用子类重构
daemon::conf
来通知另一个 class,该 class 根据类的数据构建 conf。
Edit:编辑:
I followed the second approach and split daemon::conf
to daemon::conf
, daemon::conf::A
, daemon::conf::B
我遵循第二种方法并将
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,
}
}
}
Running puppet on 3 nodes in the same hostgroup I should get:在同一主机组中的 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=...
But instead I get multiple configs of role B as well of all 3 hosts.但相反,我得到了角色 B 的多个配置以及所有 3 个主机。 What mistake do I do and how to fix it?
我会犯什么错误以及如何解决? Thanks.
谢谢。 Is it the "<<| |>>" statement that should be altered?
是否应该更改“<<| |>>”语句?
Any solution needs to accommodate the fact that the values of all of a given class's parameters are determined the first time a declaration of that class is evaluated, whether the declaration is a resource-like one or an include-like one.任何解决方案都需要适应这样一个事实,即在第一次评估 class 的声明时确定给定类的所有参数的值,无论该声明是类似资源的声明还是类似包含的声明。 Multiple declarations are permitted only if all those evaluated after the first use one of the include-like forms, and this is among the reasons that resource-like class declarations should be avoided under most circumstances.
仅当所有在第一次评估后使用类似包含的 forms 之一时才允许多重声明,这也是在大多数情况下应避免类似资源的 class 声明的原因之一。
There are various ways to take those considerations into account.有多种方法可以考虑这些因素。 One would be to invert the logic: instead of having all each
daemon::X
class declare daemon::conf
, declare it once, centrally, and pass it a list of roles to configure.一种是颠倒逻辑:而不是让所有每个
daemon::X
class 声明daemon::conf
,集中声明一次,然后向其传递要配置的角色列表。 Let it then declare appropriate daemon::conf::X
classes based on the role list:然后让它根据角色列表声明适当的
daemon::conf::X
类:
class daemon::conf (
$global_config = {}
$roles = []
) {
concat { ... }
concat::fragment {...}
$roles.each { |$role|
contain "daemon::conf::${role}"
}
}
Another way would be to absolve the central daemon::conf
class from responsibility for declaring the per-role configuration at all.另一种方法是完全免除中央
daemon::conf
class 声明每个角色配置的责任。 This is possible because you're using Concat to build your config from fragments.这是可能的,因为您使用 Concat 从片段构建配置。 One of the key features of puppetlabs::concat is that
concat::fragment
s can be declared independently of each other and of the concat
declaring the file to which they contribute: puppetlabs::concat 的关键特性之一是
concat::fragment
可以相互独立地声明,也可以独立于声明它们贡献的文件的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
# ...
}
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.