How to override / redefine outside child class (usecase and example detailled)

329 views
Skip to first unread message

Alexandre

unread,
Dec 9, 2009, 4:44:41 AM12/9/09
to Puppet Users
The use case i try to illustrate is when to declare some item (eq
mysqld service) with a default configuration that could be included on
every node (class stripdown in the example, for basenode), and still
be able to override this same item in some specific class (eg
mysql::server), to be included by specific nodes (eg myserver.local)

I illustrated this use case with the example below. But of course,
Puppet parsing fails because the Service[mysql] is included twice. And
of course, class mysql::server

Is there a way to override the Service["mysql"], or mark it as the
main one, or whatever ?
I was thinking about the virtual items and the realize function, but
it only permits apply an item multiple times, not to redefine or
override.

class stripdown {
service {"mysql": enable => "false", ensure => "stopped" }
}

class mysql::server {
service { mysqld:
enable => true,
ensure => running,
hasrestart => true,
hasstatus => true,
path => "/etc/init.d/mysql",
require => Package["mysql-server"],
}
}

node basenode {
include stripdown
}

node myserver.local inherits basenode {
include mysql::server # <- boom, fails here
because of Service["mysql"] redefinition
}

Silviu Paragina

unread,
Dec 9, 2009, 7:27:59 AM12/9/09
to puppet...@googlegroups.com
On 09.12.2009 11:44, Alexandre wrote:
The use case i try to illustrate is when to declare some item (eq
mysqld service) with a default configuration that could be included on
every node (class stripdown in the example, for basenode), and still
be able to override this same item in some specific class (eg
mysql::server), to be included by specific nodes (eg myserver.local)

I illustrated this use case with the example below. But of course,
Puppet parsing fails because the Service[mysql] is included twice. And
of course, class mysql::server

Is there a way to override the Service["mysql"], or mark it as the
main one, or whatever ?
I was thinking about the virtual items and the realize function, but
it only permits apply an item multiple times, not to redefine or
override.

class stripdown {
    service {"mysql": enable => "false", ensure => "stopped" }
}
  
