The uniqueness_key method of a type or resource object should return a key that can be used to identify this resource. In fact puppet seldomly uses this method and instead uses resource[:name] as an identifier.
While this is totally fine for resourcetypes with a single key_attribute (and resource[:name] returning the namevar), it breaks things as soon as one creates a type with a composite key (prefetching for example is broken). To ease the process of replacing calls to resource[:name] to resource.uniqueness_key, the method uniqueness_key now just returns name_var if there is only one key_attribute (immitating self[:name]) and only returns an array of all the values of all the key_attributes if we have more than one key_attribute. The resourcehash which is passed to providers in their prefetch method is now build with uniqueness_key as the hashkey. Because of the new behaviour of uniqueness_key we hopefully wont break existing providers while allowing new providers for types with composite keys to implement correct prefetch methods. Signed-off-by: Stefan Schulte <[email protected]> --- lib/puppet/resource.rb | 9 +++++++-- lib/puppet/transaction.rb | 2 +- lib/puppet/type.rb | 8 +++++++- spec/unit/resource_spec.rb | 11 +++++++++-- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/puppet/resource.rb b/lib/puppet/resource.rb index 4f0d507..a527968 100644 --- a/lib/puppet/resource.rb +++ b/lib/puppet/resource.rb @@ -237,11 +237,16 @@ class Puppet::Resource h = self.to_hash h[namevar] ||= h[:name] h[:name] ||= h[namevar] - h.values_at(*key_attributes.sort_by { |k| k.to_s }) + # Simulate the same behaviour like Type#uniqueness_key + if key_attributes.size == 1 + h[namevar] + else + h.values_at(*key_attributes) + end end def key_attributes - return(resource_type.respond_to? :key_attributes) ? resource_type.key_attributes : [:name] + resource_type.respond_to?(:key_attributes) ? resource_type.key_attributes : [:name] end # Convert our resource to Puppet code. diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index dcd9aad..0bb98f8 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -252,7 +252,7 @@ class Puppet::Transaction @catalog.vertices.each do |resource| if provider = resource.provider and provider.class.respond_to?(:prefetch) prefetchers[provider.class] ||= {} - prefetchers[provider.class][resource.name] = resource + prefetchers[provider.class][resource.uniqueness_key] = resource end end diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index 1b6e7dc..c50f8de 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -200,7 +200,13 @@ class Type end def uniqueness_key - to_resource.uniqueness_key + # If we have only one namevar use that one (res.uniqueness_key behaves + # like res[:name] in that case). Otherwise use an array of all keyattributes + if name_var + self[:name] + else + @parameters.values_at(*self.class.key_attributes).collect {|p| p.value } + end end # Create a new parameter. Requires a block and a name, stores it in the diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index e65e8a1..092ae8c 100755 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -268,7 +268,7 @@ describe Puppet::Resource do describe "when referring to a resource with name canonicalization" do it "should canonicalize its own name" do res = Puppet::Resource.new("file", "/path/") - res.uniqueness_key.should == ["/path"] + res.uniqueness_key.should == "/path" res.ref.should == "File[/path/]" end end @@ -770,7 +770,14 @@ describe Puppet::Resource do end describe "when generating the uniqueness key" do - it "should include all of the key_attributes in alphabetical order by attribute name" do + + it "should use namevar if there is only one key_attribute" do + Puppet::Type.type(:file).stubs(:key_attributes).returns [:path] + res = Puppet::Resource.new("file", "/my/file", :parameters => {:owner => 'root', :content => 'hello'}) + res.uniqueness_key.should == '/my/file' + end + + it "should include all of the key_attributes" do Puppet::Type.type(:file).stubs(:key_attributes).returns [:myvar, :owner, :path] Puppet::Type.type(:file).stubs(:title_patterns).returns( [ [ /(.*)/, [ [:path, lambda{|x| x} ] ] ] ] -- 1.7.3.4 -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.
