在我的 Puppet 配置中,我想说“如果我声明了类 X,则在类 Y 之前应用其资源。”换句话说,我想声明一个顺序,但对于是否应用类 X 保持沉默。
如果我正确理解了“之前”的元参数,那么:
class X {
...
before => Class['Y'],
}
class Y {
...
}
node N {
include Y
}
node M {
include X
include Y
}
将在节点 M 和 N 上都包含 X 和 Y 的资源。相反,我想要分别表达“仅应用 Y”或“应用 X 和 Y,并在 Y 之前应用 X”。
更具体地说,我想做的是确保在 Puppet 应用包资源之前配置我的 Yum 存储库。我想从某些节点省略一些存储库。我希望我的包资源定义对相应的存储库保持简单;我不想让我的包资源定义充斥着对特定存储库的依赖。
我尝试使用运行阶段,但除了最简单的配置之外,它们似乎会导致依赖循环。例如,这将起作用:
stage { 'first': before => Stage['main'] }
class X {
...
before => Class['Y'],
}
class Y {
...
}
node N {
include Y
}
node M {
class { "X": stage => first }
include Y
}
但这不会:
stage { 'first': before => Stage['main'] }
class X {
...
class { "Z": stage => first } # to avoid Z "floating off"
before => Class['Y'],
}
class Y {
...
include Z
}
class Z { ... }
node N {
include Y
}
node M {
class { "X": stage => first }
include Y
}
在后者中,Puppet 认为存在依赖循环。我认为这是因为 Z 被声明并且其资源在两个不同的阶段进行管理。我可以在“第一”阶段简化我需要的类,以避免我在实践中看到的依赖循环问题,但 Puppet 文档却恐惧、疑虑和不确定因素关于运行阶段。
以下是一些让我不太喜欢 Run Stages 的具体配置。在开发虚拟机中,我通过“devrepo”在本地引导 Yum 服务器。
class yum::devrepo {
# Ensures httpd is running as a Yum server before anything else
# tries to install packages from it.
exec { 'httpd-for-yum':
command => '/sbin/service httpd restart',
require => Class['yum::server'],
}
yumrepo {
"devrepo":
require => [Exec['httpd-for-yum'],],
descr => "Local Dev YUM Repo",
baseurl => "http://localhost/repos/redhat/5/x86_64/",
gpgcheck => "0",
enabled => "1",
}
}
class yum::server {
include httpd
package { ['createrepo']:
ensure => present;
}
exec { 'update-repo-metadata':
require => [ Package['createrepo']],
cwd => '/var/www/html/yum',
command => '/usr/bin/createrepo --update -d repos/redhat/5/x86_64/',
creates => '/var/www/html/yum/repos/redhat/5/x86_64/repodata/repomd.xml',
}
file {'/etc/httpd/conf.d/yum.conf':
ensure => file,
mode => 0644,
source => "puppet:///modules/yum/yum_httpd.conf",
require => Package['httpd'],
notify => Service['httpd'],
}
}
我想在某些节点上包含我的生产 Yum 存储库,并在其他节点上包含开发存储库。
如果我将yum::server
和yum::devrepo
放在“第一”阶段,那么稍后其他类中的 httpd 声明会导致问题,因为其他类将 httpd 放在主阶段。
如果 Puppet 可以表达“如果我声明类 X,则在类 Y 之前应用其资源”,那么该怎么做?如果不能,我如何才能获得我想要的顺序,而没有依赖循环,也不包括我想要省略的 Yum 存储库资源?
答案1
不确定它是否会起作用,但也许您可以尝试在节点级别范围上定义依赖项。例如:
class X {
...
}
class Y {
...
}
node N {
include Y
}
node M {
Class['X'] -> Class['Y']
include X
include Y
}
答案2
看起来像golja 的回答可能会有效。这是我自己找到的模式。到目前为止,它似乎很有效。
class yum::reposareready {
# The sole and critical purpose of this class is to act as an
# intermediary between various repositories and the package
# resources. It lets us do things like:
# class yum::repofoo { ... }
# class applicationbar {
# package { 'bazfromtherightrepo': ..., require => yum::reposareready, }
# }
# node n {
# class { 'yum::repofoo': before => Class['yum::reposareready'] }
# }
# With this pattern:
# 1. The repository resource doesn't need to know about its ordering.
# 2. Nodes can mix in repository resources, including and excluding
# repositories as needed.
# 3. Classes that declare package resources need only require a
# generic "repos are ready" class rather than the knowing the
# specific repository from which to get a package.
# DO NOT DO THIS:
# class yum::repofoo { before => Class['yum::reposareready'] }
# class yum::repobar { before => Class['yum::reposareready'] }
#
# node n {
# include yum::repofoo
# }
#
# node m {
# include yum::repobar
# }
# The former scopes the ordering dependency to the node, whereas the
# latter does not. The latter would make Puppet apply yum::repofoo
# to both nodes n and m, whereas the former only applies
# yum::repofoo to node n.
}