Not tested but it should be like
class stripdown {
    include mysql::server
    Service {"mysql": enable => "false", ensure => "stopped" }
}
Check the language tutorial for overriding. Note that is a big "S" not a small "s".
Or you may do it the other way around. (Include stripdown into mysql::server. (this probably the solution you want)

Or define a third skeleton class which starts with same bare definitions, and the other two override them

Silviu
class mysql::server {
    service { mysqld:
        enable      => true,
        ensure      => running,
        hasrestart  => true,
        hasstatus   => true,
        path        => "/etc/init.d/mysql",
        require     => Package["mysql-server"],
    }
}

node basenode {
    include stripdown
}

node myserver.local inherits basenode {
    include mysql::server                     #   <- boom, fails here
because of Service["mysql"] redefinition
}

--

You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To post to this group, send email to puppet...@googlegroups.com.
To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.


  

jcbollinger

unread,
Dec 9, 2009, 9:28:00 AM12/9/09
to Puppet Users

On Dec 9, 6:27 am, Silviu Paragina <sil...@paragina.ro> wrote:
> Not tested but it should be like
>
> class stripdown {
>      include mysql::server
>      *S*ervice {"mysql": enable =>  "false", ensure =>  "stopped" }
>
> }
>
> Check the language tutorial for overriding. Note that is a big "S" not a
> small "s".

As far as I know, overriding only works in a subclass, so it would
need to be:

class stripdown inherits mysql::server {
Service { "mysqld": enable => "false", ensure => "stopped" }
}


Obviously, that's messy and it doesn't scale for multiple overrides.
It may also have other, unwanted effects.

> Or you may do it the other way around. (Include stripdown into
> mysql::server. (this probably the solution you want)

It would indeed make more sense for mysql::server to inherit stripdown
and override it, but again this does not scale. If stripdown declares
any resources then I think you will get resource conflicts again if
you include multiple subclasses in the same manifest (e.g.
mysql::server and http::server, both inheriting stripdown).

> Or define a third skeleton class which starts with same bare
> definitions, and the other two override them

And in this case, the manifest needs to use a conditional to select
which subclass to include. I think that's the best general approach,
but if you're going to do that then you don't need to subclass or
override anything. Just have separate classes mysql::server and
mysql::server::disabled, and include exactly one, as appropriate.

Note also that any approach that forces mysqld to be disabled on
machines that aren't supposed to be mysql servers requires that mysql
nevertheless be *installed* on those machines. Many admins would
argue that it shouldn't be present at all if it's not supposed to run.

Silviu Paragina

unread,
Dec 9, 2009, 11:19:07 AM12/9/09
to puppet...@googlegroups.com
On 09.12.2009 16:28, jcbollinger wrote:
> As far as I know, overriding only works in a subclass, so it would
> need to be:
>
> class stripdown inherits mysql::server {
> Service { "mysqld": enable => "false", ensure => "stopped" }
> }
>
>
> Obviously, that's messy and it doesn't scale for multiple overrides.
> It may also have other, unwanted effects.
>

Yep, sorry I've had some bad concepts about overriding. Sorry for
posting bad stuff on the list.

Testing on a 0.25.1

I got to this


class s_test1::stripdown
{
service
{ "mysqld":
name => "mysql",
enable => false,
ensure => stopped,
}

#other definitions that make sure that the service is not working
}

class s_test1::client inherits s_test1::stripdown
{
#definition overrides to install the client part
}

class s_test1::server inherits s_test1::client
{
#if this is the server the client part should be also included
#that's why we inherit from s_test1::client


#overrides definitions
Service ["mysqld"] { enable => true, ensure => running }
}

of course you should create a class stripdown which includes stripdown
for each service you want.

I think this is the usual style of defining stuff in puppet as I've seen
it in a lot of places.

Now if you include both s_test1::stripdown and s_test::server server
will take precedence. (actually it may start as s_test1::stripdown and
then "add to it" s_test1::server, but the behavior is respected no
matter what the order of includes).


Silviu

jcbollinger

unread,
Dec 10, 2009, 11:46:11 AM12/10/09
to Puppet Users

On Dec 9, 10:19 am, Silviu Paragina <sil...@paragina.ro> wrote:
> I think this is the usual style of defining stuff in puppet as I've seen
> it in a lot of places.

I have often seen the model of

class some_facility::base {}
class some_facility::server {}
class some_facility::client {}

I have not noticed class inheritance routinely being used in such a
setup, but I may have just overlooked it. If client and server
classes simply "include" the base class, though, then that achieves
everything that inheriting would do except allowing resource
overrides.

I don't have any objection to the client and server classes both
inheriting the base class, but it is conceptually wrong for server to
inherit client, for the server machines do not need to also be
clients.

For general-purpose overrides (as opposed to node-specific ones), the
best practices recommend something of the form

class some_facility::server::disabled
inherits some_facility::server { [resource overrides here] }


> Now if you include both s_test1::stripdown and s_test::server server
> will take precedence. (actually it may start as s_test1::stripdown and
> then "add to it" s_test1::server, but the behavior is respected no
> matter what the order of includes).

Somewhat to my surprise, that works. On the other hand, the fact that
I find it surprising is enough reason for me, personally, to never use
that motif. To be clear: the surprising thing to me is that Puppet
does not complain about including both s_test1::stripdown and
s_test1::server in the same catalog, even though they define
conflicting properties for Service["mysqld"]. (It can be made to
complain about conflicting properties if you structure the classes and
overrides differently, though.)

How to approach this kind of issue is surely a matter of opinion and
preference, but for me it doesn't make sense to have a blanket disable
for a service that isn't necessarily even installed. Thus, I would do
something more like this:

class mysql::server {
package { "mysql-server": ensure => "latest" }
service { "myslqd":
name => "mysql",
require => Package["mysql-server"],
enable => true,
ensure => "running",
}

class mysql::server::disable inherits mysql::server {
Service { "mysqld": enable => false, ensure => "stopped" }
}

There are then three options for each node:
1) The mysql server is unmanaged, or forced not present if package
purging is enabled. This happens if neither mysql::server nor
mysql::server::disable is included.
2) The mysql server is installed, enabled, and running. This happens
if mysql::server is included and mysql::server::disable is not.
3) The mysql server is installed but disabled and not running. This
happens if mysql::server::disable is included.

