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

Bug #14518

Autorequire can create circular dependencies when ensure => absent

Added by Josh Cooper almost 2 years ago. Updated 5 months ago.

Status:AcceptedStart date:05/15/2012
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:-
Target version:-
Affected Puppet version:2.7.14 Branch:
Keywords:autorequire circular dependencies

We've Moved!

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

This ticket may be automatically exported to the PUP project on JIRA using the button below:


Description

The registry_key auto-require functionality doesn’t appear to work with -> style relationships when ensure => absent. This results in a circular dependency:

    Registry_key { ensure => absent }
    registry_key { '#{keypath}\\SubKey1': }
    -> registry_key { '#{keypath}\\SubKeyToPurge': }
    -> registry_key { '#{keypath}': }

But this does not:

    registry_key { '#{keypath}\\SubKey1': }
    registry_key { '#{keypath}\\SubKeyToPurge': }
    registry_key { '#{keypath}':
      require => Registry_key['#{keypath}\\SubKeyToPurge', '#{keypath}\\SubKey1'],
    }

Related issues

Related to Puppet - Bug #13617: User/Group auto-relationships not be present when ensure ... Accepted 04/04/2012
Related to Puppet - Bug #7422: undefined method `<<' for {}:Hash when combining resource... Closed 05/05/2011
Related to Puppet - Bug #4806: file-resource: useless autorequire Requires CLA to be signed 09/20/2010

History

#1 Updated by Josh Cooper almost 2 years ago

  • Project changed from 57 to Puppet
  • Target version deleted (276)

#2 Updated by Josh Cooper almost 2 years ago

  • Subject changed from Registry - Autorequire can create circular dependencies when ensure => absent to Autorequire can create circular dependencies when ensure => absent
  • Assignee deleted (Josh Cooper)
  • Affected Puppet version set to 2.7.14
  • Keywords changed from registry autorequire to autorequire circular dependencies

This turns out to not be a registry issue, it’s a general issue with autorequiring and the -> syntax. It is likely a duplicate of another issue…

This manifest attempts to delete two child directories, then the parent directory. It doesn’t actually delete them, because force is not set, but it illustrates that puppet does attempt to delete them in the right order:

File { ensure => absent }
file { '/tmp/a': }
file { '/tmp/a/b1': }
  -> File['/tmp/a']
file { '/tmp/a/b2': }
  -> File['/tmp/a']

Results in:

debug: /Stage[main]//File[/tmp/a/b2]/before: requires File[/tmp/a]
debug: /Stage[main]//File[/tmp/a/b1]/before: requires File[/tmp/a]
debug: /Stage[main]//File[/tmp/a/b2]: Skipping automatic relationship with File[/tmp/a]
debug: /Stage[main]//File[/tmp/a/b1]: Skipping automatic relationship with File[/tmp/a]
notice: /Stage[main]//File[/tmp/a/b1]: Not removing directory; use 'force' to override
notice: /Stage[main]//File[/tmp/a/b1]/ensure: removed
notice: /Stage[main]//File[/tmp/a/b2]: Not removing directory; use 'force' to override
notice: /Stage[main]//File[/tmp/a/b2]/ensure: removed
notice: /Stage[main]//File[/tmp/a]: Not removing directory; use 'force' to override
notice: /Stage[main]//File[/tmp/a]/ensure: removed

However, if the dependencies are expressed as follows (delete b1, b2, then the parent):

File { ensure => absent }
file { '/tmp/a/b1': }
 -> file { '/tmp/a/b2': }
 -> file { '/tmp/a': }

It creates a circular dependency:

debug: /Stage[main]//File[/tmp/a/b1]/before: requires File[/tmp/a/b2]
debug: /Stage[main]//File[/tmp/a/b2]/before: requires File[/tmp/a]
debug: /Stage[main]//File[/tmp/a/b1]: Autorequiring File[/tmp/a]
debug: /Stage[main]//File[/tmp/a/b2]: Skipping automatic relationship with File[/tmp/a]
err: Could not apply complete catalog: Found 1 dependency cycle:
(File[/tmp/a/b1] => File[/tmp/a/b2] => File[/tmp/a] => File[/tmp/a/b1])

The circular dependency occurs because /tmp/a/b1 should not have autorequired /tmp/a

On a general note, autorequiring generates dependency edges in the ensure => present direction. I’m thinking puppet should always ignore autorequiring when ensure => absent, or it should flip the dependency direction. For example, for files, it would ensure the child file/dir is deleted before its parent.

I think flipping the direction is preferrable. The file type autorequire already generates the correct dependency for both present and absent, it’s just the wrong direction for absent. Also, it’s strange that manifest authors have to define dependency edges in the ensure => absent case, but not ensure => present. For example, it would be nice to be able to do:

File { ensure => absent }
file { '/tmp/a/b1': }
file { '/tmp/a/b2': }
file { '/tmp/a': }

And have puppet do the right thing. But it doesn’t, since the autorequired dependencies are backwards:

debug: /Stage[main]//File[/tmp/a/b2]: Autorequiring File[/tmp/a]
debug: /Stage[main]//File[/tmp/a/b1]: Autorequiring File[/tmp/a]
notice: /Stage[main]//File[/tmp/a]: Not removing directory; use 'force' to override
notice: /Stage[main]//File[/tmp/a]/ensure: removed
notice: /Stage[main]//File[/tmp/a/b1]: Not removing directory; use 'force' to override
notice: /Stage[main]//File[/tmp/a/b1]/ensure: removed
notice: /Stage[main]//File[/tmp/a/b2]: Not removing directory; use 'force' to override
notice: /Stage[main]//File[/tmp/a/b2]/ensure: removed

Also available in: Atom PDF