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 #7486

Service refreshed despite failed dependencies

Added by John Florian almost 5 years ago. Updated almost 3 years ago.

Status:Needs DecisionStart date:05/11/2011
Priority:NormalDue date:
Assignee:eric sorenson% Done:

0%

Category:-
Target version:-
Affected Puppet version:0.25.5 Branch:
Keywords:

We've Moved!

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


Description

In the following manifest, I would expect the service to not be restarted if either File results in a failure, however that’s not the case:

# dependency-test.pp

file { "/tmp/test/xyz/A":
    content     => 'file A',
}

file { "/tmp/test/B":
    content     => 'file B',
}

service { "crond":
    enable      => true,
    ensure      => running,
    hasrestart  => true,
    hasstatus   => true,
    require     => [
        File['/tmp/test/xyz/A'],
    ],
    subscribe   => [
        File['/tmp/test/B'],
    ],
}

Here’s the results I get:

# cd /tmp; rm -rf test; mkdir test
# service crond status; puppet -v dependency-test.pp; service crond status
crond (pid  28753) is running...
info: Applying configuration version '1305125236'
err: //File[/tmp/test/xyz/A]/content: change from absent to {md5}31d97c4d04593b21b399ace73b061c34 failed: No such file or directory - /tmp/test/xyz/A.puppettmp_7091
notice: //File[/tmp/test/B]/content: defined content as 'unknown checksum'
info: //File[/tmp/test/B]: Scheduling refresh of Service[crond]
notice: //Service[crond]: Dependency file[/tmp/test/xyz/A] has 1 failures
warning: //Service[crond]: Skipping because of failed dependencies
notice: //Service[crond]: Triggering 'refresh' from 1 dependencies
crond (pid  28937) is running...
# puppet --version
0.25.5

File A’s failure (because subdir xyz doesn’t exist) is intentional here to demonstrate how the service gets restarted despite all dependencies not being satisfied. My understanding is that subscribe implies a depenency. However, I even tried adding File B to the require clause and got the exact same results, the service was started because File B sent a notify (as it should) and puppet ignored the failed dependency for File A (as it should not).

I have an application in which the service absolutely must not start unless all dependencies are satisfied.

This may be related to #5876.


Related issues

Related to Puppet - Bug #5876: Require and Subscribe on the same refreshonly exec doesnt... Needs More Information 01/13/2011

History

#1 Updated by John Florian almost 5 years ago

John Florian wrote:

However, I even tried adding File B to the require clause and got the exact same results, the service was started because File B sent a notify (as it should) and puppet ignored the failed dependency for File A (as it should not).

Sorry, this text matches a earlier variant of this test, which was unnecessarily complex. Instead, I should have stated:

The service is (re)started because File B sends a notify (as it should) and
puppet ignores the failed dependency for File A (as it should not).

#2 Updated by Nigel Kersten almost 5 years ago

  • Priority changed from Urgent to Normal

This is actually by design unfortunately.

When a resource requires another (failed) resource, it is marked as “skipped”. When a resource subscribes (or is notified by) a (successful) resource, the event that is sent at that point triggers the refresh action on the original resource.

It’s not really “ignoring the failed dependency”, it’s actually doing something different, which is to issue a refresh, which for a service by default will stop and start the service. This is a different thing to “ensure this service is running”.

I do think this is problematic. It does violate the principle of least surprise, but we’re not clear on what semantics we need to add/modify in order to get to a better place. Suggestions welcome… but I’m planning to try to get community feedback in the near future so that we can make the required changes for Telly.

Does that make sense at least?

#3 Updated by John Florian almost 5 years ago

If that’s true, then I think the design is unfortunately flawed. What value do the dependencies provide us then? I believe that only execution order remains of value and if so, puppet’s promise of being declarative is largely devalued.

Having used puppet for a couple years now, I was totally surprised to only now uncover this behavior, but even more surprised to hear it described as “by design”.

If execution order is the only criteria, the “before” meta-parameter is appropriate. However, if a declared state is the criteria, “require” would be appropriate. What we presently have greatly weakens effective expressiveness in the DSL.