YMWV

Alexandre

unread,
Dec 15, 2009, 5:03:28 AM12/15/09
to Puppet Users
I though i found a way to do it, and i would like to show it here,
but unfortunately it does not exactly work well, see the comment in
uppercase: global variables seems to be set even if no class from
the .pp file is included.
And i also think now i am going to far into akwardness, just trying
to work around some Puppet limitations, or maybe thinking of Puppet
beyond its scope, as if it was a full featured language
I am wondering now if it is always a good idea to try to do
everything within Puppet. I think if i get time, i will do a generic
script to address this problem, which would be deployed with the usual
set of scripts i deploy on each server, and run it from Puppet. I also
recently went onto another set of Puppet problem, to which i began
implementing a define to do some processing, and ended up having this
define only get the parameters and give it all to a deployed script
that does the processing (just because i needed to loop on the items
of a puppet array).

Anyway, here was my last, and almost working to get the default
stripdown (shows relevant parts) :

##
## mysqld.pp
##

# This variable is global, not defined inside the class, otherwise it
will never be seen as set, due to the dynamic scope
$_service_is_managed_mysqld=1
class mysql::server inherits mysql {
# (...)
}


##
## stripdown.pp
##

define stripdown_service ( $pattern="" ) {

if $pattern == "" {
exec { "stripdown $name stop":
command => "service $name stop",
onlyif => "service $name status",
path => "/usr/bin:/usr/sbin:/bin:/sbin",
}
} else {
exec { "stripdown $name stop":
command => "service $name stop",
onlyif => "pgrep -f \"$name\"",
path => "/usr/bin:/usr/sbin:/bin:/sbin",
}
}

exec { "stripdown $name deactivate":
command => "chkconfig $name off",
onlyif => "chkconfig $name",
path => "/usr/bin:/usr/sbin:/bin:/sbin",
}
}

class stripdown_services::centos {
service {
"autofs": enable => "false", ensure => "stopped";
"avahi-daemon": enable => "false", ensure => "stopped";
# (...)
}

# THIS $_service_is_managed_xxx THING DOES NOT WORK : EVEN IF NOT
CLASS NOT INCLUDED IN THE NODE, THE VARIABLE SEEMS TO BE SET !!!

if $_service_is_managed_squid != 1 { stripdown_service{squid:} }
if $_service_is_managed_lighttpd != 1 { stripdown_service
{lighttpd: pattern=>"lighttpd.conf"} }
if $_service_is_managed_mysqld != 1 { stripdown_service{mysqld:} }
# (...)
}


jcbollinger

unread,
Dec 15, 2009, 9:56:51 AM12/15/09
to Puppet Users


On Dec 15, 4:03 am, Alexandre <alexandre.fou...@gmail.com> wrote:
>    I though i found a way to do it, and i would like to show it here,
> but unfortunately it does not exactly work well, see the comment in
> uppercase: global variables seems to be set even if no class from
> the .pp file is included.

Yes. Modules and manifest files do not provide scoping.

>    And i also think now i am going to far into akwardness, just trying

I agree (a bit more on that below).

> to work around some Puppet limitations, or maybe thinking of Puppet
> beyond its scope, as if it was a full featured language

Puppet is a declarative language. Users who come from a programming
background seem sometimes to have difficulty coming to grips with
that. If you ever find yourself thinking "how do a make Puppet do
foo?" then you are off to a wobbly start. A better question is
usually "how do I explain foo to Puppet?".

