Issue #5761 has been updated by Charlie Sharpsteen.

Subject changed from a local collect ignores default values to Default values 
are not fully evaluated by the compiler
Status changed from Duplicate to Accepted
Assignee deleted (eric sorenson)

It turns out that this is actually a separate issue. This situation is affected 
by the ordering of compiler run stages as mentioned mentioned in #3845, but 
there is something else going on.

Resource defaults are merged in when [finish is called on 
resources](https://github.com/puppetlabs/puppet/blob/3.2.0/lib/puppet/parser/compiler.rb#L358)
 by the compiler [which leads 
to](https://github.com/puppetlabs/puppet/blob/3.2.0/lib/puppet/parser/resource.rb#L107)
 the [add_defaults 
method](https://github.com/puppetlabs/puppet/blob/3.2.0/lib/puppet/parser/resource.rb#L236-L244)
 in parser/resource.rb:

<pre>
def add_defaults
  scope.lookupdefaults(self.type).each do |name, param|
    unless @parameters.include?(name)
      self.debug "Adding default for #{name}"

      @parameters[name] = param.dup
    end
  end
end
</pre>

This method loops over each default and adds values to the @parameters hash if 
they are unset. No more, no less. The problem is that simply altering the 
@parameters hash isn't sufficient to trigger the full effect of a resource 
parameter---the value must be present in the hash when the resource is 
evaluated by the compiler. As an example, consider the following manifest:

<pre>
Notify{ tag => 'default_tag' }
notify{ 'hello, compiler!': }
</pre>

Drop a pry shell at the end of the compile method in parser/compile.rb and 
inspect what happens:

<pre>
[root@puppetmaster vagrant]# puppet apply default_tag.pp

From: /puppetlabs/puppet/lib/puppet/parser/compiler.rb @ line 108 
Puppet::Parser::Compiler#compile:

     91: def compile
     92:   # Set the client's parameters into the top scope.
     93:   Puppet::Util::Profiler.profile("Compile: Set node parameters") { 
set_node_parameters }
     94:
     95:   Puppet::Util::Profiler.profile("Compile: Created settings scope") { 
create_settings_scope }
     96:
     97:   Puppet::Util::Profiler.profile("Compile: Evaluated main") { 
evaluate_main }
     98:
     99:   Puppet::Util::Profiler.profile("Compile: Evaluated AST node") { 
evaluate_ast_node }
    100:
    101:   Puppet::Util::Profiler.profile("Compile: Evaluated node classes") { 
evaluate_node_classes }
    102:
    103:   Puppet::Util::Profiler.profile("Compile: Evaluated generators") { 
evaluate_generators }
    104:
    105:   Puppet::Util::Profiler.profile("Compile: Finished catalog") { finish 
}
    106:
    107:   fail_on_unevaluated
 => 108:   require 'pry'; binding.pry
    109:   @catalog
    110: end


[1] pry(#<Puppet::Parser::Compiler>)> resources
=> [Class[main]{}, Notify[hello, compiler!]{:tag=>"default_tag"}]


[2] pry(#<Puppet::Parser::Compiler>)> resources[1].tagged?('notify')
=> true


[3] pry(#<Puppet::Parser::Compiler>)> resources[1].tagged?('default_tag')
=> false


[4] pry(#<Puppet::Parser::Compiler>)> resources[1].tags
=> ["notify", "class"]
</pre>

The notify resource has the `:tag` parameter set to 'default_tag' as expected. 
However, this parameter wasn't set when the resource was evaluated by the 
compiler and thus isn't part of the tags array attached to the resource. 
Because of this, the `tagged?` function doesn't recognize 'default_tag' as 
being attached to the resource. The upshot is that anything that uses `tagged?` 
to filter resources, such as a Transaction applying the catalog, won't be able 
to recognize parameters that are set via resource defaults.

This will affect any parameter that produces a side effect during evaluation by 
the compiler.

----------------------------------------
Bug #5761: Default values are not fully evaluated by the compiler
https://projects.puppetlabs.com/issues/5761#change-91001

* Author: David Schmitt
* Status: Accepted
* Priority: Normal
* Assignee: 
* Category: compiler
* Target version: 
* Affected Puppet version: 2.6.3
* Keywords: export collect tags defaults
* Branch: 
----------------------------------------
    File { tag => 'sc_test' }
    @@file {
        "/tmp/test1": ensure => present;
        "/tmp/test2": ensure => present, tag => 'sc_test';
    }
    File <<| tag == 'sc_test' |>>


    # ls -la /tmp/test*
    -rw-r--r-- 1 root root 0 Jan  3 14:28 /tmp/test2

>From my understanding, the defaults statement in the first line should ensure 
>that both files are tagged 'sc_test'. As can be seen from the results, only 
>the explicitly tagged resource is collected. This can also be observed with 
>other parameters.

The resource gets written into the stored configs database and other nodes can 
collect both files.


-- 
You have received this notification because you have either subscribed to it, 
or are involved in it.
To change your notification preferences, please click here: 
http://projects.puppetlabs.com/my/account

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Bugs" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-bugs?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to