#4 Updated by James Turnbull almost 5 years ago

I think we’re agreeing the design is flawed. :) Do you have a view on how it should look?

#5 Updated by James Turnbull almost 5 years ago

  • Status changed from Unreviewed to Needs Decision

#6 Updated by Nigel Kersten almost 5 years ago

  • Assignee set to Nigel Kersten

John Florian wrote:

If execution order is the only criteria, the “before” meta-parameter is appropriate. However, if a declared state is the criteria, “require” would be appropriate. What we presently have greatly weakens effective expressiveness in the DSL.

The choice of the word “require” is part of the problem. Really the semantics are more like “If this other resource is going to be evaluated, then make sure it is evaluated before I am”.

The way tags work illustrate this. If Resource A requires Resource B, A is tagged “foo”, B is not, and you run with “—tags=foo”, A is still evaluated, even though B isn’t.

To bring this back to your problem, I’m worried we have people relying upon the existing behavior, and that if we made a change such that a resource with failed dependencies doesn’t respond to any events sent to it, this might be undesirable for them.

This is why we’re going to take this to the community. I’ll get onto that soon.

#7 Updated by John Florian almost 5 years ago

James Turnbull wrote:

I think we’re agreeing the design is flawed. :) Do you have a view on how it should look?

Absolutely, having made a large commitment to it in our technology plans, I need to make it work to rigorous standards. I’ve seen comments like:

While the holy grail is for all resources to apply correctly in a single Puppet run, it isn't always simple to achieve this; ask yourself if it really matters if it takes two runs to get the desired configuration. http://plathrop.tertiusfamily.net/puppet/best-practice-draft.html

I generally don’t have such luxuries. I need puppet to bring about a certain state on a platform the first time, every time. By count, most of the nodes I manage are stateless Linux systems (where all state is lost at shutdown/reboot). These nodes are power-cycled frequently, so you might say I’m perpetually running unit tests. :–)

So give me a bit and I’ll be back with a vision.

#8 Updated by Nigel Kersten almost 5 years ago

John Florian wrote:

James Turnbull wrote:

I think we’re agreeing the design is flawed. :) Do you have a view on how it should look?

Absolutely, having made a large commitment to it in our technology plans, I need to make it work to rigorous standards. I’ve seen comments like:

While the holy grail is for all resources to apply correctly in a single Puppet run, it isn’t always simple to achieve this; ask yourself if it really matters if it takes two runs to get the desired configuration.

http://plathrop.tertiusfamily.net/puppet/best-practice-draft.html

I generally don’t have such luxuries.

I’m completely and utterly opposed to that statement by the way. It does matter if it takes two runs.

So give me a bit and I’ll be back with a vision.

Thank you John. Your stateless deployment is something we really must support first class, and I’m thrilled to see someone actively using Puppet in that sort of environment and reporting issues.

#9 Updated by Jo Rhett over 4 years ago

John, I’m curious if this would solve your problem? I doubt it, but it’s worth a try:

subscribe => [

    File['/tmp/test/A'],File['/tmp/test/B'],
],

#10 Updated by John Florian over 4 years ago

Jo Rhett wrote:

John, I’m curious if this would solve your problem? I doubt it, but it’s worth a try:

subscribe => [

    File['/tmp/test/A'],File['/tmp/test/B'],
],

Jo, while I don’t recall the exact scenario from which this abstract problem stems, I am 100% certain that if that had been an option, I would have tried it. The problem is that work-around introduces other undesired behavioral changes, specifically that the service would be restarted should either file change whereas, as written above, I would only want the service restarted should File[‘/tmp/test/B’] change. I realize that may sound odd, but I assure you that in the real example, it was by requirement.

#11 Updated by Nan Liu over 4 years ago

The solution in this case is File[‘B’] require File[‘A’]. If A fails, B doesn’t get deployed and service doesn’t get refreshed.

#12 Updated by Nigel Kersten almost 4 years ago

  • Assignee changed from Nigel Kersten to eric sorenson

Also available in: Atom PDF