On 06/02/2010 07:42 PM, Luke Kanies wrote:
How would something like this work as a language feature? Something
like:
class apache2::redhat implements apache2 for(operatingsystem =>
redhat) { ... }
>
We need something that can be queried from outside, and we need
something that can essentially be automatically loaded when the base
class is evaluated.
That could work for me. Agreed on the query-ability, though I'd still
like to leave in a override mechanism. Example: so you could override
apache2::redhat to use a custom apache package, rather than the generic
redhat one -- yet otherwise keep the other standard "apache redhat
module" behaviors intact -- how sites are defined in /etc/httpd/conf.d/,
etc, etc.
It seems like we almost want to build an automatically included class
heirarchy, with a class search path that the base class can define:
class apache2
loads_subclasses(operatingsystem::operatingsystem_release,
operatingsystem) { ... }
So, when someone included apache2, Puppet would automatically look for
"apache::$operatingsystem::$operatingsystem_release" then "apache::
$operatingsystem", and include them if found.
Doing it in this way would mean folks could override apache2 with a
child class, then override the load_subclasses line. That'd let them
include their own partial or full implementations (which couldn't be
named apache2::$operatingsystem since that'd be duplicate definitions),
so I guess that'd work out fine. Bit complex and intimidating looking
though...
That doesn't start to approach your provider feature stuff, but I
think that's a bit outside my brain space right now. :)
It might be able to be much simpler; boiling it down, all we're really
doing is writing a lot of fancy syntax to accomplish what looks a lot
like a shell alias, right? Consider:
class apache {
include apache::$os
implements {
"apache::featuers": provider => apache::$os::features;
"apache::sites": provider => apache::$os::sites;
}
}
which would essentially translate any class/define calls to
apache::features into apache::$os::features. The only trick there is
it'd be hard to override the "include apache::$os" -- at least until
parameterized classes and you could pass in a "provider=>" to the apache
class (defaulting to provider=>$operatingsystem). {post-thought: I
suppose extlookup() actually would be a really good solution there until
or even after param'd classes.}
This contradicts any type/providers pattern by removing the "provider
knows where it belongs" pushing that up into the generic apache class.
I'm not particular on where that applicability decision resides, but
pushing it up keeps the DSL simpler and in many ways, clearer. Module
developers specify "sane" defaults, but individual sysadmins running
puppet can override them.
It'd be easy to use too -- add site-specific tweaks to a module -- so if
I run RedHat but need to store things in /services for historic reasons,
I can tweak the provided classes to do that with (relatively) minimal
effort. I don't have to fork the apache module, nor do I have to start
from scratch. Or be sick and wrong and mix and match providers, thus:
class siteapache inherits apache {
# Use CAR instead (Custom Apache on Redhat)
include siteapache::myca
Implements["apache::features"] { provider=>apache::redhat::sites }
Implements["apache::sites"] { provider=>apache::debian::sites }
file { "/etc/httpd/conf.d/debian_style_sites.conf":
content => "Include /etc/apache2/sites-enabled/" }
}
class siteapache::myca inherits apache::redhat {
Package["httpd"] { name => "mycrazycustomapache" }
}
I can't tell from a brief grep around the puppet ruby code if
implements{} would be easy to write or not. My offhand guess is fairly
easy -- it'd basically just reach inside puppet's class listings and at
the worst, subclass $name to provider=>value. (I did try 'class foo
inherits foo::$operatingsystem' in the DSL itself, but the parser wasn't
impressed with a variable interpolation post 'inherits'.)
One big drawback I'm seeing is this is likely order-dependent. Until
apache/implements{} is evaluated, calls to apache::sites are likely to
be undefined. So you may never be able to 'include apache' -- you'll
have to 'require apache' instead.
--
You received this message because you are subscribed to the Google Groups "Puppet
Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en.