muru muru - 6 months ago 65
Ruby Question

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

I'm trying to create a Puppet ERB template for a file, with some default content and an optional tail. The optional part is to be determined by the hostname/FQDN of the Ppuppet client, and need not exist. Currently, I have this:

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


mod
is the module name. I had to create an empty
mod/files/empty
so that
scope.function_file
doesn't fail if it doesn't find a file for the hostname or FQDN. I think this is ugly.

I have tried variations of:

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


With files placed in the
mod/templates
directory instead of
mod/files
, but I usually got an error about missing files. Using
scope.function_template
with the files in
mod/templates
also has the same problem as
scope.function_file
- the action fails if files are missing.

How can I do this, without having to create placeholder files (like
empty
here)?

Answer

Instead of using scope.function_file in the erb template itself, you should consider using it in your manifest. The below should suffice and should stop you from creating the "empty" file.

$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
}

Then in your template you can just use <%= @real_content %>

If that is the only content of the file then you can skip using a template altogether and just use the file resource as follows:

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

By using /dev/null you will get empty content if mod/${::hostname}, or mod/${::fqdn} do not exist. Or you can stick with your route and just add /dev/null to your scope.function_file calls.