On Nov 23, 2:22 pm, Chris C <mazzy...@gmail.com> wrote: > I'm trying to establish a simple inheritance
Although people new to Puppet seem to like to try that, especially when they have a programming background, it's usually not a very good idea. For one thing, inheritance in Puppet doesn't work the way newbies typically expect it to do. For another, it is frequently the case that real-world systems don't fit neatly into the cubbyhole of a single leaf node of the tree. [...] > I have classes with defined files and services for each class of > systems. > > Here is an example... > cat classes/all/class.pp > class all_hosts { > file { "/etc/motd": > ensure => present, > mode => 644, > owner => root, > group => root, > checksum => md5, > source => > "/net/puppetmaster/etc/puppet/manifests/files/all/motd" > } > > cat classes/redhat/all/class.pp > class all_linux { > file { "/etc/motd": > ensure => present, > mode => 644, > owner => root, > group => root, > checksum => md5, > source => > "/net/puppetmaster/etc/puppet/manifests/files/all/motd" > } > > cat site.pp > class all_hosts_redhat { > ####################################################### > # CLASS DEFINITION > import "classes/all/class.pp" > import "classes/redhat/all/class.pp" > ####################################################### > # NODE DEFINITIONS > node default { > include all_hosts > > } > > node /^prac6.akc.org/ { > include all_linux > > } > > I had a heck of a time getting around the "Duplicate Definition" > issue. > > Shouldn't file { "/etc/motd" in prac override file { "/etc/motd" in > all_hosts? No. For good reasons, Puppet forbids duplicate resource declarations in the scope of any node (but see below). > When I do a puppetd --test the content of motd flip flops > between the two classes. That's surprising, because a) unless its hostname changes or your manifests change, each node will get only one definition of File["/etc/motd"], and besides, b) both definitions you have shown point to the same file. (*) (*) Filesystem paths are resolved on the client, and it looks like in your case the file is remote, so you might be getting changes either because a different remote filesystem is mounted at different times or because the remote file is changing. > Maybe there is a better way to do this and I'm just missing something. Yes, there are better ways. Here are several recommendations, with varying degrees of specificity for your stated problem: 1) Organize your manifests into modules. It is never too early to do this. 2) As a general rule, do not declare resources directly in node definitions. Declare them only in classes or definitions. (This does not appear currently to be an issue for you.) 3) Where you want Puppet to manage individual files (such as /etc/ motd), use its built-in file server. Refer clients to this by using a "source" URL of the form "puppet:///<module>/<file>". 4) If you don't need or want a stand-alone external file to serve, especially if the contents rarely change, then consider using "content" instead of "source". 5) If you use node inheritance at all, keep your inheritance tree extremely shallow. If find yourself using more than two levels then either refactor your manifests or switch to an external node classifier (or both). 6) Instead of multiple, similar classes for differing circumstances, write single classes that use nodes' facts where necessary to tailor resources to the target node. 7) Use classes instead of node groups to describe facilities or roles that systems should have. Nodes that serve multiple roles or have multiple unrelated features then simply include all the appropriate classes. 8) If you have resources so general that it's otherwise difficult to declare them in only one place, then create central, virtual declarations for them, and "realize" them wherever needed. System users are the canonical example of such resources. 9) Puppet does provide a feature for overriding resource definitions: a subclass may override properties of resources declared by one of its superclasses, using a special syntax. Leveraging this feature is the *only* good reason for creating a subclass; for any other purpose it is better to "include" another class than to inherit from it. Avoid the temptation to overuse resource overrides, however. 10) For details on how to use any of the features I've mentioned above, consult the Puppet documentation. In particular, these documents may be helpful to you: http://docs.puppetlabs.com/guides/language_tutorial.html, http://docs.puppetlabs.com/guides/modules.html, http://docs.puppetlabs.com/guides/file_serving.html. Perhaps also http://docs.puppetlabs.com/guides/best_practices.html, though it's a bit skeletal at the moment. Good Luck, John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-us...@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.