>    I am wondering now if it is always a good idea to try to do
> everything within Puppet.

Puppet does have limits to what it can do natively for you (though it
is also highly extensible). Where it is possible, using Puppet types
other than Exec to get the work done has several advantages.

[...]

> and ended up having this
> define only get the parameters and give it all to a deployed script
> that does the processing (just because i needed to loop on the items
> of a puppet array).

Puppet is not built to do user-defined processing, except inasmuch as
you can always create your own types and / or providers.

>    Anyway, here was my last, and almost working to get the default
> stripdown (shows relevant parts) :

[...]

> # This variable is global, not defined inside the class, otherwise it
> will never be seen as set, due to the dynamic scope
> $_service_is_managed_mysqld=1

So the idea is that you have a variable for each service that later
instructs Puppet whether to run "stripdown" commands for that
service? And that implies that somewhere you dynamically choose a
value for this variable based on the facts presented to the
puppetmaster?

That seems awfully convoluted. Why not use that same decision logic
to dynamically choose whether to include a class? Furthermore, if you
have to make that decision dynamically, then it is no harder to choose
between two alternative classes than to make only a yes/no decision
about a single class. That leads to having two alternative classes,
one declaring "stripdown"-configured resources and the other declaring
enabled resources, where you dynamically decide which to include for
each node. And that's what I have been recommending all along.

[...]

>     if $pattern == "" {
>         exec { "stripdown $name stop":
>                 command => "service $name stop",
>                 onlyif  => "service $name status",
>                 path    => "/usr/bin:/usr/sbin:/bin:/sbin",
>             }
>     }

[etc.]

I'm not seeing what that "stripdown" define does for you that the
Service type doesn't, unless .... Please tell me that you're not
using these Execs to change the state of Services declared elsewhere!
That way lies madness.

I guess I'm at a loss as to what problem you're trying to solve any
more. Silviu and I offered two solutions to you, either one of which
will work cleanly and entirely within Puppet to solve your problem as
I understood it. What more are you looking for that neither of these
provides?

Alexandre

unread,
Dec 16, 2009, 10:17:35 PM12/16/09
to Puppet Users
Yes all of this is very convoluted, but not because of my mind,
just because Puppet PARSER is too strict and prevents states that can
exists in the real.

No, i do not try to use exec to change the change the state of the
service which is -executed- elsewhere (i aggree it would be stupid and
impossible, a ressource can not have two different status at the same
time), but i do use exec to set services that are -declared- elsewhere
in puppet, but not included(executed). So that the state of the
service is the one of the exec. Unfortunately, i had to do that,
because otherwise Puppet would complain at -parsing- time, not execute
time, since it does not want to have the same ressource(here service)
declared twice, even if one is not included for the node, nor be
overriden if not in a child class (and i understand very well the
logic behind that, it makes sense, if we do not consider that we could
assign priorities or precedences on puppet ressources (but then it
could be a mess :-/))

I also checked your solutions, but it does not solve what i wanted
to achieve. What i wanted is per node :
- if i want to include a class (eg mysql::server), then i
include it.
- If it is missing(not included or required by some other
included class), then have the default global stripdown executed.
As i understood, your solution says that if i do not want a
service in a node, then i should include the disabled class (eg
mysql::server::disabled). This is not what i want, what i want is my
nodes definition to be agnostic of what could have been included
previously in the past or may already be present on the server. I do
not want for each node to declare every ressource that exist in my
puppet repo to be disabled (Eg if only 1 node of my 100 needs mysql
running, i do not wish to have to include mysql::server::disabled in
the 99 other nodes definitions. But i want to ensure the mysqld
service is down for these 99 nodes, in case it was running on the node
for whatever reason).
Of course, we need to accept that puppet will try to stripdown
services that are not even installed, but i do not see it as a
problem.

