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.