我正在尝试使用ERB模板在Puppet 5中构建文件。该ERB文件以常规方式使用类变量,但也可以通过插入另一个由Puppet管理的本地文件来构造。但是,我发现每当更新插入的文件时,Puppet都要运行两个来更新ERB生成的文件。我希望更新在一个木偶运行中进行。
通过示例最容易看到这一点:
# test/manifests/init.pp
class test {
# This file will be inserted inside the next file:
file { '/tmp/partial.txt':
source => 'puppet:///modules/test/partial.txt',
before => File['/tmp/layers.txt'],
}
$inserted_file = file('/tmp/partial.txt')
# This file uses a template and has the above file inserted into it.
file { '/tmp/layers.txt':
content => template('test/layers.txt.erb')
}
}
这是模板文件:
# test/templates/layers.txt.erb
This is a file
<%= @inserted_file %>
如果我对文件test/files/partial.txt
进行了更改,则需要两次运行Puppet,更改才能传播到/tmp/layers.txt
。出于操作原因,仅一次运行Puppet进行更新非常重要。
我尝试使用各种依赖项(before
,require
等),甚至使用Puppet阶段,但是我尝试的所有操作仍然需要运行两次Puppet。
虽然可以将exec
资源与sed
(或类似的东西)实现相同的结果,但我宁愿使用“纯” Puppet方法。这可能吗?
答案 0 :(得分:3)
我正在尝试使用ERB模板在Puppet 5中构建文件。该ERB文件以常规方式使用类变量,但也可以通过插入另一个由Puppet管理的本地文件来构造。
木偶戏分为三个主要阶段:
在清单建立阶段会完全评估人偶清单,包括评估所有模板和函数调用。此外,通过主服务器/代理程序设置,目录构建在主服务器上进行,因此在该阶段是“本地系统”。所有目标系统的修改都在目录应用阶段进行。
因此,您的
$inserted_file = file('/tmp/partial.txt')
在应用File[/tmp/partial.txt]
之前,在目录构建期间运行。由于您为file()
函数提供了绝对路径,因此它会尝试使用目录构建系统上已经存在的版本,甚至不一定要为清单构建机器。
对于我来说,目前尚不清楚为什么除了完整的模板文件之外,还想安装和管理部分结果,但是如果确实如此,那么在我看来,最好的方法是从相同的来源,而不是尝试从另一个来源获取。为此,您可以利用file
函数从(任何)模块的files/
目录中的文件中加载数据的功能,类似于File.source
可以做到的。
例如,
# test/manifests/init.pp
class test {
# Reads the contents of a module file:
$inserted_file = file('test/tmp/partial.txt')
file { '/tmp/partial.txt':
content => $inserted_file,
# resource relationship not necessary
}
file { '/tmp/layers.txt':
# interpolates $inserted_file:
content => template('test/layers.txt.erb')
}
}
还请注意,示例清单中的注释具有误导性。您提供的文件资源及其管理的文件内容都不会插值到模板中,除非偶然。内插的是评估模板的类的$inserted_file
变量的值。