I think this is good general practice of sysadmin to ensure
everything on a linux system that is not needed should be removed,
restricted or disabled (services, users, dir permissions). As we see
here, it seems Puppet can not fullfill this need, except by listing
explicitely and exhaustively what needs to be or not be activated for
each node. So of course, one way or another, there is a place where i
need to tell what should be stripdowned. But i want it to be accepted
as the default -state- of the node, unless specified otherwise by
including a class which redefines some of the ressources that need to
be activated. I do not want my nodes.pp to be 1000000 lines and
unmaintanable.

I understand the meaning of declarative language. I just miss the
fact that i can not declare something like if something is not
included, then apply this whole set of declarations.
-> Unfortunately for me, there might be a way to do this
"default state"/"included state" scheme in Puppet, or by including
ruby or facter or ..., but i am not a puppet expert. This could maybe
be the subject of another thread

Peter Meier

unread,
Dec 17, 2009, 3:51:36 AM12/17/09
to puppet...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

> [...]


> I think this is good general practice of sysadmin to ensure
> everything on a linux system that is not needed should be removed,
> restricted or disabled (services, users, dir permissions). As we see
> here, it seems Puppet can not fullfill this need, except by listing
> explicitely and exhaustively what needs to be or not be activated for
> each node. So of course, one way or another, there is a place where i
> need to tell what should be stripdowned. But i want it to be accepted
> as the default -state- of the node, unless specified otherwise by
> including a class which redefines some of the ressources that need to
> be activated. I do not want my nodes.pp to be 1000000 lines and
> unmaintanable.


How about doing it the other way round? Generally include the
stripped-down classes and then include additionally per node the mysql
class which inherits the stripped down class but overwrites the
resources to manage mysql:

node default {
include configsets
}

node mysqlserver {
include configsets::mysqlserver
}

class configsets {
include mysql::server
}

class configsets::mysqlserver {
include config
include mysql::server::present
}

class mysql::server {
package{'mysql-server': ensure => absent }
service{'mysql-server':
ensure => stopped,
enable => false,


require => Package['mysql-server'],
}
}

class mysql::server::present inherits mysql::server {
Package['mysql-server']{ ensure => installed }
Service['mysql-server']{
ensure => running,
enable => true,
}
file{'/etc/my.conf':
source => "...."
notify => Service['mysql-server'],
}
}

Naming convention could be better, but I think this should generally
work. You simply include every resource you manage in the general class
configsets, which gets applied to every node (also due to inheritance,
reinclusion) but include the "present" class in nodes that need it.

> I do not want my nodes.pp to be 1000000 lines and unmaintanable.

I would generally avoid putting too much into nodes. My nodes look like:

node default {
$some_var_1 = 'aaa'
$some_var_2 = 'bbb'
include configsets
}

node foobar {
$some_var_1 = 'foo'
$some_var_2 = 'bar'
include configsets::foobar
}

And all the actual service includes are done in the module called
configesets, which can have further abstraction like node-types, i.e.
physical nodes (class is included depending on the virtual fact) etc.,
inheritance and so on.

Did I miss some circumstances why this shouldn't work?

cheers pete.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAksp8QQACgkQbwltcAfKi383ZwCdHOZO8yYdo6zooR07tgy5OE7/
ZhgAoJzWrZoO2ikcrO/ZRJVLE/fPcufr
=/lYm
-----END PGP SIGNATURE-----

jcbollinger

unread,
Dec 17, 2009, 9:18:03 AM12/17/09
to Puppet Users

On Dec 17, 2:51 am, Peter Meier <peter.me...@immerda.ch> wrote:
> How about doing it the other way round? Generally include the
> stripped-down classes and then include additionally per node the mysql
> class which  inherits the stripped down class but overwrites the
> resources to manage mysql:

[...]

This is precisely what Sliviu recommended, and, as far as I can tell,
it's exactly what Alexandre is asking for. The general approach
demonstrably works, which is why I am confused by Alexandre's claim
that Puppet can't do what he wants.


John

jcbollinger

unread,
Dec 17, 2009, 9:34:30 AM12/17/09
to Puppet Users

