如何选择性地将文件包含在 Puppet ERB 模板中?

How do I optionally include a file in a Puppet ERB template?

我正在尝试为文件创建一个 Puppet ERB 模板,其中包含一些默认内容和一个可选尾部。可选部分由Ppuppet客户端的hostname/FQDN决定,可以不存在。目前,我有这个:

<%= scope.function_file(['mod/default']) %>
<%= scope.function_file(["mod/" + @hostname, "mod/" + @fqdn, 'mod/empty']) %>

mod 是模块名称。我必须创建一个空的 mod/files/empty,以便 scope.function_file 在找不到主机名或 FQDN 的文件时不会失败。我认为这很丑陋。

我试过以下变体:

<%= File.read('default') %>
<% if File.file?(@hostname) %>
<%= File.read(@hostname) %>
<$ elsif File.file?(@fqdn) %>
<%= File.read(@fqdn) %>
<& end %>

将文件放在 mod/templates 目录而不是 mod/files 目录中,但我通常会收到有关丢失文件的错误消息。对 mod/templates 中的文件使用 scope.function_template 也有与 scope.function_file 相同的问题 - 如果文件丢失,操作将失败。

如何才能做到这一点,而不必创建占位符文件(如此处的 empty)?

与其在 erb 模板本身中使用 scope.function_file,不如考虑在清单中使用它。下面应该足够了,应该阻止你创建“empty”文件。

$default_content = file('mod/default')
$tail = file(
  "mod/${::hostname}",
  "mod/${::fqdn}",
  "/dev/null"
)

if $tail != "" {
  $real_content = "${default_content}\n${tail}"
} else {
  $real_content = $default_content
}

然后在你的 template 中你可以使用 <%= @real_content %>

如果这是文件的唯一内容,那么您可以完全跳过使用模板,只需按如下方式使用文件资源:

file { '/path/to/file':
  ensure  => file,
  content => $real_content
}

通过使用 /dev/null 如果 mod/${::hostname}mod/${::fqdn} 不存在,您将获得空内容。或者你可以坚持你的路线,只需将 /dev/null 添加到你的 scope.function_file 调用中。