在模块中,使用定义的资源在puppet3中有效,但在puppet5中失败
所有内容都在manifests目录中 在manifest execute.pp中,我有:在模块中,使用定义的资源在puppet3中有效,但在puppet5中失败,puppet,Puppet,所有内容都在manifests目录中 在manifest execute.pp中,我有: define execute ( String $command = "echo", String $workdirectory = "/tmp", String $runas = "www", Boolean $failonerror = true ) { # Resources require stdlib
define execute (
String $command = "echo",
String $workdirectory = "/tmp",
String $runas = "www",
Boolean $failonerror = true
) {
# Resources
require stdlib
etc ...
使用它的代码:
....
if defined(Execute["$titlePreviousExecRes"]) {
....
puppet5的错误是
错误:评估错误:评估资源语句时出错,评估错误:未找到资源类型:在执行
您定义的类型的清单在物理上位于模块的清单中(您尚未公开其名称),但该类型不是模块的一部分,因为其名称不在模块的命名空间中。因此,木偶的加载器将无法找到它。您的代码对于Puppet 3来说也是有缺陷的,但它似乎得益于一个宽松特性的融合 例如,如果您定义的类型应属于名为“mymodule”的模块,则应在该命名空间中显式声明:
define mymodule::execute ( ...
if defined(Mymodule::Execute["$titlePreviousExecRes"]) {
还应通过该名称空间引用:
define mymodule::execute ( ...
if defined(Mymodule::Execute["$titlePreviousExecRes"]) {
。通过将定义的类型放置在正确的命名空间中,并通过其完全限定名引用它来修复问题
至于为什么它似乎在Puppet 3中起作用,Puppet语言的第3版假设对未显式锚定到顶级作用域的类和类型的引用(例如,
::execute
)可能与引用出现的类或类型的命名空间有关(甚至与其他一些类或类型有关)。在您的情况下,自动加载程序首先会猜测您对名为Execute
的类型的引用可能是指::mymodule::Execute
。看到清单mymodule/manifests/execute.pp
存在,它将对该文件求值,从而获得类型::execute
——而不是它所寻找的::mymodule::execute
的定义
由于没有找到要查找的类型,自动加载程序将在其他名称空间中搜索,直到最终尝试top scope。然而,当它到达那里时,它会发现它已经拥有它从模块中的清单中获得的顶级范围定义,因此加载程序将成功,前提是该定义放错了位置。但这只适用于同一模块内的引用,并且存在严重的冲突风险
Puppet 5的autoloader在定位类和定义的类型定义时仍然表现出一些回退行为,但Puppet不再识别相对类和定义的类型名。因此,当尝试解析对类型execute
的引用时,自动加载程序从不考虑评估mymodule/manifests/execute.pp
,因为它希望在那里找到::mymodule::execute
,而不是它正在寻找的类型,::execute
因此,不,您的定义从未定位或加载。这是一个特性,不是bug