On Dec 16, 9:17 pm, Alexandre <alexandre.fou...@gmail.com> wrote:
[...]


> because otherwise Puppet would complain at -parsing- time, not execute
> time, since it does not want to have the same ressource(here service)
> declared twice, even if one is not included for the node,

Puppet does not exhibit this problem for me. The only way I have been
able to elicit a resource conflict error from Puppet is to have one
node include two classes each declaring a resource of the same type
and name. It is not enough to cause such an error (in my tests)
simply for two classes to define the same resource -- both must be
included in the same node to get the error. If you find differently
then I encourage you to file a bug report.

John

jcbollinger

unread,
Dec 17, 2009, 11:39:42 AM12/17/09
to Puppet Users

On Dec 16, 9:17 pm, Alexandre <alexandre.fou...@gmail.com> wrote:

>     I understand the meaning of declarative language. I just miss the
> fact that i can not declare something like if something is not
> included, then apply this whole set of declarations.

From the glass-half-full department, I'd like to point out that this
is only an issue in the first place because the Puppet language is
rich enough that there can be some uncertainty about whether a
particular class will be included for a particular node.

You cannot solve your problem in the particular way you were trying to
do, but that does not mean that you cannot solve it within Puppet, nor
even that you cannot solve it within Puppet in a concise and
maintainable way. The structure of the Puppet language strongly
encourages modularity, in the sense of putting related logic and
declarations in the same place. If you try to go against that grain,
as it appears you did, then you are indeed likely to become
frustrated. Nevertheless, you may be able to make that approach work
with use of the built-in "defined" function or by writing your own
custom function. I think the alternatives that Silviu and I, and now
Peter, are suggesting are better aligned with with the language
structure, however.


John

jcbollinger

unread,
Dec 17, 2009, 12:57:08 PM12/17/09
to Puppet Users

On Dec 17, 8:34 am, jcbollinger <John.Bollin...@stJude.org> wrote:
> On Dec 16, 9:17 pm, Alexandre <alexandre.fou...@gmail.com> wrote:
> [...]
>
> > because otherwise Puppet would complain at -parsing- time, not execute
> > time, since it does not want to have the same ressource(here service)
> > declared twice, even if one is not included for the node,
>
> Puppet does not exhibit this problem for me.  The only way I have been
> able to elicit a resource conflict error from Puppet is to have one
> node include two classes each declaring a resource of the same type
> and name.

I just had an additional thought about this one: are you putting all
your declarations into classes? Anything that is outside a class
definition is global, so if that file is parsed, such resources (and
variables, etc.) apply to all nodes.

Incidentally, please do not take this as a cue to attempt to influence
global declarations by controlling which files get parsed. You will
drive yourself nuts that way. For the most part, you should just put
everything into classes. There are some uses for global declarations,
but all the ones I can think of have these characteristics:

1) not harmful if applied when unneeded
2) certain to be parsed if needed

Resource parameter defaults can sometimes fall into this category, for
instance.


John

Alexandre

unread,
Dec 17, 2009, 10:08:51 PM12/17/09
to Puppet Users
Yes, in fact this is exactly what i have for the services -i want to
install or manage-. A base class with common stuff (eg mysql user,
group, pkg, test directories ... and service disabled by default), and
a child class ...::server with typically just include the service
specific config file and override Service[] to enable it

But this was not my original problem. Let's take an example :
1) i want to apply a general linux stripdown
2) i get a server, which had already stuff on it, maybe services
activated but not used, and on which sometimes people get on and
modify things (file permissions, start services, ...)
3) I want to apply the general stripdown to this server, without
having to know what is there and create a special stripdown just for
this server
4) I still want to install or activate services on this server, while
having the general stripdown still active

So far i can do 1), 2) and 3) with puppet, very simply. My problem is
4). All implementations of 4) i saw in this discussion say i have for
each node, specify exactly what i want to disable and enable, so that
if i have 100 nodes, i have to create 100 different stripdown.
While it is easy saying a node what it should include so that it
provides the needed services, it is big task and unmaintanable to
specify exhaustively what nodes should not include. Especially that
these nodes are used by some people that need some priviledges, but do
not always clean after work or are not sysadmins

