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

This issue tracker is now in read-only archive mode and automatic ticket export has been disabled. Redmine users will need to create a new JIRA account to file tickets using https://tickets.puppetlabs.com. See the following page for information on filing tickets with JIRA:

Bug #2423

Intermittent dependency cycle

Added by Alan Harder almost 7 years ago. Updated almost 7 years ago.

Status:ClosedStart date:07/18/2009
Priority:NormalDue date:
Assignee:Alan Harder% Done:

0%

Category:plumbing
Target version:0.25.0
Affected Puppet version:0.24.8 Branch:
Keywords:behaviorchange

We've Moved!

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


Description

I have a setup which fails with “Found dependency cycle” much of the time (about half? generally within 2-3 runs it’ll occur). Using 0.24.8 on Solaris 10. I’ve narrowed the code down to this:

class cc { notify { 'cc': } }

define util() {
  include cc
  exec { "util_$name": command => 'echo hoho', require => Class[cc] }
}

define job() {
  include cc
  exec { "job_$name": command => "echo foo", require => Class[cc] }
}

class app {
  util { 'test': }
  exec { 'app': command => 'echo hello', refreshonly => true, subscribe => Exec['util_test'] }
}

node 'myhost.foo.com' {
  include app
  job { 'blah': require => Class[app] }
}

I have a common component (“cc”) and two defines (“util” and “job”) that both use that common component. Then an application (“app”) that uses “util” and subscribes to an exec it has. Finally, I want to use “app” and “job”, but want “app” to be installed first.. so I make it require Class[app].

Here is the error when it fails: err: Could not apply complete catalog: Found dependency cycles in the following relationships: Notify[cc] => Exec[util_test], Exec[util_test] => Exec[app], Exec[util_test] => Notify[cc], Exec[app] => Notify[cc], Exec[util_test] => Exec[job_blah], Notify[cc] => Exec[job_blah], Exec[app] => Exec[job_blah]

And the full output:

