在模块中,使用定义的资源在puppet3中有效,但在puppet5中失败

在模块中,使用定义的资源在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

所有内容都在manifests目录中

在manifest execute.pp中,我有:

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