Ricardo Bartolome Mendez
2011-Aug-25 19:52 UTC
[Puppet Users] Unexpected behavior using class inheritance and run stages
Hello guys, I use stages for defining a kind of order about how the things are done in my automations. I’ve defined four different stages: boot, os, service and online. We also have Main stage. The issue I found today may be derived from a incorrect usage of class inheritance, or run stages. Let me show you an example: We use rsyslog for both systems logging and application logging. So, depending of the facilities and so on, we transport operating systems logs to a syslog receiver, or stats to a data analysis cluster. So, given that is the same piece of software I decided to create a module called “rsyslog” and inside init.pp describe all the necessary stuff for having the operating systems syslog configured, what is a must in any of my nodes. I also defined inside stats.pp a new class named “rsyslog::stats” that inherits rsyslog. So, then, in my node class named “frontend” where I need both configurations I define the rsyslog class it in this way: include stages class { ‘rsyslog::stats’: stage => ‘os’ } But today I found (using debug option) that the things explicitly defined in “rsyslog::stats” are done in the stage “os”, but the things defined in the class “rsyslog” are done in Main [1]. What I expect? I expect that given that “rsyslog::stats” was defined in the Stage “os”, the inherited one, too. I’ve fixed this by defining the class in the node like: include stages class { ‘rsyslog’: stage => ‘os’ } class { ‘rsyslog::stats’: stage => ‘os’ } But this means repeating lines and it’s quite ugly. I don’t know if that’s the proper way of doing what I’m doing. I’m using class inheritance because there are servers that are running rsyslog for systems logs, but they don’t need the stats configuration (a database server, for example), so including just “rsyslog” class and defining its run stage should be enough. Any idea how to get rid of this behavior? I’m using Puppet 2.6.3, and I know it’s quite old, but I haven’t found any information regarding to this, or any bug already reported. Potentially, I’m not searching for the correct words, but anyways, other ideas about how to accomplish with that modular configuration are welcome. Regards, [1] debug: /Stage[main]/Rsyslog/File[/etc/default/rsyslog]/notify: subscribes to Service[rsyslog] debug: /Stage[main]/Rsyslog/Service[rsyslog]/require: requires Package[rsyslog] debug: /Stage[main]/Rsyslog/Service[rsyslog]/require: requires File[/etc/rsyslog.conf] debug: /Stage[main]/Rsyslog/File[/etc/default/rsyslog]: Autorequiring User[root] debug: /Stage[main]/Rsyslog/File[/etc/rsyslog.conf]: Autorequiring User[root] -- Ricardo Bartolomé Méndez Systems Engineer +34.672.194.729 tuenti.com -- 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2011-Aug-25 22:13 UTC
[Puppet Users] Re: Unexpected behavior using class inheritance and run stages
On Aug 25, 2:52 pm, Ricardo Bartolome Mendez <rica...@tuenti.com> wrote:> Hello guys, > > I use stages for defining a kind of order about how the things are done in > my automations. I’ve defined four different stages: boot, os, service and > online. We also have Main stage. The issue I found today may be derived from > a incorrect usage of class inheritance, or run stages. Let me show you an > example: > > We use rsyslog for both systems logging and application logging. So, > depending of the facilities and so on, we transport operating systems logs > to a syslog receiver, or stats to a data analysis cluster. So, given that is > the same piece of software I decided to create a module called “rsyslog” and > inside init.pp describe all the necessary stuff for having the operating > systems syslog configured, what is a must in any of my nodes. I also defined > inside stats.pp a new class named “rsyslog::stats” that inherits rsyslog.It''s not clear that this is a good use case for class inheritance. Does Class[''rsyslog::stats''] override the properties of any resources inherited from Class[''rsyslog'']? From your description, it''s not obvious that it would need to do. If indeed it doesn''t, then you are using inheritance where you should instead be aggregating (more on that below).> So, then, in my node class named “frontend” where I need both configurations > I define the rsyslog class it in this way: > > include stages > > class { ‘rsyslog::stats’: stage => ‘os’ } > > But today I found (using debug option) that the things explicitly defined in > “rsyslog::stats” are done in the stage “os”, but the things defined in the > class “rsyslog” are done in Main [1]. What I expect? I expect that given > that “rsyslog::stats” was defined in the Stage “os”, the inherited one, too.I would not have anticipated that result either, but in hindsight I don''t find it altogether surprising. That doesn''t mean you shouldn''t file a ticket about it, though. Or it wouldn''t, but it looks like there are already at least three separate tickets describing this issue (5349, 6019, 7533). An important question arises at this point: is this something you actually need to fix? I mean, was anything actually breaking? If not, then you should consider just ignoring the issue.> I’ve fixed this by defining the class in the node like: > > include stages > > class { ‘rsyslog’: stage => ‘os’ } > > class { ‘rsyslog::stats’: stage => ‘os’ } > > But this means repeating lines and it’s quite ugly.I think that''s your best alternative at the moment. Also, although the need to do that is a bit surprising, it makes a certain amount of sense if you look at it from the right angle. For one thing, it''s valid to do that in the first place. For another, it is possible to do that and specify different stages for base- and subclass. For a third, consider what would happen if you wanted to put two different subclasses of the same class into different stages. Moreover, if the stats collection is in addition to rsyslog reporting, as opposed to being a modified form of the same, then I think the form you found is what you should have been doing all along. In that case, the fact that stats collection relies on rsyslog is better modeled via an ordinary relationship than via class inheritance. That might even allow you to make some of Class[''rsyslog:stats''] implementation a little cleaner, depending on what resource-level relationships you may have declared.> I don’t know if that’s > the proper way of doing what I’m doing. I’m using class inheritance because > there are servers that are running rsyslog for systems logs, but they don’t > need the stats configuration (a database server, for example), so including > just “rsyslog” class and defining its run stage should be enough.I agree that it''s good form for your Class[''rsyslog''] to not contain the stats stuff itself. I''m still doubtful, however, that it''s appropriate to make Class[''rsyslog::stats''] a subclass. As a bonus, if you make it a top-level class then maybe you won''t be so dissatisfied about declaring both classes in your node class. 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Ricardo Bartolome Mendez
2011-Aug-26 08:33 UTC
RE: [Puppet Users] Re: Unexpected behavior using class inheritance and run stages
Hello John, Class rsyslog::stats does not override any definition already declared in rsyslog, reason because I was not sure of doing a correct usage of class inheritance. rsyslog was the simpler example, but I have a module was suffering a serious problem of order (it''s related to production code and config retrieval, which is executed after all the related services are ready). The tickets #6019 and #7533 are related with the issue I''m facing at the moment, so I''ll follow them up. It''ll be potentially fixed/changed on 2.7.x branch, which I have planned to upgrade very soon. Thanks for pointing me out in the correct direction. Regards, -----Mensaje original----- De: puppet-users@googlegroups.com [mailto:puppet-users@googlegroups.com] En nombre de jcbollinger Enviado el: viernes, 26 de agosto de 2011 0:13 Para: Puppet Users Asunto: [Puppet Users] Re: Unexpected behavior using class inheritance and run stages On Aug 25, 2:52 pm, Ricardo Bartolome Mendez <rica...@tuenti.com> wrote:> Hello guys, > > I use stages for defining a kind of order about how the things are done in > my automations. I’ve defined four different stages: boot, os, service and > online. We also have Main stage. The issue I found today may be derived > from > a incorrect usage of class inheritance, or run stages. Let me show you an > example: > > We use rsyslog for both systems logging and application logging. So, > depending of the facilities and so on, we transport operating systems logs > to a syslog receiver, or stats to a data analysis cluster. So, given that > is > the same piece of software I decided to create a module called “rsyslog” > and > inside init.pp describe all the necessary stuff for having the operating > systems syslog configured, what is a must in any of my nodes. I also > defined > inside stats.pp a new class named “rsyslog::stats” that inherits rsyslog.It''s not clear that this is a good use case for class inheritance. Does Class[''rsyslog::stats''] override the properties of any resources inherited from Class[''rsyslog'']? From your description, it''s not obvious that it would need to do. If indeed it doesn''t, then you are using inheritance where you should instead be aggregating (more on that below).> So, then, in my node class named “frontend” where I need both > configurations > I define the rsyslog class it in this way: > > include stages > > class { ‘rsyslog::stats’: stage => ‘os’ } > > But today I found (using debug option) that the things explicitly defined > in > “rsyslog::stats” are done in the stage “os”, but the things defined in > the > class “rsyslog” are done in Main [1]. What I expect? I expect that given > that “rsyslog::stats” was defined in the Stage “os”, the inherited one, > too.I would not have anticipated that result either, but in hindsight I don''t find it altogether surprising. That doesn''t mean you shouldn''t file a ticket about it, though. Or it wouldn''t, but it looks like there are already at least three separate tickets describing this issue (5349, 6019, 7533). An important question arises at this point: is this something you actually need to fix? I mean, was anything actually breaking? If not, then you should consider just ignoring the issue.> I’ve fixed this by defining the class in the node like: > > include stages > > class { ‘rsyslog’: stage => ‘os’ } > > class { ‘rsyslog::stats’: stage => ‘os’ } > > But this means repeating lines and it’s quite ugly.I think that''s your best alternative at the moment. Also, although the need to do that is a bit surprising, it makes a certain amount of sense if you look at it from the right angle. For one thing, it''s valid to do that in the first place. For another, it is possible to do that and specify different stages for base- and subclass. For a third, consider what would happen if you wanted to put two different subclasses of the same class into different stages. Moreover, if the stats collection is in addition to rsyslog reporting, as opposed to being a modified form of the same, then I think the form you found is what you should have been doing all along. In that case, the fact that stats collection relies on rsyslog is better modeled via an ordinary relationship than via class inheritance. That might even allow you to make some of Class[''rsyslog:stats''] implementation a little cleaner, depending on what resource-level relationships you may have declared.> I don’t know if that’s > the proper way of doing what I’m doing. I’m using class inheritance > because > there are servers that are running rsyslog for systems logs, but they don’t > need the stats configuration (a database server, for example), so > including > just “rsyslog” class and defining its run stage should be enough.I agree that it''s good form for your Class[''rsyslog''] to not contain the stats stuff itself. I''m still doubtful, however, that it''s appropriate to make Class[''rsyslog::stats''] a subclass. As a bonus, if you make it a top-level class then maybe you won''t be so dissatisfied about declaring both classes in your node class. 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en. -- 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.