> Comment: Using GnuPG with Mozilla -http://enigmail.mozdev.org

Alexandre

unread,
Dec 17, 2009, 10:19:34 PM12/17/09
to Puppet Users
it was because the case

$mysql_enabled = 1
class mysql::server {
service{mysqld: blablabla activate}
}

class stripdown{
if $mysql_enabled == 1 {
service{mysqld: blablabla deactivate}
}
}

node somenode {
include mysql::server
include stripdown
}

So you see in the case above, the parser will fail because service
[mysql] is included and defined twice (of course, since it is grammar
parser and not an AI ;-). But it would have worked if executed
( But i know the whole thing with variables is maybe a wrong
implementation of the problem )

Alexandre

unread,
Dec 17, 2009, 10:24:51 PM12/17/09
to Puppet Users
Yes, i try to be as modular and generic as possible. I do not put
anything global, every thing is either a class or a define, and
variables are usually only set in nodes, either as flags or to be used
in templates. The only exception are the global variables (eg
$_service_is_managed_mysqld=1) , which i described above but i removed
them because the whole thing is too convoluted and does not work
anyway.

Peter Meier

unread,
Dec 18, 2009, 5:02:30 AM12/18/09
to puppet...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

> it was because the case


>
> $mysql_enabled = 1
> class mysql::server {
> service{mysqld: blablabla activate}
> }
>
> class stripdown{
> if $mysql_enabled == 1 {
> service{mysqld: blablabla deactivate}
> }
> }
>
> node somenode {
> include mysql::server
> include stripdown
> }
>
> So you see in the case above, the parser will fail because service
> [mysql] is included and defined twice (of course, since it is grammar
> parser and not an AI ;-). But it would have worked if executed
> ( But i know the whole thing with variables is maybe a wrong
> implementation of the problem )

why don't you include a stripped down mysql class instead of defining
the service twice? I don't get it:

$mysql_enabled = 1

class mysql::stripdown {
service{mysqld: blablabla deactivate}
}

class mysql::server inherits mysql::stripdown{
Service[mysqld]{ blablabla activate}
}

class stripdown{
if $mysql_enabled == 1 {

include mysql::stripdown
}
}

node somenode {
include mysql::server
include stripdown
}

but I don't like this $mysql_enable at all, in your productive setup is
it a fact or do you set the variable?

cheers pete


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAksrUzMACgkQbwltcAfKi39/rQCcC9sRnnfrgmqH4uKAPZu1iYlh
bnMAn3tc2KsZDGgA9uWDBw3GrdwriYHy
=NuYW
-----END PGP SIGNATURE-----

jcbollinger

unread,
Dec 18, 2009, 9:39:22 AM12/18/09
to Puppet Users

On Dec 17, 9:19 pm, Alexandre <alexandre.fou...@gmail.com> wrote:
> it was because the  case
>
> $mysql_enabled = 1
> class mysql::server {
>     service{mysqld:   blablabla  activate}
>
> }
>
> class stripdown{
>     if $mysql_enabled == 1 {
>         service{mysqld:   blablabla  deactivate}
>     }
>
> }
>
> node somenode {
>     include mysql::server
>     include stripdown
>
> }
>
> So you see in the case above, the parser will fail because service
> [mysql] is included and defined twice (of course, since it is grammar
> parser and not an AI ;-). But it would have worked if executed
> ( But i know the whole thing with variables is maybe a wrong
> implementation of the problem )

I agree that variables are not likely constitute a viable approach to
solving this problem. I'm also not all that enthusiastic about the use
of a general stripdown, but that's a personal preference thing. Since
you seem to be intent on that manner of solution, have you tried
something along these lines:

class stripdown {
# turn off everything we care about managing
service { "mysqld": <deactivate> }
service { "apache": <deactivate> }
...
}

