how to use file resource with source file name unknown

42 views
Skip to first unread message

Andreas Dvorak

unread,
Jul 7, 2015, 6:22:45 AM7/7/15
to puppet...@googlegroups.com
Hello,

I have a module to copy files /etc/hostname.* in Solaris. But the interface name can be any.

e.g.
networking/file/vm6742/hostname.e1000g0
networking/file/vm6742/hostname.e1000g1

I do not want to user file with recurse because the files in /etc have different permissions.

Is it possible to get a file list of the source to use that in the file resource or is there an other solution?


Best regards
Andreas

jcbollinger

unread,
Jul 7, 2015, 9:24:55 AM7/7/15
to puppet...@googlegroups.com
You can use Puppet's generate() function to get a listing of the files on the master, and manipulate the result into on File resource for each of the source files.  Probably the built-in split() function will be useful for that, and perhaps also regsubst().  Alternatively, you could package some or all of that into a custom function.

You might also find it to your advantage to wrap up the per-file details in a defined type, which you can instantiate with an array title derived from your file list:

mymodule::hostname_file { $filenames: }

Or I guess the newfangled way to go about it would involve the each() function (Puppet 4 or future parser only).


John

Christopher Wood

unread,
Jul 7, 2015, 9:54:54 AM7/7/15
to puppet...@googlegroups.com
In your place I would probably use a fact to get the names, see inline. Fair warning that I haven't tested any of this. It may even damage your server as written!

On Tue, Jul 07, 2015 at 03:22:44AM -0700, Andreas Dvorak wrote:
> Hello,
>
> I have a module to copy files /etc/hostname.* in Solaris. But the
> interface name can be any.
>
> e.g.
> networking/file/vm6742/hostname.e1000g0
> networking/file/vm6742/hostname.e1000g1

I am assuming that "vm6742" is the hostname. Also that you have the stringify_facts config option set to false. Also that you find it acceptable for an agent run to partially fail if the source file does not exist. If not, use a template, that way you will find out via catalog compilation failure.

https://docs.puppetlabs.com/puppet/latest/reference/lang_facts_and_builtin_vars.html#handling-boolean-facts-in-older-puppet-versions

A custom fact (pardon the cheap ruby, note how it's a hash of hashes since the define later needs hashes):

array = Dir.glob('/etc/hostname.*')
hash = {}
array.each do |item|
hash[item] = {}
end
Facter.add('hostnamefiles') do
setcode do
hash
end
end

https://docs.puppetlabs.com/facter/2.4/custom_facts.html

Then a define, wherein we extract the source based on the resource title and hostname fact and manage the file resource:

define networking::hnf {
$sourcefile = inline_template('<%= File.basename(@title) %>')
$source = "puppet:///modules/networking/${::hostname}/${sourcefile}"
file { $title:
source => $source,
}
}

https://docs.puppetlabs.com/puppet/latest/reference/lang_defined_types.html

And in networking/manifests/init.pp something to create the resources (or using each iteration for puppet4):

create_resources('networking::hnf', $::hostnamefiles)

Two big caveats to this approach:

It's more difficult to troubleshoot create_resources than plain listed-in-manifests resources.

This is verging on an anti-pattern, managing based on what's on the host. Better to affirmatively control all aspects of your host. Know what interfaces they get before you install the OS.

Minor caveat:

You will need every single hostname.whatever file listed in your module for the approach above. If you needed the hostname.whatever file to only contain the hostname of the VM, without per-interface customization, you could just do that and skip maintaining all the files:

define networking::hnf {
file { $title:
content => "${::hostname}\n",
}
}

(Not sure about that \n, don't have a Solaris host to check.)

> I do not want to user file with recurse because the files in /etc have
> different permissions.
>
> Is it possible to get a file list of the source to use that in the file
> resource or is there an other solution?
>
> Best regards
> Andreas
>
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [1]puppet-users...@googlegroups.com.
> To view this discussion on the web visit
> [2]https://groups.google.com/d/msgid/puppet-users/1b0199b1-7e9b-47ff-a08a-10ef8ae6c5bc%40googlegroups.com.
> For more options, visit [3]https://groups.google.com/d/optout.
>
> References
>
> Visible links
> 1. mailto:puppet-users...@googlegroups.com
> 2. https://groups.google.com/d/msgid/puppet-users/1b0199b1-7e9b-47ff-a08a-10ef8ae6c5bc%40googlegroups.com?utm_medium=email&utm_source=footer
> 3. https://groups.google.com/d/optout

Andreas Dvorak

unread,
Jul 8, 2015, 8:47:32 AM7/8/15
to puppet...@googlegroups.com, christop...@pobox.com
Hi,

thank for the help.
I have solved the issue with the generate funktion.
      $redhatfiles = generate("/bin/bash","-c","/bin/ls /data/git/${zweig}/modules/networking/files/${::hostname}/network-scripts 2>/dev/null | tr -t '\n' ':'")
      $redhat_interfaces = split($redhatfiles, ":")
      redhat::create_interface { $redhat_interfaces: }


Unfortunately spaces are not allowed in the generate funktion. But I have found a solution.
https://projects.puppetlabs.com/issues/5481

Regards
Andreas

jcbollinger

unread,
Jul 8, 2015, 9:06:07 AM7/8/15
to puppet...@googlegroups.com


On Tuesday, July 7, 2015 at 8:54:54 AM UTC-5, Christopher Wood wrote:
In your place I would probably use a fact to get the names, see inline. Fair warning that I haven't tested any of this. It may even damage your server as written!

I read the OP as saying that the list of files was dictated by the catalog compiler, not the client.  It makes little difference if those happen to be the same machine (i.e. with 'puppet apply'), but in a master / agent setup the difference is profound.  Facts are evaluated on the client, so if indeed the file list is governed by a Puppet master then facts cannot do the job in any reasonable way.


John

Reply all
Reply to author
Forward
0 new messages