On Monday, May 6, 2013 12:25:30 PM UTC-5, Ken Coar wrote:
I've been having to write (and modify) a lot of modules lately, and I've
so far moved to the following pattern. I'd appreciate comments and
feedback about my approach, particularly in light of the changes to name
scoping (all my modules are currently deployed under 2.7).
I think there's a great advantage to using a consistent module structure,
whatever that happens to be. Of course, some structures are more helpful
than others. I'm still trying to wrap my head around the particulars you
present, but I'll see what I can come up with.
1. mod::defaults (defaults.pp)
- does *not* inherit from anywhere
- 'include mod::settings'
- references module variables with $mod::settings::varname
2. mod::base (base.pp)
- 'inherits mod::defaults'
- 'include mod'
- 'include mod::settings'
- any other things which apply to all classes in the module
3. mod::settings (settings.pp)
- does *not* inherit from anywhere
- has responsibility for resolving and normalising any global or
mod() class variables into sane values
4. mod (init.pp)
- 'inherits mod::defaults'
- 'include mod::settings'
- imports all $mod::settings::<varname> definitions into the $mod
namespace
- if it's a multi-function module (*i.e.*, classes may be
selectively called out for use), this is all it does.
- if it's a single-purpose module, the rest of its work can go here
-- or in other classes it includes
5. all other classes
1. 'inherits mod::defaults'
2. 'include mod::base'
3. does whatever else it's suppposed to do.
The ideas I'm working from are to abstract all the parameter selectors and
such into one class,
Not to be dense, but that class is mod::settings?
resource declaration defaults into another,
And that one is mod::defaults?
and the module top-level namespace and every-class-needs-this stuff into a
third.
And mod::base? Or is this mod?
Does this make sense, or is it completely lame? Or are there better
patterns (that don't require hiera nor puppetdb) I should consider?
That resource defaults are so important to you that you make special
provision for them in your standard module structure seems a bit
questionable to me. Given reliance on module-wide resource defaults, I
guess having classes inherit those from a parent class is a decent
approach, but I would advise you to avoid defaults as much as possible in
the first place. If you do so then few, if any, modules should need
classes for resource defaults.
Which, if any, of these classes are parameterized? Not mod::defaults, I
presume, because parameterized base classes are not supported (though they
don't automatically fail). Are any of the others allowed to be
parameterized? This makes a great difference to the analysis.
If class 'mod' is going to declare any other classes of the module, then
those particular classes cannot follow your "all other classes" pattern.
Otherwise, you would have a parse-order dependency loop: mod::other ==> mod
==> mod::base ==> mod::other. If catalog compilation nevertheless
succeeds, you probably will not get the results you expect. I think that
pattern is suitable only for external-facing classes of a "multi-function"
module.
Class mod::base is confusingly named. It undoubtedly makes sense to you,
but to me it strongly suggests a base class for class inheritance. If your
module structure needs to be easy for anyone other than you to grasp, now
or in the foreseeable future, then I recommend choosing a different name.
Or possibly, just dispense with class mod::base altogether. I'm not sure
what the "any other things" that it provides for might tend to be, but I'm
guessing little, if anything. And what there is could be moved to class
'mod' without disturbing your scheme, since mod::base includes mod. That
leaves just
- inheriting mod::defaults, which does not help other classes because
they inherit mod::defaults themselves
- including class 'mod', which is a possible problem in some modules, as
discussed above
- including mod::settings, which is not harmful, but also not useful,
because parent class mod::defaults also includes mod::settings.
Thus, I'd either remove class mod::base, or restructure its pattern. If
you make class mod include mod::base instead of the other way around, then
perhaps mod::base could have a role in keeping the pattern consistent
between single-function and multi-function modules. Even then, however,
I'm not seeing much advantage.
I think it might help to re-cast your pattern categories. In particular,
"all other classes" is probably too broad a category, and class 'mod' may
not deserve to be in a category by itself. It might be to your advantage
to draw the line between outward-facing classes and other classes, instead.
John