简体   繁体   English

如何在木偶清单中懒惰地定义 class

[英]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::confdaemon::conf::Adaemon::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM