On Mar 29, 12:39 pm, Thomas Bellman <bell...@nsc.liu.se> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> (I know I'm late in responding; I'm a couple of months behind in reading
> the mailing-list, and still have 2000 unread.  I have read this entire
> thread, though.)
>
> On 2012-01-19 18:18, Nigel Kersten wrote:
>
> > I'm looking for strong opinions on whether we should or shouldn't deprecate
> > the defined() function for Telly, the next major Puppet release this year.
>
> > jcbollinger put it quite well in another thread:
>
> > "Use of the "defined" function introduces a parse-order dependency, and the
> > additional work you need to do to ensure that that dependency is always
> > fulfilled overcomes any simplicity advantage that might otherwise exist."
>
> - -1 until there is some other, usable, way of realizing the good things
> you can achieve with defined().
>
> My use case for defined() is in definitions that wants to make sure
> a package it needs is installed, and where that package varies between
> instances of the definitions.  For example, I have a definition named
> nrpe::check, which configures a Nagios NRPE check.  It wants to make
> sure the appropriate nagios-plugins-PLUGIN is installed, so it does
> (simplified, and just retaining the code dealing with the package):
>
>     define nrpe::check($plugin='', $checker='', $args=[], $prefixcmd=[])
>     {
>         $pluginpkg = $plugin ? {
>             ''      => "nagios-plugins-${name}",
>             0       => '',
>             default => $plugin,
>         }
>
>         if $pluginpkg != ''  and  ! defined(Package[$pluginpkg]) {
>             package {
>                 $pluginpkg: ensure => installed,
>             }
>         }
>     }


Yes, that's exactly the sort of thing you should avoid for reliability
and maintainability.  It will not do what you want if the declaration
of the desired package has not yet been parsed, and parse order is
tricky to predict except by means that offer better solutions anyway.

That particular example appears to be a good use case for virtual
resources:

class nrpe::plugins {
    @package { 'nagios-plugins-plugin1': ensure => 'installed' }
    @package { 'plugin2': ensure => 'installed' }
}

define nrpe::check($plugin='', $checker='', $args=[], $prefixcmd=[])
{
    include 'nrpe::plugins'

    $pluginpkg = $plugin ? {
        ''      => "nagios-plugins-${name}",
        0       => '',
        default => $plugin,
    }

    if $pluginpkg != '' {
        realize Package[$pluginpkg]
    }
}


> A user would do things like:
>
>     nrpe::check { 'load': args => [ '-w20,10,8', '-c30,18,10' ]; }
>
> and the "nagios-plugins-load" package will automatically be installed.
> This becomes interresting when you have:
>
>     nrpe::check { 'test_foo': args => ['foo'], plugin => 
> 'nagios-plugins-ourtest'; }
>
> and
>
>     nrpe::check { 'test_bar': args => ['bar'], plugin => 
> 'nagios-plugins-ourtest'; }
>
> both using the same plugin, but with different parameters, in different
> parts of the manifest for the node.  The cincher here is that there are
> several dozens of Nagios plugin packages available (EPEL has 63, many
> organizations probably have several of their own, and so on).
>
> It would be possible to instead have the nrpe::check definition do
>
>     include "nagios_plugin_package::${plugin}"
>
> and force the user to define a class for each plugin they use (and I
> could of course "pre-seed" by writing 63 of those myself in my nrpe
> module).  But it becomes much easier on the users of the nrpe module
> if they don't need to do so.


And defining separate classes for the needed packages is indeed
another avenue to the desired result.


> This use of defined() is safe, since there is really only a single
> declaration of each Package['nagios-plugins-PLUGIN'] resource.


Your particular usage may work reliably in your context, but I
wouldn't call it "safe".  It risks breakage if any of the packages in
question indeed are declared elsewhere in your manifests, and it is
insufficient if ever you have a need for any of the plugin packages to
be declared with nonstandard properties (e.g. a specific version).

That usage of defined() requires faithful adherence to usage patterns
that Puppet has no means to check or validate, and there are viable
alternatives (even if you don't like them as well for your specific
case).  That's why that use of defined() is under consideration for
deprecation.


> I'm not fond of defined(), as it is easy to get wrong, but it is also
> quite useful in some cases.  It would be a shame to deprecate a useful
> feature before there is a workable way to achieve the same end results
> in place.


The use you describe has much in common with the module
interoperability problem.  I don't expect any fundamental advances in
that area in Telly, but I have high hopes for the following major
release.


John

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

Reply via email to