debug: Creating default schedules
debug: Failed to load library 'ldap' for feature 'ldap'
debug: Failed to load library 'shadow' for feature 'libshadow'
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[ssl]/File[/etc/opt/csw/puppet/ssl/certs]: Autorequiring File[/etc/opt/csw/puppet/ssl]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[ssl]/File[/etc/opt/csw/puppet/ssl/private]: Autorequiring File[/etc/opt/csw/puppet/ssl]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[ssl]/File[/etc/opt/csw/puppet/ssl/private_keys]: Autorequiring File[/etc/opt/csw/puppet/ssl]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[ssl]/File[/etc/opt/csw/puppet/ssl/public_keys]: Autorequiring File[/etc/opt/csw/puppet/ssl]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[main]/File[/var/opt/csw/puppet/log]: Autorequiring File[/var/opt/csw/puppet]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[ssl]/File[/etc/opt/csw/puppet/ssl/csr_gssie-210-6-z2.nis-86.central.sun.com.pem]: Autorequiring File[/etc/opt/csw/puppet/ssl]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[main]/File[/var/opt/csw/puppet/lib]: Autorequiring File[/var/opt/csw/puppet]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[main]/File[/var/opt/csw/puppet/run]: Autorequiring File[/var/opt/csw/puppet]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[ssl]/File[/etc/opt/csw/puppet/ssl/certs/gssie-210-6-z2.nis-86.central.sun.com.pem]: Autorequiring File[/etc/opt/csw/puppet/ssl/certs]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[ssl]/File[/etc/opt/csw/puppet/ssl/certs/ca.pem]: Autorequiring File[/etc/opt/csw/puppet/ssl/certs]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[ssl]/File[/etc/opt/csw/puppet/ssl/public_keys/gssie-210-6-z2.nis-86.central.sun.com.pem]: Autorequiring File[/etc/opt/csw/puppet/ssl/public_keys]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[puppetd]/File[/etc/opt/csw/puppet/puppet.conf]: Autorequiring File[/etc/opt/csw/puppet]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[main]/File[/var/opt/csw/puppet/state]: Autorequiring File[/var/opt/csw/puppet]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[main]/File[/etc/opt/csw/puppet/ssl]: Autorequiring File[/etc/opt/csw/puppet]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[ssl]/File[/etc/opt/csw/puppet/ssl/private_keys/gssie-210-6-z2.nis-86.central.sun.com.pem]: Autorequiring File[/etc/opt/csw/puppet/ssl/private_keys]
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[main]/File[/var/opt/csw/puppet/state]: File does not exist
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[main]/File[/var/opt/csw/puppet/state]: Changing ensure
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[main]/File[/var/opt/csw/puppet/state]: 1 change(s)
debug: /Settings[/etc//opt/csw/puppet/puppet.conf]/Settings[main]/File[/var/opt/csw/puppet/state]/ensure: created
debug: Finishing transaction 2125824 with 1 changes
debug: Retrieved facts in 1.19 seconds
debug: Retrieving catalog
debug: Calling puppetmaster.getconfig
debug: Retrieved catalog in 0.75 seconds
debug: Puppet::Network::Client::File: defining fileserver.describe
debug: Puppet::Network::Client::File: defining fileserver.list
debug: Puppet::Network::Client::File: defining fileserver.retrieve
debug: Creating default schedules
debug: Finishing transaction 9337776 with 0 changes
info: Caching catalog at /var//opt/csw/puppet/state/localconfig.yaml
notice: Starting catalog run
debug: //Node[gssie-210-6-z2.nis-86.central.sun.com]/app/Util[test]/Exec[util_test]/require: requires Class[cc]
debug: //Node[gssie-210-6-z2.nis-86.central.sun.com]/app/Exec[app]/subscribe: subscribes to Exec[util_test]
debug: //Node[gssie-210-6-z2.nis-86.central.sun.com]/Job[blah]/cc/Notify[cc]/require: requires Class[app]
debug: //Node[gssie-210-6-z2.nis-86.central.sun.com]/Job[blah]/Exec[job_blah]/require: requires Class[cc]
debug: //Node[gssie-210-6-z2.nis-86.central.sun.com]/Job[blah]/Exec[job_blah]/require: requires Class[app]
err: Could not apply complete catalog: Found dependency cycles in the following relationships: Notify[cc] => Exec[util_test], Exec[util_test] => Exec[app], Exec[util_test] => Notify[cc], Exec[app] => Notify[cc], Exec[util_test] => Exec[job_blah], Notify[cc] => Exec[job_blah], Exec[app] => Exec[job_blah]
debug: Storing state
info: Creating state file /var//opt/csw/puppet/state/state.yaml
debug: Stored state in 0.04 seconds
debug: Calling puppetreports.report
info: Sent transaction report in 0.27 seconds
notice: Finished catalog run in 0.44 seconds

Maybe this is a “will not fix” case if I’m using require improperly somewhere.. but it seems like it should be able to do everything “app” needs, and when “job” is processed it’ll just find that Class[cc] is already done.


Related issues

Related to Puppet - Bug #8040: Classes should be able to contain other classes to provid... Closed 06/22/2011

History

#1 Updated by Luke Kanies almost 7 years ago

  • Status changed from Unreviewed to Needs More Information

I ran into this problem before with a customer, and we have it fixed in 0.25.

I’ve tried with no luck to find record of the conversation, but it was essentially something related class relationships and ordering. I think if you move the ‘job’ line above the ‘include’ line, you’ll stop getting the loop.

#2 Updated by Alan Harder almost 7 years ago

I still see the error with job/include lines swapped.. I’ll test now with 0.25.0-beta2 and report back.

#3 Updated by Alan Harder almost 7 years ago

With 0.25.0beta2 it does seem to work with the code I posted above (15 runs with no error anyway). Though for curiosity I tried with the include/job reversed and then I get the error every time (6 in a row anyway).. here is the error:

err: Could not apply complete catalog: Found dependency cycles in the following relationships: Exec[util_test] => Exec[app], Notify[cc] => Exec[util_test], Exec[app] => Exec[job_blah], Exec[util_test] => Exec[job_blah], Notify[cc] => Exec[job_blah], Exec[app] => Notify[cc], Exec[util_test] => Notify[cc]

Since my original code works, I think it’s ok to close this bug.. unless you choose to keep it open for the reversed case. Thanks.

#4 Updated by Luke Kanies almost 7 years ago

  • Category changed from server to plumbing
  • Status changed from Needs More Information to Needs Decision
  • Assignee set to Luke Kanies
  • Target version set to 0.25.0

I found it. The problem is a result of the fact that the ‘include’ function attaches classes at the point of inclusion, rather than at the top-level. This means that the first class to call ‘include’ adds an edge to the graph.

Try moving your ‘include cc’ upward in the graph.

But I’ll investigate whether this is fixable.

#5 Updated by Luke Kanies almost 7 years ago

  • Status changed from Needs Decision to In Topic Branch Pending Review
  • Assignee changed from Luke Kanies to Alan Harder

I’ve just pushed a fix to the tickets/master/2423 branch in my repo.

This is a bit of an esoteric fix, but it works for me.

#6 Updated by Luke Kanies almost 7 years ago

  • Keywords set to behaviorchange

#7 Updated by James Turnbull almost 7 years ago

Luke – how does the behaviour change? Can you cite some examples so I can better document it? Thanks

#8 Updated by Luke Kanies almost 7 years ago

The behaviour change is a bit hard to explain. If you’ve got a class structure like the following:

class one {
  ...
}
class two {
  include one
  ...
}
class three {
  notify { three: require => Class[two] }
}
include two, three

In the old behaviour, we make an edge between one and two because of the ‘include’, so our dependency between two and three gets extended to be a dependency between the ‘three’ notify and all of the resources in ‘one’.

In the new behaviour, the edge between one and two doesn’t get created, so you don’t get any dependency between three and one.

Clear enough? :)

#9 Updated by James Turnbull almost 7 years ago

  • Category changed from plumbing to documentation

#10 Updated by James Turnbull almost 7 years ago

  • Category changed from documentation to plumbing

#11 Updated by Brice Figureau almost 7 years ago

Luke Kanies wrote:

The behaviour change is a bit hard to explain. If you’ve got a class structure like the following: […] In the old behaviour, we make an edge between one and two because of the ‘include’, so our dependency between two and three gets extended to be a dependency between the ‘three’ notify and all of the resources in ‘one’.

In the new behaviour, the edge between one and two doesn’t get created, so you don’t get any dependency between three and one.

and to get the new behavior:

class two {
  require one
  ...
}

should do it.

#12 Updated by Luke Kanies almost 7 years ago

  • Status changed from In Topic Branch Pending Review to Ready For Checkin

I’m pretty comfortable with this being merged.

#13 Updated by James Turnbull almost 7 years ago

  • Status changed from Ready For Checkin to Closed

Pushed in commit:eeec8e99eaeb6bb97173f2bc04148bff3be58036 in branch master.

Also available in: Atom PDF