On Apr 28, 2:07 pm, vagn scott <vagnsc...@gmail.com> wrote: > On 04/28/2011 09:54 AM, jcbollinger wrote: > > > > You have to do some sort of provisioning to get Puppet working in the > > first place, so option (1) wouldn't really be so bad. > > > > There is no question that it could be done in provisioning. > > My question is really: How do stages work? > Can I use stages to, as in this example, set up > a proxy that should be in place before > any other classes are expressed?
Run stages leverage Puppet's existing dependency system, to which the "require" and "before" resource metaparameters and other features are also hooked. A run stage essentially creates a node in the dependency graph such that all classes assigned to that stage have a "before" relationship with that stage and a "require" relationship with all previous stages. You can achieve exactly the same effect without run stages, but it can be messy. > > Absolutely the wrong direction (says me). To the extent possible -- > > and that's a very large extent -- use only *un*parameterized classes. > > I don't see any particular reason to expect that using only > > parameterized classes would help here, anyway. > > > > Oh good. But, to rephrase the question, can I control the > stage an unparameterized class gets expressed in? Or, is > it guaranteed that unparameterized classes are expressed in > stage[main]? Because if not, it is useless to have > parameterized classes that want to run before stage[main]. You can use the class { "foo": ... } syntax with unparameterized classes to assign them to stages (or simply as an alternative to "include"), but only once each. I do not recommend also "include" ing the same classes elsewhere in the manifest, which otherwise you could do with an unparameterized class. > > First, consider why you (think you) need class Proxy to be > > parameterized. > > Because, according to the docs I've seen, only parameterized > classes run in stages other than stage[main]. Please clarify > if I'm mistaken. You are mistaken. You must use the class {"foo": } syntax to assign a class to a run stage, but that class does not need to be parameterized. > > From where does the parameter value come? If it's > > really fixed for all nodes, as in your example, then it would be > > better to make it an ordinary variable of class Proxy, or even to > > inline it. Perhaps you could switch to using source=> instead of > > content=>; then you could change the proxy host at need without > > modifying any manifests. > > Don't get sidetracked by the details of the example. > My question is about expressing sequence dependencies in puppet. > The proxy is a real-life example of something that should be done first, > never mind that there are other ways to do it. My point is not so much to quibble the details, but to assert that parameterized classes in general are not everything that they are cracked up to be. I like run stages better than parameterized classes, to the extent that they are separable, but I don't think those are the first tool anyone should reach for to deal with resource ordering issues. That's why I am suggesting alternatives. > > Then recognize that run stages are purely a convenience feature, > > providing nothing that you cannot get by using Puppet's dependency > > system more directly. For instance, you could consider doing this at > > top level: > > > > Package { require => Class['proxy'] } > > But I really don't want to require it. > I want to express that IF a node has Class['proxy'], > then proxy needs to go first. That strikes me as a possible conceptualization problem, and, separately, a possible design problem: On the conceptual level, what does it or *should* it mean that a node has Class['proxy']? To you it seems to mean that the node positively uses an HTTP proxy, at least for Apt. But it could instead mean that the node's proxy configuration is managed, which might include ensuring that it doesn't use a proxy. And that's where the design problem comes in: what do you do if a node configured with a proxy ever needs to be reconfigured for direct connection? Simply excluding Class['proxy'] from that node's manifest doesn't do the job: you must actively manage the config file absent. You could do that by including a different class instead, but it's smoother to give Class['proxy'] enough brains to know whether to configure the node with a proxy or without. If you do that then you can include it on every node, and you probably would want to do so. > > Any package that does not specify its own require parameter > > will then be applied after class proxy. > > This breaks modularity, orthogonality and encapsulation. Any resource that affects the application of resources in different scopes does this -- for an oh-so-random example, a resource that affects how the system's package provider operates. Problems without those characteristics are poor candidates for run stages in the first place. > If I have a class with no require in Package{}, > and then decide to add it, I unwittingly change it's global sequence > relationships as well. It would work if the require > relationships accumulated, rather than got redefined, but that > has its own problems. That is all true. Any approach has its advantages and disadvantages, and my message is not that the default parameter approach is superior. I simply want to challenge you to consider whether run stages are the best solution for your particular problem, and it's entirely possible that they are. It is also possible, however, that they are not. > >> 4. How do parameterized classes and inheritance fit together? > > > > As far as I know, they don't fit together at all. Parameterized > > classes really should be thought of as a distinct thing from ordinary > > classes, offering similar features and bearing a confusingly similar > > name. If you have a need for class inheritance -- and the appropriate > > use cases are few -- then do not mix it with parameterized classes. > > Cool. I can definitely live with that. > > But, I am left wondering if there is any utility to the stage[] > concept at all. I think there is. In particular, I think it's more broadly applicable than you supposed. On the other hand, it's by no means a panacea for dependency problems, and sometimes it even makes them worse by introducing formal dependencies that aren't actually needed. > Puppets dependencies seem to be: > provisioning > network config > backup/restore/disaster recovery > kernel/filesystem config > puppet config > > Puppet can affect these things in only a limited way. And, generally, > they all > have to be there before puppet is useful. Puppet does have its dependencies and limits, just like any other management application. As far as I am aware, those that operate in the context of a running system, like Puppet does, all have dependencies and limits more or less along those lines. Those that operate by different means (e.g. some forms of VM-based systems) have different limits and dependencies. 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-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.