之前在 ServerFault 中,我们展示了如何测试资源是否已定义: Puppet:测试资源是否已定义,或创建它
if defined(File["/tmp/foo"]) {
alert("/tmp/foo is defined")
} else {
alert("/tmp/foo is not defined")
}
我想在通过收集器实现虚拟资源之前测试它是否已定义或存在,但它似乎不适用于相同的语法。
create_resource('@package',hiera_hash('packages',{}),{})
if !defined(@Package['foo']) {
alert('Hiera screwed up, critical virtual package is missing')
}
# Realize the critical packages
Package<| groups == critical |>
这让我:
Error: Could not parse for environment production: Virtual (@) can only be applied to a Resource Expression at test.pp..
原因是我想要通过 create_resources 和 collectors 来实现,并且在测试时,如果它实际上没有创建一些关键的虚拟资源,则会引发错误。
编辑于 2014/11/12 19:07 UTC 其中一个答案建议这样做,但是没有用,由于答案评论框太小,因此将其粘贴到这里。
class base::test1 {
@package { 'cookietool':
ensure => 'present',
}
realize(Package['cookietool'])
}
base::test2
具有相同的内容。
node testbox {
include base::test1
include base::test2
}
失败并出现以下错误:
Error: Failed to compile catalog for node testbox: Evaluation Error: Error while evaluating a Resource Statement, Duplicate declaration: Package[cookietool] is already declared in file /var/lib/puppet/checkouts/environments/production/modules/base/manifests/test1.pp:2; cannot redeclare at /var/lib/puppet/checkouts/environments/production/modules/base/manifests/test2.pp:2 at /var/lib/puppet/checkouts/environments/production/modules/base/manifests/test2.pp:2:3 on node testbox
答案1
根据定义,虚拟资源只有经过 才被称为“定义” realized
。
与标准资源一样,您只能声明虚拟资源一次,但它们可以realized
多次出现——这是它们被使用的主要原因之一。
例子
模块/包/init.pp
class packages {
@package { 'git':
ensure => present,
}
}
模块/git/init.pp
class git {
realize Package['git']
}
模块/mymodule/init.pp
class mymodule {
realize Package['git']
}
清单/站点.pp
node 'mynode' {
include packages
include git
include mymodule
}
这将编译并确保git
包已安装。
答案2
只需声明依赖于您正在实现的资源的资源。
notify { 'important resources are declared':
loglevel => debug,
require => [
Package['foo'],
...
],
}
Package[foo]
如果没有实现,目录将会失败。
无论如何,使用定义的函数都是极其糟糕的实践
不要在这个或几乎任何其他场景中使用它。它的评估顺序依赖于编译器端,并且其结果不可靠。