Re: [Puppet Users] how to implement cascading defaults based on puppet classes
On Sunday, February 10, 2013 12:58:48 PM UTC-6, Roman Shaposhnik wrote: On Sun, Feb 10, 2013 at 9:32 AM, Keith Burdis ke...@burdis.orgjavascript: wrote: Have you looked at using hiera [1] for your configuration? It is very good for cascading defaults with more specific config at the top of the hierarchy and the least specific at the bottom. It is part of Puppet 3 and an add on for 2.7. Yes, I have looked at it. My problem with Hiera is that it resides completely outside of Puppet's DSL and is arguably pretty orthogonal to the parameterized classes API. Separating configuration data from your manifests is precisely what Hiera is for. The prevailing opinion around here is that that's a *good* thing. Besides, if you want the data in Puppet DSL then you can just declare it as variables of some class or classes. Or your ENC can set it as the values of global variables. Furthermore, Puppet 3 integrates Hiera with parameterized classes by using hiera to look up values for class parameters that are not explicitly declared, before ultimately falling back to any defaults written into the class itself. There are good reasons to rely on that function completely, instead of declaring parameters explicitly anywhere, though those reasons are somewhat weaker if you use a custom ENC. I like parameterized classes precisely because they are dynamic. IOW, I can have my ENC instantiate classes with particular parameters depending on any criteria I want *without* affecting anything else on the system. If I want my cluster instantiated during odd numbered hours to have auth = 'simple' and the rest auth = 'kerberos' -- that's just ENC's job. If I want to pull off that same trick with Hiera -- I'm essentially signing up to change a bunch of global variables that can potentially affect my entire site. Is that a bona fide use case for you? That would be unusual. In any case, if you rely on the Hiera integration with parametrized classes then you can draw your data from Hiera under normal circumstances without losing the ability to override via your ENC. That said, I'm starting to suspect that any solution to my problem that can be hidden inside of parsing step has to either be parsing order dependent (yuk!) or it has to rely on some global state that is guaranteed to be consistent before the parser takes over. Hiera fits that description, but it is too global. I really don't understand what you mean by too global. Hiera's architecture appears to be an excellent fit for your cascading defaults, and as I already discussed, you can apply local overrides via your ENC in the event that you actually need to do. It is also easy to define your data hierarchy so that you can provide per-machine data where you want to do that (or per-rack, or per-datacenter, etc., provided only that Puppet can identify the target machines via their node facts). Perhaps I can simply teach my ENC to spew out the top-level parameter called cascading_defaults which would be a hiera-like hash for looking up those very same values. Then my params class could be made rewritten as: class cluster::hdfs::params { auth = hlookup('auth', $::cascading_defaults, ['cluster', 'hdfs'], 'simple') } Does it make sense? That sounds like a workable solution, but whether it makes sense depends on information I don't have. I am inclined to suspect, however, that you are rejecting Hiera based on mis- or limited understanding of what it can do for you. If Hiera can in fact do the job adequately, then I think it makes the *most* sense to use it instead of building your own custom solution. John -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: [Puppet Users] how to implement cascading defaults based on puppet classes
On Mon, Feb 11, 2013 at 6:39 AM, jcbollinger john.bollin...@stjude.org wrote: I am inclined to suspect, however, that you are rejecting Hiera based on mis- or limited understanding of what it can do for you. If Hiera can in fact do the job adequately, then I think it makes the most sense to use it instead of building your own custom solution. Honestly, I started this thread to be educated on various options. If you have the patience to bear with me -- that'll be mostly appreciated. I may ask some silly questions, though -- so patience is the keyword here ;-) Now, before you read further let me state a few assumptions that I have as far as using Hiera with a very custom ENC is concerned and see if they hold true. Here's my ideal state of things as far as how I'd like to use Puppet: #1 I'd like to have a very flexible set of Puppet classes capable of deploying radically different topologies of Bigtop Hadoop clusters. ASSUMPTION: to me this means a set of module(s) full of highly parameterized classes #2 Given that there's nothing static about my environment (I'm not running a datacenter -- I'm running a utility that lets users deploy random configurations of Bigtop Hadoop clusters on VMs) I'd rather minimize the # of things I have to configure/interact with when describing how the next N VMs should look like. ASSUMPTION: to me this means relying exclusively on a very custom ENC that would instantiate classes with precisely the right set of parameters, instead of updating Hiera backend everytime a new deployment is asked for. #3 Even though I can make my ENC spew out a setting for every single parameter that each class needs I'd rather check with the collective Puppet intelligence first to figure out whether there's a DSL-level language construct that would allow a parameter in a 'base' class affect the defaults in the 'child' one. NOTE: I'm NOT talking about dragging data/settings into my classes, I'm purely asking whether there's a sane way for the following bit of my ENC output: classes: cluster::hdfs auth: kerberos to affect all the children such as cluster::hdfs::namenode so the ENC doesn't have to do it explicitly. ASSUMPTION: I do realize that Hiera is one option to make this happen, however, it seems that in my case the trade off is: I need to teach my ENC to manipulate the state of Hiera backend. If I decide to do that it seems that I might as well make my ENC output extremely verbose. Separating configuration data from your manifests is precisely what Hiera is for. The prevailing opinion around here is that that's a good thing. Besides, if you want the data in Puppet DSL then you can just declare it as variables of some class or classes. Or your ENC can set it as the values of global variables. An ideal place for me to keep this data is at the level of ENC. I really *DO NOT* want it at the level of the DSL itself. What I do need at the level of the DSL are the hooks to make the kind of interfacing with the ENC possible. Furthermore, Puppet 3 integrates Hiera with parameterized classes by using hiera to look up values for class parameters that are not explicitly declared, before ultimately falling back to any defaults written into the class itself. There are good reasons to rely on that function completely, instead of declaring parameters explicitly anywhere, though those reasons are somewhat weaker if you use a custom ENC. That's precisely my use case -- a very custom ENC. In fact, I'd rather have my ENC be a single source of truth for all *parameterization* Is that a bona fide use case for you? That would be unusual. It seems to be (unless given my description above you will draw a different conclusion). I really don't understand what you mean by too global. Sorry for the poor choice of words. What I really meant was that in my case, where: # the knowledge of how defaults cascade changes with every single deployment # such knowledge originates with an ENC having Hiera in the mix would mean yet another subsytem which state I'd have to keep consistent with the state of my ENC. That sounds like a workable solution, but whether it makes sense depends on information I don't have. Well, you know know the full story. If you could help making the right choice here -- that'll be, as I said, appreciated. Thanks, Roman. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to
Re: [Puppet Users] how to implement cascading defaults based on puppet classes
On Monday, February 11, 2013 11:09:28 AM UTC-6, Roman Shaposhnik wrote: On Mon, Feb 11, 2013 at 6:39 AM, jcbollinger john.bo...@stjude.orgjavascript: wrote: I am inclined to suspect, however, that you are rejecting Hiera based on mis- or limited understanding of what it can do for you. If Hiera can in fact do the job adequately, then I think it makes the most sense to use it instead of building your own custom solution. Honestly, I started this thread to be educated on various options. If you have the patience to bear with me -- that'll be mostly appreciated. I may ask some silly questions, though -- so patience is the keyword here ;-) Now, before you read further let me state a few assumptions that I have as far as using Hiera with a very custom ENC is concerned and see if they hold true. Here's my ideal state of things as far as how I'd like to use Puppet: #1 I'd like to have a very flexible set of Puppet classes capable of deploying radically different topologies of Bigtop Hadoop clusters. ASSUMPTION: to me this means a set of module(s) full of highly parameterized classes False. Any parametrized class you write can be trivially rewritten without parameters, instead pulling data from an external source (with hiera being the canonical example of such a source). That changes only the protocol by which data is fed to your classes, not their expressive capability. #2 Given that there's nothing static about my environment (I'm not running a datacenter -- I'm running a utility that lets users deploy random configurations of Bigtop Hadoop clusters on VMs) I'd rather minimize the # of things I have to configure/interact with when describing how the next N VMs should look like. ASSUMPTION: to me this means relying exclusively on a very custom ENC that would instantiate classes with precisely the right set of parameters, instead of updating Hiera backend everytime a new deployment is asked for. Questionable. You posit a large and diverse collection of data characterizing the configuration that will be deployed. You will certainly need to record that data somewhere, somehow, for each configuration. You or your users will need to do this at least as part of the process of developing a configuration. You or your users will probably want to have it on an ongoing basis if they want to *maintain* their configuration via Puppet or deploy the same configuration on a new set of VMs. You or your users may also want to have it as a starting point for creating variant configurations, instead of starting from scratch each time. So, since you need to record your data, why not do so in a form that Puppet can use directly? As a bonus, your ENC can then be a lot simpler. #3 Even though I can make my ENC spew out a setting for every single parameter that each class needs I'd rather check with the collective Puppet intelligence first to figure out whether there's a DSL-level language construct that would allow a parameter in a 'base' class affect the defaults in the 'child' one. NOTE: I'm NOT talking about dragging data/settings into my classes, I'm purely asking whether there's a sane way for the following bit of my ENC output: classes: cluster::hdfs auth: kerberos to affect all the children such as cluster::hdfs::namenode so the ENC doesn't have to do it explicitly. ASSUMPTION: I do realize that Hiera is one option to make this happen, however, it seems that in my case the trade off is: I need to teach my ENC to manipulate the state of Hiera backend. If I decide to do that it seems that I might as well make my ENC output extremely verbose. Questionable. Although you could, in principle, make your ENC write or rewrite data for the hiera back end, that seems a strange way to go about it. One would normally maintain the data separately from, but in parallel with the ENC itself. Otherwise you're recomputing the data every time, or else you're reading it from somewhere else and transliterating it into the form that Puppet will consume, which seems like wasted effort to me. To answer your question more directly, Puppet parametrized classes can draw on *non-parametrized* classes' variables for their own parameter defaults, but the mechanism for doing so reliably uses class inheritance, so 1. Doing so prevents you using class inheritance for anything else (which may be tolerable), and 2. You cannot safely use
Re: [Puppet Users] how to implement cascading defaults based on puppet classes
Have you looked at using hiera [1] for your configuration? It is very good for cascading defaults with more specific config at the top of the hierarchy and the least specific at the bottom. It is part of Puppet 3 and an add on for 2.7. - Keith [1] http://www.devco.net/archives/2011/06/05/hiera_a_pluggable_hierarchical_data_store.php On 10 Feb 2013 06:00, Roman Shaposhnik ro...@shaposhnik.org wrote: Hi! suppose my puppet recipes are deploying a configuration for the entire cluster (lets say Hadoop) consisting of quite a few distributed systems (lets say distributed file-system -- HDFS, scheduler -- YARN, coordinator -- zookeeper). Each of these distributed systems in turn consists of a few agents (e.g. in HDFS there's a NameNode, DataNode, etc.). My biggest concern is how to make it possible to cascade defaults in such a way that they can be specified at each of the levels: entire cluster, subsystem, an agent that is part of the subsystem. To be more explicit, suppose I have a node description that looks like this: - class { cluster::hdfs::datanode: namenode_uri = hdfs://foo.company.com, auth = kerberos } class { cluster::hdfs::secondary_namenode: namenode_uri = hdfs://foo.company.com, auth = kerberos } class { cluster::zookeeper::server: ensemble = zoo1.company.com, auth = kerberos } - What would be the ideal way for me to not repeat myself and set auth as a cluster-level default, while having namenode_uri as an HDFS-level default? Really, what I need should look something like: -- class { cluster: auth = kerberos } class { hdfs: namenode_uri = hdfs://foo.company.com } class { cluster::hdfs::datanode: } class { cluster::hdfs::secondary_namenode: } class { cluster::zookeeper::server: ensemble = zoo1.company.com, } Any ideas on how this could be implemented? I've tried a couple of things, but so far no luck. The natural way of solving it via inheritance (e.g. cluster::hdfs inherits cluster and cluster::hdfs::datanode inherits cluster::hdfs, etc.) seems to be of no help at all. Another thing I was considering was something along the lines of: class cluster::hdfs::datanode ( $auth = $cluster::hdfs::params::auth ) inherits cluster::hdfs::params {...} .. class cluster::hdfs::params { if defined(Class['cluster::hdfs']) { $auth = $cluster::hdfs::auth } elsif defined(Class['cluster']) { $auth = $cluster::auth } else { $auth = 'simple' } } seems to be pretty ugly and worse yet dependent on the parsing order. Am I missing something obvious here? Thanks, Roman. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: [Puppet Users] how to implement cascading defaults based on puppet classes
On Sun, Feb 10, 2013 at 9:32 AM, Keith Burdis ke...@burdis.org wrote: Have you looked at using hiera [1] for your configuration? It is very good for cascading defaults with more specific config at the top of the hierarchy and the least specific at the bottom. It is part of Puppet 3 and an add on for 2.7. Yes, I have looked at it. My problem with Hiera is that it resides completely outside of Puppet's DSL and is arguably pretty orthogonal to the parameterized classes API. I like parameterized classes precisely because they are dynamic. IOW, I can have my ENC instantiate classes with particular parameters depending on any criteria I want *without* affecting anything else on the system. If I want my cluster instantiated during odd numbered hours to have auth = 'simple' and the rest auth = 'kerberos' -- that's just ENC's job. If I want to pull off that same trick with Hiera -- I'm essentially signing up to change a bunch of global variables that can potentially affect my entire site. That said, I'm starting to suspect that any solution to my problem that can be hidden inside of parsing step has to either be parsing order dependent (yuk!) or it has to rely on some global state that is guaranteed to be consistent before the parser takes over. Hiera fits that description, but it is too global. Perhaps I can simply teach my ENC to spew out the top-level parameter called cascading_defaults which would be a hiera-like hash for looking up those very same values. Then my params class could be made rewritten as: class cluster::hdfs::params { auth = hlookup('auth', $::cascading_defaults, ['cluster', 'hdfs'], 'simple') } Does it make sense? Thanks, Roman. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
[Puppet Users] how to implement cascading defaults based on puppet classes
Hi! suppose my puppet recipes are deploying a configuration for the entire cluster (lets say Hadoop) consisting of quite a few distributed systems (lets say distributed file-system -- HDFS, scheduler -- YARN, coordinator -- zookeeper). Each of these distributed systems in turn consists of a few agents (e.g. in HDFS there's a NameNode, DataNode, etc.). My biggest concern is how to make it possible to cascade defaults in such a way that they can be specified at each of the levels: entire cluster, subsystem, an agent that is part of the subsystem. To be more explicit, suppose I have a node description that looks like this: - class { cluster::hdfs::datanode: namenode_uri = hdfs://foo.company.com, auth = kerberos } class { cluster::hdfs::secondary_namenode: namenode_uri = hdfs://foo.company.com, auth = kerberos } class { cluster::zookeeper::server: ensemble = zoo1.company.com, auth = kerberos } - What would be the ideal way for me to not repeat myself and set auth as a cluster-level default, while having namenode_uri as an HDFS-level default? Really, what I need should look something like: -- class { cluster: auth = kerberos } class { hdfs: namenode_uri = hdfs://foo.company.com } class { cluster::hdfs::datanode: } class { cluster::hdfs::secondary_namenode: } class { cluster::zookeeper::server: ensemble = zoo1.company.com, } Any ideas on how this could be implemented? I've tried a couple of things, but so far no luck. The natural way of solving it via inheritance (e.g. cluster::hdfs inherits cluster and cluster::hdfs::datanode inherits cluster::hdfs, etc.) seems to be of no help at all. Another thing I was considering was something along the lines of: class cluster::hdfs::datanode ( $auth = $cluster::hdfs::params::auth ) inherits cluster::hdfs::params {...} .. class cluster::hdfs::params { if defined(Class['cluster::hdfs']) { $auth = $cluster::hdfs::auth } elsif defined(Class['cluster']) { $auth = $cluster::auth } else { $auth = 'simple' } } seems to be pretty ugly and worse yet dependent on the parsing order. Am I missing something obvious here? Thanks, Roman. -- You received this message because you are subscribed to the Google Groups Puppet Users group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.