In regard to: [Puppet Users] package handling in puppet?, lamour said (at...:
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 }
There are several ways to deal with this. I know perl is probably a general example of the problem, but at least in that case, it's fairly rare that you need to specify the interpreter directly. If you're making good use of packages, what you probably instead want is something like package { 'perl-Net-SMTP-SSL': ensure => installed, require => Yumrepo['your-local-repo-name-or-maybe-epel'], } In other words, specify your "package { whatever: }" so that it asks for the "highest level" requirement, and just let the packaging system pull in the dependencies. A properly packaged perl module should automatically cause perl to be installed. Let's say you have an unpackaged script (hint: consider packaging it!) that relies on just the core perl modules and doesn't have any external module dependency that you can key on, so keying on some higher level dependency isn't going to work. Now you're back to the cases you were considering. For the first case:
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' }
*Definitely* do not do this. There might be other places where this kind of chicanery is appropriate, but it's not a good idea here.
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.
That's the way we do it for packages where we've run into this issue, but remember again that you generally don't need to do this for every package, you just need to do it for cases where you can identify a package that must be installed *but* isn't going to be pulled in automatically by your package management system via a dependency from some *other* package you're requiring.
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.
I wouldn't recommend that. Generate only the classes that you need, and consider subclasses too. For example, we do have a few cases where non-packaged scripts written by e.g. a dba require something like perl's Foo::Bar module. We have a class for perl and subsclasses for stuff like perl::foo::bar. We only need to include perl::foo::bar and that has the package { 'perl-Foo-Bar': ensure => installed, } *and* the actual OS package has the proper dependency to get pulled in if needed.
Another, less gross, way to do it is to do something like this: if !defined(Package['perl']) { package { 'perl': ensure => installed, } }
I would instead do something more like file { 'your-unpackaged-perl-script-here.pl': ensure => file, owner => 'whomever', group => 'ditto', mode => '0whatever-whatever-whatever', require => Package['perl'], source => 'puppet:///module_name/script-source-here.pl', }
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.
So do class your_class { include your_class::packages # other stuff here. } and split your packages into the your_class::packages class.
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.
Don't rip out hiera, it will be part of puppet 3.x. I'm not familiar with the Singleton module, but I wouldn't think you would need to resort to external modules for something that's pretty fundamental to the problem domain. Another option that some have used in this situation is virtual resources for packages, e.g. class all_packages { @package { 'perl': } @package { 'perl-Foo-Bar': } } and class your_class { realize(Package['perl-Foo-Bar']) } That might be worth considering. We're not doing it that way, but perhaps we should be.
So...what am I doing wrong? Does the puppet philosophy not really allow for maintaining package lists in classes?
It does, but in my experience it should be done in a minimal fashion. Specify the highest level dependency, and let the OS package management system pull in the prereqs, rather than trying to repeat all of the same relationships in your puppet classes. Tim -- Tim Mooney tim.moo...@ndsu.edu Enterprise Computing & Infrastructure 701-231-1076 (Voice) Room 242-J6, IACC Building 701-231-8541 (Fax) North Dakota State University, Fargo, ND 58105-5164 -- 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.