class mysql::server inherits stripdown {
Service ["mysqld"] { <activate> }
}

class apache::server inherits stripdown {
Service ["apache"] { <activate> }
}

node foo {
include stripdown
}

node bar {
include stripdown
include mysql::server
}

node baz {
include stripdown
include mysql::server
include apache::server
}

In other words, all your some_facility::server classes inherit from
the same general stripdown and override different (that's important)
resources. Each node then includes the stripdown and the service-
specific classes for those services it should run.

jcbollinger

unread,
Dec 18, 2009, 10:02:39 AM12/18/09
to Puppet Users

On Dec 17, 9:08 pm, Alexandre <alexandre.fou...@gmail.com> wrote:
> 4). All implementations of 4) i saw in this discussion say i have for
> each node, specify exactly what i want to disable and enable, so that
> if i have 100 nodes, i have to create 100 different stripdown.

I think the result is rather that if you have 100 different *services*
you want to manage via Puppet, then you need a stripdown for each
one. And any way around that's true; it's merely a question of
whether you put all those services' stripdowns in the same class or in
separate classes. You probably have a lot fewer than 100 services.

Personally, if I am interested in the mysql service, then for each
node I would prefer to see one of:

node foo {
include mysql::server
...
}

or

node foo {
include mysql::server::disabled
...
}

or maybe

node foo {
include mysql::server::absent
...
}

You prefer to not be explicit about the latter two cases, and that's
fine, but it doesn't change the number of different combinations of
services your various nodes offer.

> While it is easy saying a node what it should include so that it
> provides the needed services, it is big task and unmaintanable to
> specify exhaustively what nodes should not include.

How maintainable it is depends in part on how many distinct
configurations you need to manage. Do be aware that nodes that are
configured identically do not need separate entries in the node list:

node node1,
node2 {
include mysql::server
}

If you have more than a handful of distinct configurations, though,
then you might be well served by an external node classifier. That's
a program you provide that Puppet uses to dynamically determine which
classes should be included for each node.


John

Eric Gerlach

unread,
Dec 18, 2009, 10:55:19 AM12/18/09
to puppet...@googlegroups.com
I'd like to weigh in on this discussion a little bit.

First of all, Alexandre, you might feel more at home with bcfg2. Bcfg2 by
default manages *everything*, and tells you if something appears that is
unmanaged, forcing you to either manage it or remove it. We looked at bcfg2,
and whereas I liked its model, the puppet community is better, and bcfg2 uses
XML files for configuration *shudder*.

That is a feature I'd love to see in puppet. If unknown and new things appear
on one of my systems, I'd love to know about it. That way I can either decide
to add it to a manifest, or remove it.

That, to me, is better than applying a general stripdown. A general stripdown
(other than "remove everything not explicitly managed") doesn't deal with the
unknowns, and the "remove everything not explicitly managed" doesn't allow for
emergency fixes.

tl;dr: I want to know when *anything* on my system changes, puppet doesn't let
me do that.

Cheers,

Eric

> --
>
> You received this message because you are subscribed to the Google Groups "Puppet Users" group.
> To post to this group, send email to puppet...@googlegroups.com.
> To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
>
>

--
Eric Gerlach, Network Administrator
Federation of Students
University of Waterloo
p: (519) 888-4567 x36329
e: eger...@feds.uwaterloo.ca

Peter Meier

unread,
Dec 18, 2009, 11:05:39 AM12/18/09
to puppet...@googlegroups.com
> That is a feature I'd love to see in puppet. If unknown and new
> things appear
> on one of my systems, I'd love to know about it. That way I can
> either decide
> to add it to a manifest, or remove it.
> [...]

> tl;dr: I want to know when *anything* on my system changes, puppet
> doesn't let
> me do that.

Generally I like the idea, but I didn't yet think of it in every detail.

maybe it could be a bit more elaborated and then a feature request
could be filed?

cheers pete

Reply all
Reply to author
Forward
0 new messages