parsedfile providers: reacting to target changes.

2 views
Skip to first unread message

Udo Waechter

unread,
Jun 21, 2009, 4:20:43 PM6/21/09
to Puppet Developers
Hello,
following my questions about the nfs_export provider (see: http://alturl.com/mtdj
for the thread) one last question remains. Please see: http://pastie.org/518507
for the provider and http://pastie.org/518506 for the type.

I would like to refresh 'mountd' after /etc/exports has been updated.
Unfortunately I can not get it to work. My thought was to implement a
"flush" method in my provider:

def flush
cmd=nil
if Facter.value(:kernel) == "Linux"
cmd = "/usr/sbin/exportfs -ra"
elsif Facter.value(:kernel) == "FreeBSD"
cmd = "/etc/rc.d/mountd reload"
end
debug "Running refresh of mountd with: \"#{cmd}\""
out = %x{#{cmd}}
unless $? == 0
raise ArgumentError, "Failed to apply new exports: #{out}"
end
end

This executes the commands, but does not write the changes to the file.
This makes sense, since I would need to call parsedfile's flush method
first.

If I use "def self.flush" I get:
"err: Got an uncaught exception of type ArgumentError: wrong number of
arguments (1 for 0)"

Can someone please tell me how to achieve this? I have looked into
many providers that do similar things, but the implemenations vary
very much. It is hard to find out from looking at the code.

Is there a way to react to file changes within parsedfile providers,
or types?

Thank you very much,
udo.
--
:: udo waechter - ro...@zoide.net :: N 52º16'30.5" E 8º3'10.1"
:: genuine input for your ears: http://auriculabovinari.de
:: your eyes: http://ezag.zoide.net
:: your brain: http://zoide.net


Luke Kanies

unread,
Jun 22, 2009, 3:18:28 AM6/22/09
to puppe...@googlegroups.com

I don't have much time to help, but basically:

1) You should send an event to the mount service, rather than directly
restarting it. Currently, you'd need to do that by directly adding a
relationship to the catalog if the service exists. This would be best
done in the finish method. E.g.:

def finish
if mount = catalog.resource(:service, "mount")
self[:notify] = mount
end
super
end

Dealing with existing :notify values is left as an exercise to the
reader.

This *should* work, but obviously I haven't tested it. And, of course,
it requires that you choose a specific service name. And it results
in a lot of edges, potentially.

2) The easiest way to track where flush is used/called is via
Transaction, but ParsedFile is special, as always. In general,
individual resources get 'flush' called on them with no arguments, and
they call provider.class.flush with themselves as an argument. I think.

--
Don't tell me how hard you work. Tell me how much you get done.
-- James Ling
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com

Udo Waechter

unread,
Jul 1, 2009, 12:15:20 PM7/1/09
to puppe...@googlegroups.com
Hey Luke.
Thanks for the reply. I was gone onvacation thus the late reaction.

On 22.06.2009, at 09:18, Luke Kanies wrote:

>
> On Jun 21, 2009, at 1:20 PM, Udo Waechter wrote:
>>
>> Can someone please tell me how to achieve this? I have looked into
>> many providers that do similar things, but the implemenations vary
>> very much. It is hard to find out from looking at the code.
>>
>> Is there a way to react to file changes within parsedfile providers,
>> or types?
>
> I don't have much time to help, but basically:
>
> 1) You should send an event to the mount service, rather than directly
> restarting it. Currently, you'd need to do that by directly adding a
> relationship to the catalog if the service exists. This would be best
> done in the finish method. E.g.:
>
> def finish
> if mount = catalog.resource(:service, "mount")
> self[:notify] = mount
> end
> super
> end
>

I found out that this goes into the type but not the provider. The
problem is now, that I can not use this method if I do not have a
service{"mountd": } defined somewhere. Or I would need to create these
resources within the type, but I do not understand how to do that :(

Another problem is, that on some OSes its nfs-kernel-server (or the
userspace versions), on others its mountd.
Thus I have decided to go without this in the type/provider, but
rather definind a way to refresh mountd/nfs-kernel-server within the
manifests via subscribe => File["/etc/exports"]

Thank you,

Luke Kanies

unread,
Jul 1, 2009, 1:18:12 PM7/1/09
to puppe...@googlegroups.com


I figured anyone using this type would need to define that service,
but you need to define it anyway. If the service is named
differently, then they just alias it to 'mountd', so the relationship
always works.

I think this is a much better solution than subscribing to the exports
file, which requires even more work on the part of the person using
your type.

--
The big thieves hang the little ones. -- Czech Proverb

Reply all
Reply to author
Forward
0 new messages