Composing a text file with Puppet

3,003 views
Skip to first unread message

M C

unread,
Aug 30, 2011, 10:15:01 AM8/30/11
to puppet...@googlegroups.com
Hi,

is it possible to push a file (with "source" or "content") and then add lines without having Puppet to regenerate it every time it runs?
And, how can I add, remove or alter text lines without keeping old contents? Note: i want resources to be executed only if something actually changes.

Please help, thanks.

Matteo

Daniel Maher

unread,
Aug 30, 2011, 1:06:33 PM8/30/11
to puppet...@googlegroups.com

Hello,

I'm not entirely sure if I understand your use-case properly; however,
for all instances of text-file manipulation, I have found the "concat"
module to be _extremely_ useful.

https://github.com/ripienaar/puppet-concat


--
Daniel Maher
� makin' plans now to live on Mars 'cuz I got Earth on lock. �

jcbollinger

unread,
Aug 31, 2011, 9:57:40 AM8/31/11
to Puppet Users


On Aug 30, 9:15 am, M C <mcsof...@gmail.com> wrote:
> Hi,
>
> is it possible to push a file (with "source" or "content") and then add
> lines without having Puppet to regenerate it every time it runs?
> And, how can I add, remove or alter text lines without keeping old contents?


As I understand you, you want Puppet to provide a default version of
the file in the event that it does not exist at all, but otherwise to
leave it completely alone. That runs against the Puppet grain: it
would be better to completely manage the file content, updating the
node's manifests as appropriate when you want the file's contents to
change.

Nevertheless, you can do this with Puppet, though it requires a bit
more work (note: that's a sign that you're trying to work against the
tool). You can hack it together as an Exec resource, and that may be
the most reliable way to go, but I'm going to show you how you can
build this around a File resource. Using a File may be advantageous
when the default file contents are lengthy or sensitive, but mainly
Files just aren't Execs. The best way might be to derive a custom
type from File that provides the behavior you want, but I'm not going
there today.

The first thing to understand is that File's 'source' and 'content'
properties always specify the exact file contents. If we're going to
use them then we have to put in some kind of conditional logic. For
your specific request, that conditional logic needs to be based on the
presence or absence of the target file. Conditional logic is
evaluated on the master, so the master needs to know during catalog
compilation whether the target file already exists, and that requires
a custom fact (see http://docs.puppetlabs.com/guides/custom_facts.html).
The Ruby code for this particular fact can probably be something
similar to this:

Facter.add('myconf_exists') do
setcode do
File.exists?('/etc/myconf') ? 'true' : 'false'
end
end


Your manifest using this fact might then contain something like this:

file { '/etc/myconf':
ensure => file,
content => $::myconf_exists ? {
'true' => undef,
default => '... contents ...'
}
# other properties ...
}

Note that when formulated as above, any properties other than content
(e.g. owner, permissions) will be ensured on every run. If you want
more than one property to be conditional, then you would probably be
better off wrapping the while resource declaration in an 'if'
construct.

Note also that there is a hidden potential gotcha here: the presence
of the file is determined when Puppet requests the catalog, not when
it applies it. If the file is created in between then Puppet will
replace it. Furthermore, if Puppet ever cannot retrieve a fresh
catalog from the master, then its cached one may be stale with respect
to whether the target file actually exists; that potentially extends
the window in which file creation might be overlooked.


> Note: i want resources to be executed only if something actually changes.


Depending on how you look at it, that's either always or never what
Puppet does. That is, Puppet always checks each declared resource to
determine whether its actual state matches its declared target state,
so if you're saying you don't want that then Puppet is not the tool
for you. On the other hand, Puppet only modifies resources that it
finds out of sync with their declarations, and I think that's what
you're asking for.


John

Brian Gallew

unread,
Aug 31, 2011, 11:52:50 AM8/31/11
to puppet...@googlegroups.com

On Aug 31, 2011, at 6:57 AM, jcbollinger wrote:

>
>
> On Aug 30, 9:15 am, M C <mcsof...@gmail.com> wrote:
>> Hi,
>>
>> is it possible to push a file (with "source" or "content") and then add
>> lines without having Puppet to regenerate it every time it runs?
>> And, how can I add, remove or alter text lines without keeping old contents?
>
>
> As I understand you, you want Puppet to provide a default version of
> the file in the event that it does not exist at all, but otherwise to
> leave it completely alone. That runs against the Puppet grain: it
> would be better to completely manage the file content, updating the
> node's manifests as appropriate when you want the file's contents to
> change.

Call me crazy, but isn't this just a matter of adding "replace => false" to the file resource? If it doesn't exist, Puppet will create it according to the manifest. Once in place, Puppet will leave it alone unless it vanishes, at which point it will be re-created.

jcbollinger

unread,
Sep 1, 2011, 9:29:04 AM9/1/11
to Puppet Users


On Aug 31, 10:52 am, Brian Gallew <g...@gallew.org> wrote:

> Call me crazy, but isn't this just a matter of adding "replace => false" to the file resource?  If it doesn't exist, Puppet will create it according to the manifest.  Once in place, Puppet will leave it alone unless it vanishes, at which point it will be re-created.


Um. Err. Coffee.

I mean, yeah, but where's the fun in that?


John

M C

unread,
Sep 2, 2011, 11:44:46 AM9/2/11
to puppet...@googlegroups.com
Hi,

thank you verymuch for the explanations.
I will first try with a combination of "replace => false" and custom "Line" resource to see if I can easily concat and update my configuration file content.

Matteo

2011/9/1 jcbollinger <John.Bo...@stjude.org>

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To post to this group, send email to puppet...@googlegroups.com.
To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.


Reply all
Reply to author
Forward
0 new messages