From 9f6dec267467334dcc5e1157b9dce57a325cbb73 Mon Sep 17 00:00:00 2001 From: Nick Lewis Date: Thu, 26 May 2011 13:32:11 -0700 Subject: (#7681) Allow array variables as resource references The commit df088c9ba16dce50c17a79920c1ac186db67b9e9 introduced a regression where $files = ["/tmp/one", "/tmp/two"] file { "/tmp/one": content => "one", } file { "/tmp/two": content => "two", } file { "/tmp/three": content => "three", require => File[$files], } no longer worked. File[$files] was concatenating the elements of $files to create a single title, instead of expanding to multiple File dependencies. Since resource reference titles are implicitly wrapped in an array, if one of the elements of that array is a variable containing an array, the list of titles is a nested array. Prior to the change causing the regression, we would flatten arrays when evaluating them, under certain circumstances. We no longer ever flatten AST arrays when evaluating them, so anywhere that we really do need a flattened array, we have to manually flatten it. ResourceReference expects its list of titles to be a single, flat list of titles, so we have to make it so. Paired-with: Jacob Helwig --- lib/puppet/parser/ast/resource_reference.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/puppet/parser') diff --git a/lib/puppet/parser/ast/resource_reference.rb b/lib/puppet/parser/ast/resource_reference.rb index 0f8e655bf..256a99d75 100644 --- a/lib/puppet/parser/ast/resource_reference.rb +++ b/lib/puppet/parser/ast/resource_reference.rb @@ -7,7 +7,7 @@ class Puppet::Parser::AST::ResourceReference < Puppet::Parser::AST::Branch # Evaluate our object, but just return a simple array of the type # and name. def evaluate(scope) - titles = Array(title.safeevaluate(scope)) + titles = Array(title.safeevaluate(scope)).flatten a_type, titles = scope.resolve_type_and_titles(type, titles) -- cgit From 75e2764d15de6cf1dee923019f579f436d5b1587 Mon Sep 17 00:00:00 2001 From: Daniel Pittman Date: Fri, 27 May 2011 10:12:34 -0700 Subject: (#5318) Always notice changes to manifests when compiling. When we are asked to compile a catalog we need to update the set of known resource types, along with the node declaration, from the pool of manifests on disk. This is, obviously, a per-environment pool of resource types. To reduce the scope of the race where an update to those manifest files on disk can be updated during a compilation, we tried to cache the set of known resources in the current thread at the start of compilation, then flush it after compile finished and used the cache unconditionally if it was set. Theoretically, this would assure us that we would parse the set of manifests once, use them for the entire compile, flush the cache, and then carry on. Practically, this was enforced as described: flush *after* the compile, assume this would mean that it was clear at the start of the next compile. That presumably worked more or less right until a change was made to push extra data into the catalog at the start of the 2.6 series; that made serialization of the catalog depend on the pool of known resource types. When that happened we would reload the cache (and reparse the manifests) during serialization, but after compilation ... and leave that in the thread cache, so the precondition for the compiler was no longer true. It would see the cache as of the end of the previous compile run, not the start of the next compile run. This, in turn, was what made Puppet wait for multiple runs of the agent before showing you a change in your manifests under Passenger, but *not* under Webrick: Passenger would reuse the same thread for the next request, cache in place, while Webrick would create a new thread and (by side-effect) "flush" the cache as the compiler expected. To minimally fix this, with as little change of side-effect as possible, we move the cache flush from after compile runs to before compile runs. This might have minimal memory cost until another compile request runs in the same thread, because we cache the data longer, but most models won't cause that to be too much trouble. Reviewed-By: Matt Robinson --- lib/puppet/parser/compiler.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'lib/puppet/parser') diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb index 98bf3b574..2d065dad5 100644 --- a/lib/puppet/parser/compiler.rb +++ b/lib/puppet/parser/compiler.rb @@ -15,15 +15,19 @@ class Puppet::Parser::Compiler include Puppet::Resource::TypeCollectionHelper def self.compile(node) + # We get these from the environment and only cache them in a thread + # variable for the duration of the compilation. If nothing else is using + # the thread, though, we can leave 'em hanging round with no ill effects, + # and this is safer than cleaning them at the end and assuming that will + # stick until the next entry to this function. + Thread.current[:known_resource_types] = nil + Thread.current[:env_module_directories] = nil + + # ...and we actually do the compile now we have caching ready. new(node).compile.to_resource rescue => detail puts detail.backtrace if Puppet[:trace] raise Puppet::Error, "#{detail} on node #{node.name}" - ensure - # We get these from the environment and only cache them in a thread - # variable for the duration of the compilation. - Thread.current[:known_resource_types] = nil - Thread.current[:env_module_directories] = nil end attr_reader :node, :facts, :collections, :catalog, :node_scope, :resources, :relationships -- cgit