This is one of the best descriptions of how to do things in Puppet (or
maybe how not to) that I've seen, and touches on a *lot* of common
misunderstandings.

I think I might have to keep a short url to the archive of this handy...

Thanks, John.

On 01/03/2014 10:35 AM, jcbollinger wrote:
>
>
> On Thursday, January 2, 2014 8:28:33 AM UTC-6, Jelle B. wrote:
>
>     Hi all,
>
>     I have been kinda stuck  with the following few issues (all
>     related to one and other)
>
>     What I want ot ddo is define a couple of standard actions in
>     puppet that I can use across all my classes.
>     So for example I define a exec for apt-get update , or a reload.
>     When built in to a class it works fine I would just have to
>     redeclare it with an other name in the next class and I want to
>     get away from it.
>
>
>
> Part of your problem may be that you have a wrong conception of Puppet
> DSL.  The DSL is not a scripting language; in fact, it is not an
> imperative language at all.  There are no "actions" in it.  You need
> to discard the mindset that you are telling Puppet what to do. 
> Instead, embrace the concept that you are describing to Puppet what
> state it needs to achieve.
>
>  
>
>     Now I have started working on importing it via my site.pp but I
>     can not define say the exec for "service $service_name reload", it
>     will generate an error when I include it : Must pass service_name
>     to Class[Defaults] (class defaults being the collective class I
>     brought all these snippets together)
>
>
>
> With respect to services in particular, you are likely to be better
> off relying on the Service resource than to roll your own service
> management via Exec resources.
>
>  
>
>     So question one am I on the right path in creating this , using
>     the top scope prinocipal in my design for this.
>
>
>
> I think not, but it's hard to tell because I don't know what you mean
> by "using the top-scope principal".  On the other hand, you are right
> to be trying to consolidate redundant declarations and to avoid
> repeating yourself.
>
>  
>
>     Second question how do I pass a variable in this setup , as I can
>     not include the class in site.pp as it will generate the "must
>     pass error" but just doing an import in my site.pp and then an
>     include in my module init.pp does not actually work either but
>     then silentlly. 
>
>
>
> The "import" function and the "include" function do very different
> things.  You use "import" to persuade Puppet to parse a /manifest
> file/ that it otherwise would not parse (because it's in the wrong
> place for the autoloader to find it or because there is nothing to
> trigger the autoloader to load it in the first place).  That has
> little to do with declaring classes on the target node, and there are
> very few good use cases for it in modern Puppet.  Instead, put your
> classes and defined types in modules, laid out appropriately for
> autoloading.
>
> The "include" function, on the other hand, instructs Puppet that the
> named /class/ must be included in the target node's catalog.  That is
> sometimes referred to as "declaring" the class.  This form of class
> declaration does not explicitly specify any class parameters, which
> can be useful.
>
> In your case, however, it appears that your class has a defined
> parameter with no default value.  If you must use class parameters --
> a discussion that I will omit for now -- then you must ensure that
> each parameter of each declared class is assigned a value exactly
> once.  Parameter values can come from these places (from highest
> precedence to lowest):
>
>   * from a parameterized-style class declaration or ENC-based class
>     declaration
>   * from hiera via automated data binding (Puppet 3+ only)
>   * from a default value specified in the class itself
>
> I predict that you will be inclined to use parameterized-style class
> declarations, but I urge you to avoid them.  They will cause you
> grief.  Instead, avoid parameterization where it is unneeded, define
> sensible default parameter values, and use Hiera to provide parameter
> overrides where necessary.
>
>  
>
>     I am missing somethign I think just not sure what and where .
>
>
>
> You are missing several things, I suspect.  Among them may be that
>
>   * classes are idempotent -- declaring the same class more than once
>     has no different meaning than declaring it exactly once
>   * defined types and custom functions are therefore better vehicles
>     for parameterized declarations that you want to reuse within the
>     scope of the same node's catalog 
>   * Puppet terminology incorporates some words from the
>     object-oriented programming world that may mislead people with OO
>     programming background.  In particular,
>       o a Puppet "class" is not a model or type for objects, rather it
>         represents a classification of the target node.  There are no
>         class instances, or if that's too alien for you then you can
>         consider all Puppet classes to be Singletons.
>       o Puppet class and node inheritance does not work the way OO
>         programmers tend to expect.
>   * A few other Puppet keywords and terminology sometimes trip up
>     people coming from a programming background, not necessarily OO:
>       o Defined types, created via the "define" keyword, are not
>         analogous to C preprocessor macros.  They are more like OO
>         classes (a lot more so than Puppet classes are, in fact), such
>         that we sometimes talk about "defined type instances" or similar.
>       o Unlike the C preprocessor macro and similar statements in
>         several other programming languages, Puppet's "include"
>         statement does not perform textual interpolation.  I already
>         covered what it actually does do.
>       o The "import" statement does not perform textual interpolation
>         either, though what it actually does do is fairly similar to
>         what Python's "import" does.
>
>  
>
>     Here below the code snippets of what I am doing.
>
>     site.pp in /etc/puppet/environments/dev/manifests/
>     Exec { path => [ "/bin/", "/sbin/" , "/usr/bin/", "/usr/sbin/" ] }
>
>
>
> Ok.  A default path for all Execs is a reasonably sensible thing.  If
> you are using third-party modules, however, then I would be very
> cautious about setting global defaults.  Even something as innocuous
> as that could conceivably cause trouble for a module that did not
> expect it.
>
>  
>
>     import 'classes/*.pp'
>
>
>
> No.  Do not use 'import' to load class definitions.  Instead, put your
> classes into one or more modules, and lay them out where the
> autoloader will find them.
>
>  
>
>     the defaults.pp with the class from
>     /etc/puppet/environments/dev/manifests/classes/ :
>     class defaults ( $service_name ){
>
>
>
> To put this properly in a module named "site", change the class name
> to "site::defaults"
>
>     class site::defaults ($service_name) {
>
> and move the file to
> /etc/puppet/environments/dev/modules/site/manifests/default.pp.  In
> your puppet.conf, make sure the master's configuration for the "dev"
> environment has "/etc/puppet/environments/dev/modules" as or in its
> module path.  (Though in truth, I would leave environments for later
> if I were you.)
>
>  
>
>             case $::operatingsystem {
>                     debian, ubuntu: {
>                             exec { "apt update":
>                                     command => "/usr/bin/apt-get update",
>     #                               onlyif => < snipped >
>                             }
>                     }
>             }
>
>             exec { "reload":
>                     command => "/usr/sbin/service $service_name reload",
>                     refreshonly => true,
>                     require => Service[[$service_name]],
>             }
>
>             exec { "restart":
>                     command => "/usr/sbin/service $service_name restart",
>                     refreshonly => true,
>                     require => Service[[$service_name]],
>             }
>
>
>
> Those particular Execs pretty much duplicate functionality that the
> Service resource provides already.  If you trigger a refresh on a
> running Service resource then the service will be restarted.
>  
>
>
>     }
>
>
>
> Overall, however, the class doesn't make sense.  More specifically, it
> doesn't make sense to parameterize the class with a service name,
> because classes are idempotent.  You would only be able to use it
> once, anyway.  You might, however, be able to make use of something
> like this as a defined type.
>
>  
>
>     And the class calling it from
>     /etc/puppet/environments/dev/modules/pdns/init.pp
>
>     include defaults
>
>
>
> See above: include does not perform textual interpolation.  (Also,
> classes are not analogous to macros.)
>
>  
>
>     class pdns_33 ( $mysql_password, $srv_type, $web_password ) {
>     <-- snipped -->
>            file { "/etc/powerdns/pdns.conf":
>                     ensure => present,
>                     owner => root,
>                     group => root,
>                     mode => 644,
>                     content => template("pdns_33/pdns.conf.erb"),
>                     notify => Exec[[reload]],
>             }
>     <-- snipped -->
>
>
>
> What you are trying to do will not work.  Puppet DSL does not have
> macros.  If your intended uses are similar enough to each other, then
> you might be able to achieve at least some of what you're after via a
> defined type, but in general, you're approaching the whole thing in a
> very non-idiomatic way.
>
> Successful and effective Puppet manifest design is an exercise in
> /modeling/, not programming.  Your objective is to model the target
> configuration of your nodes.  It follows that when writing manifests
> you should be thinking primarily in terms of describing the
> configuration artifacts you want Puppet to manage, rather than in
> terms of specifying actions for Puppet to perform.
>
> Recommended reading:
>
>   * http://docs.puppetlabs.com/puppet/3/reference/lang_summary.html
>   * http://docs.puppetlabs.com/puppet/3/reference/modules_fundamentals.html
>   * 
> http://www.devco.net/archives/2012/12/13/simple-puppet-module-structure-redux.php
>
> Additionally, you should at least skim these:
>
>   * http://docs.puppetlabs.com/references/3.stable/type.html
>   * http://docs.puppetlabs.com/references/3.stable/function.html
>
>
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/puppet-users/ddad9657-6496-41f7-bf0f-e8fee43df7fe%40googlegroups.com.
> 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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/52C80B7C.7070404%40jasonantman.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to