On 05/28/2010 05:00 AM, Luke Kanies wrote:
* Alessandro's presentation caused someone to point out to me
afterward that case statements of this ilk:
case $operatingsytem {
debian: { ... }
redhat: { ... }
}
make a module difficult to extend with support for new operating
system types - you have to modify the module itself in this case.
This situation is not so different from the same problem that occurs
with type/provider pairs in the ruby half of puppet. You just have
fancier tools to implement the case in the providers.
Pulling the case out into extlookup() is nice for simple case statements
-- where you're only looking up the name of one package. OpenSSH on
Solaris vs RedHat vs Ubuntu it makes a great solution. For
puppet-dashboard on RedHat vs Ubuntu though, extlookup() isn't as clear
a winner.
Dashboard doesn't like Ubuntu's rake package (maybe that's a bug? But
ignore it for now for this example...) -- it wants the one from
rubygems. So now the package lists for rhel/ubuntu differ. Worse still,
there's an inter-list dependency where rake needs to be installed via
the gem provider, which requires rubygems installed. Modeling that in
extlookup() is going to be a worse mess than that case statement -- if
nothing else because now you also have to extlookup() the provider=>.
Plus potentially a requires=> for other package situations -- the gem
provider doesn't need it, but other packages may need specific ordering
to install %pre/%post scripts correctly.
If there was a better way to specify a type/provider pattern in puppet
code (not ruby), that seems to me like a better solution here. You can
do this now, but it looks pretty hackish:
[warning: snippeted code. Don't expect it to work as presented here.
Original code can be provided if needed.]
class apache2 {
package { "apache2": alias => "apache2", ensure => present; }
...
# Include operating-specific aspects
include "apache2::${operatingsystem}"
}
define apache2::feature($purge = false, $ensure = 'present') {
search "apache2::${operatingsystem}"
provider::feature {"$name": purge=>"$purge", ensure=>"$ensure"; }
}
... later, in redhat.pp in the apache module:
class apache2::redhat inherits apache2 {
Package["apache2"] { name => "httpd" }
...
# Disable the default site
apache2::redhat::provider::site {"welcome.conf":ensure => absent;}
}
define apache2::redhat::provider::feature($purge = false, $ensure =
'present') {
$string = "LoadModule ${name}_module /u/l/a2/mod/mod_${name}.so"
$conf = "/etc/httpd/conf.d/features.conf"
case $ensure {
'present': { exec { "echo $string >> $conf": unless => "grep
'${string}' $conf"; } }
'absent': { exec { "sed -i '\...@^$string$@ d' $conf": onlyif =>
"grep '${string}' $conf"; } }
}
file {
"/etc/httpd/conf.d/features-${name}.conf":
source =>
"puppet:///modules/apache2/redhat/features-${name}.conf",
ensure => $ensure;
}
}
Of course rather than using ${operatingsystem} you could use an
externally-sourced ${apache2provider} selector. Then anyone could extend
the "default" apache2 module for their OS via their own "class
apache2::redhatfrommysite inherits apache2::redhat { ... }" and use it
by changing the external variable. On the down side, they'd have to
implement all the define ...::provider::<feature, site, etc> even if
they just re-called the parent provider's version of it.
One bad thing about the above is until we get paramaterized classes
(assuming they can be multi-included!), you can end up running into
multiply-defined uglyness ("Apache2::Feature['foo'] already defined at
...") you have to hack around with an if defined in the source where you
want to do the define.
... at least that's where I ended up on a new deployment I'm building
after considering the problem for a while. I'd rather keep all my
OS-specific configuration in one clearly defined location than spread
across multiple files in various locations. YMMV.
--
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.