The Puppet Labs Issue Tracker has Moved: https://tickets.puppetlabs.com

Bug #5349

Class inheritance and stages act weirdly

Added by R.I. Pienaar about 4 years ago. Updated about 1 year ago.

Status:AcceptedStart date:11/18/2010
Priority:UrgentDue date:
Assignee:-% Done:

0%

Category:-
Target version:3.x
Affected Puppet version:2.6.3 Branch:
Keywords:

We've Moved!

Ticket tracking is now hosted in JIRA: https://tickets.puppetlabs.com

This ticket is now tracked at: https://tickets.puppetlabs.com/browse/PUP-1108


Description

Given the code:

stage { "first": before => Stage[main] }

class foo { 
   package{"zsh": 
      ensure => present
   } 
}

class bar inherits foo { 
   notify{"/usr/bin/cowsay 'hello world'": 
      require => Package["zsh"] 
   } 
}

class{"bar": stage => "first"}

This produce

err: Could not apply complete catalog: Found dependency cycles in the following relationships: Package[zsh] => Notify[/usr/bin/cowsay 'hello world'], Notify[/usr/bin/cowsay 'hello world'] => Package[zsh], Notify[/usr/bin/cowsay 'hello world'] => Class[main]; try using the '--graph' option and open the '.dot' files in OmniGraffle or GraphViz

If I add:

class{"foo": stage => "first"}

It sorts itself out.

I am not sure what the correct behavior would be, at first I think we should just pull the inherited class into the ‘first’ stage as well but I can imagine that causing weird issues too?


Related issues

Related to Puppet - Bug #8702: "including" 2 inherited classes via class resource syntax... Duplicate 07/29/2011
Duplicated by Puppet - Bug #7533: subclass stage doesn't apply to baseclass Duplicate 05/16/2011
Duplicated by Puppet - Bug #6019: Subclasses don't inherit run stage correctly? Duplicate 01/26/2011

History

#1 Updated by Nigel Kersten about 4 years ago

  • Status changed from Unreviewed to Needs Decision
  • Assignee set to Nigel Kersten

you always bring us the curly problems RI….

I’m happy to get more feedback from people as to what the correct behavior should be. I’m still not sure myself.

#2 Updated by Brent Jones almost 4 years ago

I can confirm this does happen. When creating a class, and a sub class with inherit defined in a stage outside of Main, it seems to create a looping dependency cycle.

I’ve worked around it by not using inherits in my classes which are to be defined in another stage.

#3 Updated by Dan Bode over 3 years ago

I have seen the same problem with composite classes. I think that stages should follow all resources (including classes through inclusion)

My use case is something like:

class apt {
  notify { 'I love apt!': }
}
define apt::source (

) {
  class { apt :}
  notify { "Creating my repo #{name}":
    require => Class['apt']
  }
}
class my::repo {
  apt::source { 'myrepo': }
}
stage { 'pre':
  before => Stage['main']
}
class { 'my::repo':
  stage => 'pre'
}

:!puppet apply /private/tmp/foo.pp --noop
err: Could not apply complete catalog: Found 1 dependency cycle:
(Stage[main] => Class[Apt] => Notify[I love apt!] => Class[Apt] => Apt::Source[myrepo] => Notify[Creating my repo #{name}] => Apt::Source[myrepo] => Class[My::Repo] => Stage[pre] => Stage[main])
Try the '--graph' option and opening the resulting '.dot' file in OmniGraffle or GraphViz
notice: Finished catalog run in 0.03 seconds

I know that the practice of including a class from a define may be a bad style(according to the recommended 2.6 styles), but it is a pervasive pattern. I will basically have to fork someones module b/c of this.

#4 Updated by Steve Snodgrass over 3 years ago

I think I just ran into this problem too. My case is similar to Dan’s – I’m just trying to get my yum repos to install before everything else, but I’m doing it in a base class that all my nodes inherit. Example:

stage { 'pre':
    before => Stage['main'],
}
node base {
    class { 'yum::repos': stage => 'pre' }
    include ssh
    ...more junk elided...
}
node foobar inherits base {
    ...
}

This generates a huge dependency cycle. :(

#5 Updated by Steve Snodgrass over 3 years ago

One more update, this bug doesn’t even require inheritance, it happens even if you include another class that contains a class using the “pre” stage. This should definitely be fixed so that the class always runs in its designated stage no matter how it was included.

#6 Updated by Steve Snodgrass over 3 years ago

Sigh… now I feel sheepish. After more troubleshooting I found the real cause of the problem. In another class that was not in the pre stage I set the password for the root user, and it turns out that files installed by my yum::repos module have an implicit dependency on root as the file owner. But the cycle error that puppet output was so huge I couldn’t figure out what was going on without lots of trial and error. Once I moved my user::root module to the pre stage all was well again, even with the node inheritance. Sorry about the noise.

#7 Updated by Nigel Kersten over 3 years ago

No worries. On the plus side, we’ve immensely improved the cycle detection in 2.7 so it only shows you relevant information, and with the —graph option we produce a cycle graph for you so you can debug visually.

#8 Updated by Nigel Kersten over 3 years ago

I think I’m leaning towards us pulling the parent class into the stage if undefined.

Does it also seem reasonable to throw an error if you attempt to set a parent and child class to have two different stages explicitly?

#9 Updated by Peter Meier over 3 years ago

Nigel Kersten wrote:

I think I’m leaning towards us pulling the parent class into the stage if undefined.

yes, I would favor that. The current behavior prevents the usage of stages in a lot of cases and is quite nasty… :/ So getting here some priority might also be nice…

Does it also seem reasonable to throw an error if you attempt to set a parent and child class to have two different stages explicitly?

Yes.

#10 Updated by Nigel Kersten over 3 years ago

Ok. At this stage (no pun intended!) we’re going to proceed with the following plan:

  • Pull the parent class into the current stage if it has no stage defined.
  • In the case of class inheritance, throw an error if a parent and child class are assigned to two different stages.

Thanks for the feedback Peter, but just to make sure we’re coping with actual use cases, I would love feedback from RI and Dan as to whether this plan works for their cases.

#11 Updated by R.I. Pienaar over 3 years ago

Thanks for the feedback Peter, but just to make sure we’re coping with actual use cases, I would love feedback from RI and Dan as to whether this plan works for their cases.

works for me, I mostly avoid stages in favor of chaining at this point.

#12 Updated by Nigel Kersten over 3 years ago

  • Status changed from Needs Decision to Accepted
  • Priority changed from Normal to Urgent
  • Target version set to 3.x

#13 Updated by Nigel Kersten over 3 years ago

  • Assignee deleted (Nigel Kersten)

#14 Updated by R.I. Pienaar about 1 year ago

Redmine Issue #5349 has been migrated to JIRA:

https://tickets.puppetlabs.com/browse/PUP-1108

Also available in: Atom PDF