Puppet 4:如何将调用类变量添加到定义类型的范围中

Puppet 4:如何将调用类变量添加到定义类型的范围中,puppet,Puppet,在Puppet 3和更早的版本中,defines中的模板从其调用类继承了作用域,与本机定义的类型相同,因此,如果我有一个文件资源,其模板源由define创建,则无论哪个类调用define,该模板都可以使用调用类中设置的变量 在Puppet 4中,也使用Puppet 3.8 future parser进行了测试,但情况似乎不再如此,它导致的破坏在我的环境中甚至难以测量,我的环境依赖于这种行为编写了成千上万行代码。有没有办法把这个拿回来?研究之后,即使将定义转换为本机类型也无法解决问题,因为它们依赖

在Puppet 3和更早的版本中,defines中的模板从其调用类继承了作用域,与本机定义的类型相同,因此,如果我有一个文件资源,其模板源由define创建,则无论哪个类调用define,该模板都可以使用调用类中设置的变量

在Puppet 4中,也使用Puppet 3.8 future parser进行了测试,但情况似乎不再如此,它导致的破坏在我的环境中甚至难以测量,我的环境依赖于这种行为编写了成千上万行代码。有没有办法把这个拿回来?研究之后,即使将定义转换为本机类型也无法解决问题,因为它们依赖于通过自定义函数收集服务器端关于不同模块中可用模板的信息的能力,并且本机资源类型中的所有内容似乎都发生在客户机上

这是可修复的,还是我尝试等待傀儡5

编辑:不要在这里过于沉迷于“scope”这个词——我需要任何方法将所有类变量传递给一个define,并在那里解压它们,以便它们可用于模板,或者让本机类型查看puppetmaster上指定模块内的文件。只要有这样的结果,我就会接受任何奇怪的、模糊的消息传递选项,因为类不知道模板在哪里——只有define知道,因为它使用的是扫描服务器上文件系统的helper函数

编辑2:为了证明这一点符合Puppet 3.8.5中的预期,请使用以下内容:

模块/so1/manifests/autotemplate.pp:

# Minimal define example for debugging
define so1::autotemplate (
    $ensure = 'present',
    $module = $caller_module_name,
) {
    $realtemplate = "${module}${title}"

    file { $title :
        ensure  => $ensure,
        owner   => 'root', group => 'root', mode => '0600',
        content => template($realtemplate),
    }
}
在modules/so2/manifests/example.pp中:

# Example class calling so1::autotemplate
class so2::example (
    $value = 'is the expected value'
) {
    so1::autotemplate { '/tmp/qwerasdf': }
}
在模块/so2/模板/tmp/qwerasdf中:

Expected value: <%= @value %>
在3.8.5中。对于environment.conf中的parser=future和Puppet 4.x,尽管我专门在3.8.5 future parser环境中测试了这个示例,但这会导致创建包含以下内容的文件:

Expected value: is the expected value
Expected value:
编辑3:双字润色,精度高

在Puppet 3和更早的版本中,从调用类定义继承的作用域的方式与本机定义的类型相同,因此,如果我有一个文件资源,其中有一个由define创建的模板源,那么无论哪个类调用define,该模板都可以使用调用类中设置的变量

您所描述的是Puppet的旧动态范围。范围规则的变化是Puppet 3.0的主要变化之一;这在《木偶4》中并不新鲜。然而,在Puppet3中,模板仍然使用动态范围。这在Puppet 3.5中得到了修复,但只是前瞻性的——也就是说,当未来的解析器启用时。定义的类型本身在Puppet 3.0.0中经历了范围的更改,以及其他所有更改。范围的改变是一件大事,Puppet在用户刚开始使用时花了相当大的精力提醒他们,但现在已经没有什么大不了的了

它导致的破坏在我的环境中甚至很难测量,我的环境依赖于这种行为已经有上万行代码了

很抱歉你有这样的经历

有没有办法把这个拿回来

不。傀儡范围规则不能按您希望的方式工作。它们在模板中确实是这样工作的,但在Puppet 3中的大多数其他地方都不是这样,这与Puppet的文档是相反的,而且从来都不是有意的

这是可修复的,还是我尝试等待傀儡5

在模板中或Puppet 4中的其他地方无法获得动态变量作用域,我也没有理由认为Puppet 5中会有动态变量作用域

如果您需要一个模板来从特定类的作用域扩展主机变量,那么您可以通过在该类的作用域中计算模板来获得该模板。或者,ERB模板可以从特定的其他作用域获取变量。另一方面,如果要在定义类型的范围内扩展模板,则可以考虑将所需变量作为该类型的参数。


也许有其他方法来解决你的问题,但我需要更多的细节来提出任何其他建议。如果你选择在这里这样问,这将构成一个单独的问题。

同意这在Puppet 5中是否会再次出现是值得怀疑的。请参阅我的更新。不要过于沉迷于范围界定的机制——问题实际上是如何打包类中的每个变量,以便它们能够显示在定义的范围内。只要一个类可以在一行中说“处理这个文件”,并拥有定义工作的逻辑,我不在乎它是否是通过作用域、模糊函数、隐藏在服务器某处的自定义ruby代码实现的。另外,这段代码绝对可以在Puppet 3.8.5上运行,而不需要启用未来的解析器。一旦启用未来的解析器,或者在Puppet 4.8上,它就会立即中断。2@Zed,如果您认为我的意见不适用于您的公司
de,那么我倾向于认为您的代码所做的并没有很好地用这个问题来描述。你的编辑也把我引向了那个方向。如果您的问题确实与范围不同,那么我建议您在再次尝试提出问题时,在问题的后面加上一个字母,以帮助澄清您真正想知道的内容。@Zed,您是对的,当未来的解析器未启用时,Puppet 3的所有版本中都会出现错误行为。该修复仅在启用未来解析器时适用。我已更新了这方面的答复。在Puppet 3中,模板始终不应该使用动态作用域,而且在启用未来的解析器时,模板也不会使用动态作用域。这种通用的东西——帮助您为主要版本之间的更改做好准备——是未来解析器的目的之一。当范围不仅是您使用的词,而且是您正在讨论的概念的正确词时,我们不能避免关注范围。因此,您的编辑似乎试图将问题更改为提出与以前完全不同的问题。冒着听起来自私自利的风险,您不应该在收到答案后这样做。问题是标题中的问题-如何将所有调用类变量添加到定义类型的范围中。剩下的只是背景-在Puppet 3中,这是自动发生的,一直到3.8.5。我不需要它在Puppet 4中是自动的-我只需要它是可能的。标题中问题的答案仍然是我更新后写的。Puppet 3中定义的类型从未从using类的作用域中获取变量。模板确实存在,但这是一个bug,尽管只有在Puppet 4中修复了这个bug,并且在Puppet 3中启用了未来的解析器。您可以通过定义类型的参数将调用类中的数据传递给定义类型,模板可以通过其范围对象访问外部范围中的数据。没有理由认为这会在傀儡5中改变。