I'm starting to feel like, maybe, I have a fundamentally flawed concept of
how puppet is intended to be used. (new to puppet. setting up initial
puppet environment. blah blah)
so, I've got most of the pieces worked out, but I've hit a major roadblock
with the way packages are handled in puppet. (according to my limited
understanding of puppet, that is) The problem starts with the fact that
including the following in two different classes:
package { 'perl': ensure => installed }
causes this error:
"Duplicate definition: Package[perl] is already defined"
This is pretty unfortunate, but we can try to work around it by doing this:
package { 'test-perl': ensure => installed, alias => 'perl' }
which gives us this error:
"Parameter alias failed: test-perl can not create alias perl: object
already exists"
Ok, can't even get around it like that. I've found two ways around this so
far, both are kinda gross, so I'm starting to wonder if I'm working against
some "prime directive" of puppet.
One pretty kludgey way around it is to wrap each package definition in a
class and then just "include" the classes where I want the packages
defined. I mean, I can write a perl script to generate a class for each
package that is in my packaging system and just do it this way, but it just
feels like I'm cheating, and I have no idea what kind of overhead that
would put on puppet.
Another, less gross, way to do it is to do something like this:
if !defined(Package['perl']) {
package { 'perl':
ensure => installed,
}
}
This is kinda what I expected "ensure => installed" to mean. The big
problem with this method is that it's so verbose that to do this for every
package I want to include would make it somewhat difficult to see which
packages I was including in a class if I had more than a few. I can fix a
bit of the bulkiness by reformatting the expression, but it's still pretty
verbose. The obvious answer to this mess is a defined type, and yet, using
a simple defined type brings us full circle to collisions again. lol
(yes, I can create a defined type that avoids the collision, but then the
invocation starts to get pretty verbose again, and really, it just starts
to feel like I'm not doing any of this "the right way")
We also stumbled across the Singleton puppet module, which does almost kind
of exactly what we want, except it has a dependency on hiera. We haven't
really decided whether to use hiera or not. Efforts to rip the hiera
dependencies out of Singleton and also getting it to run even with hiera
installed have both failed. I'll probably keep looking into modifying the
ruby code to behave in some useful manner for us, but for now, I'm running
out of good options.
So...what am I doing wrong? Does the puppet philosophy not really allow
for maintaining package lists in classes? Do people pretty much define
classes down at the host level to get around this limitation? Does
everyone use some external DB or something to track which classes require
which packages and just manually avoid the collision problem? Is there
some magic syntax that I just haven't found yet? Am I just totally on the
wrong track?
To describe what I'm trying to accomplish, I have a "baseline" class which
defines things I want everywhere and I want to be able to define classes
like "mail_server", "web_server", "samba_server", etc, and then just
include whichever of those classes on a box I need to define the machine's
configuration. I think I've figured out how to do every piece of this
except the packages. I saved this until last, because, honestly, I never
imagined that it was going to work this way. sigh
thanks for any help,
Michael
--
You received this message because you are subscribed to the Google Groups
"Puppet Users" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/puppet-users/-/7ia1AlfYsXMJ.
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-users?hl=en.