我正试图强制创建要处理的文件的Puppet类之前另一个需要该文件存在才能正常运行的类。在Puppet文章Language: Containment of resources之后,我正在使用contain
。
我的代码不起作用,我不明白为什么。它给出了这个错误:
Error: Evaluation Error: Error while evaluating a Function Call, Failed to parse template testing/def.erb:
Filepath: /root/local/testing/templates/def.erb
Line: 1
Detail: No such file or directory @ rb_sysopen - /tmp/abc
at /root/local/test2.pp:16:16 on node example.com
这里是代码(向下细分):
### test2.pp
class klass1 {
file { '/tmp/abc':
content => 'xxx',
}
}
# Stage 0 creates the file /tmp/abc.
class stage0 {
contain klass1
}
# Stage 1 uses the contents of /tmp/abc to create the
# file /tmp/def.
class stage1 {
file { '/tmp/def':
content => template('testing/def.erb'),
}
}
# Try to force stage0 to be loaded before stage1.
include stage0
class { 'stage1':
require => Class['stage0']
}
### testing/templates/def.erb
Contents: <%= File.read("/tmp/abc") %>
我正在使用Puppet 5.3.3。
这里的问题与遏制无关,但与编译时对文件/tmp/abc
的依赖性有关。
您的模板def.erb
尝试在编译时从此文件读取,但是在编译时不存在,或者至少在第一次运行时不存在。
如果您将def.erb
更改为此:
<% contents = begin
File.read('/tmp/abc')
rescue
''
end -%>
Contents: <%= contents %>
您不会避免编译问题,但是仍然会遇到排序问题,因此您需要应用两次才能使文件按预期收敛。
但是,更好的解决方案可能是将Puppet本身中文件/tmp/abc
的内容定义为数据或变量,然后将该变量传递给模板函数,从而消除对从磁盘上的文件读取的依赖总共。
这有效,但是您希望不使用顶级作用域变量来做到这一点,就像我那样:]
$content = 'xxx'
class klass1 {
file { '/tmp/abc':
content => $::content,
}
}
class stage0 {
contain klass1
}
class stage1 {
file { '/tmp/def':
content => "Contents: ${::content}",
}
}
include stage0
class { 'stage1':
require => Class['stage0']
}