redalert.commander@gmail.com
2013-Aug-14 13:23 UTC
[Puppet Users] Replace file based on content
Hi, I wanted to know if there is an easy way to replace a file in puppet (using the file directive) but only when a certain string exists. My use case: I have a package that installs a config file, I want to replace that file with puppet, but I in normal operation the application may also write to that file. So a simple replace => true is not sufficient. I tried with something like this: define configfile ($source) { $grepcommand = ''/bin/grep --quiet "string to check"'' exec { "check_${name}": command => "/bin/true", onlyif => "${grepcommand} ${name}", } file { "$name": ensure => "present", replace => "true", mode => "0644", owner => ''user'', group => ''user'', source => $source, require => Exec["check_${name}"] } } configfile {"/etc/software/config.xml": source => "puppet:///modules/software/config.xml" } I can''t get that to work properly, the file is always getting replaced. Regards, Steven -- 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 puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users. For more options, visit https://groups.google.com/groups/opt_out.
On Wednesday, August 14, 2013 8:23:47 AM UTC-5, redalert....@gmail.com wrote:> > Hi, > > I wanted to know if there is an easy way to replace a file in puppet > (using the file directive) but only when a certain string exists. > > My use case: > I have a package that installs a config file, I want to replace that file > with puppet, but I in normal operation the application may also write to > that file. > So a simple replace => true is not sufficient. > > I tried with something like this: > define configfile ($source) { > > $grepcommand = ''/bin/grep --quiet "string to check"'' > exec { "check_${name}": > command => "/bin/true", > onlyif => "${grepcommand} ${name}", > } > > file { "$name": > ensure => "present", > replace => "true", > mode => "0644", > owner => ''user'', > group => ''user'', > source => $source, > require => Exec["check_${name}"] > } > > } > > configfile {"/etc/software/config.xml": > source => "puppet:///modules/software/config.xml" > } > > I can''t get that to work properly, the file is always getting replaced. > >I think it would work if you rewrote your Exec like so: exec { "check_${name}": command => ''grep -q <disqualifying-pattern> ${name}'' } The point is that for the Exec to condition application of the File, its application must *fail* when you want to avoid applying the File. When an Exec''s ''onlyif'' or ''unless'' parameter causes the ''command'' to be skipped, that counts as the Exec succeeding. It should be viewed as finding the Exec resource already in sync with the target node, so that the command does not need to be run. Nevertheless, this is all the wrong approach. Better alternatives include - create per-file-of-interest custom facts to communicate the grep results to Puppet, and use them in Puppet conditional statements to control whether the target File resources are declared at all. - if really all that matters is that the file contain a particular line, then manage just that line. PuppetLabs'' add-in "stdlib" module provides a File_line resource serving exactly that purpose. - if the objective is to install a default file, but only if the target does not already exist, then set replace => false on your File resource - flip around the File and Exec: sync the config to a temp file, and use an Exec to conditionally update the true target with the temp version. The main advantage here is that Puppet will not report failed resources in the course of normal operations. John -- 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 puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users. For more options, visit https://groups.google.com/groups/opt_out.
redalert.commander@gmail.com
2013-Aug-16 08:16 UTC
[Puppet Users] Re: Replace file based on content
Hi John, Thanks for having a look. I already had the idea that there should be a better way, so I included the use case. I used stdlib to solve my issue, I''m still relatively new to Puppet, so I didn''t know about this. Below your suggested options again with a little comment. Thanks again for the solution. custom-facts: I have no idea how to do that, but will look into it once I come across something else that might need that. stdlib: it took a little figuring out and reading the documentation, but this does exactly what I need. In this case I need 2 File_line directives as there are 2 line to manage, but it definitely works. file with replace = false: as I explained in my first post, this doesn''t work because the file is also included in the rpm package. flip around the file and exec: seems a bit complicated for what I''m trying to achieve, haven''t tried this. Best regards, Steven -- 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 puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users. For more options, visit https://groups.google.com/groups/opt_out.