Issue #5605 has been updated by Jesse Wolfe.

I've got a sketch of a solution that changes the keys of the hash passed to 
"prefetch", so it might not be compatible with third-party providers.
I have a vague idea of how to fix it in a back-compatible way, if that's 
necessary.
Either way, I'd like to spend a little time thinking about how to test it, as 
it's a fairly cross-cutting change.
----------------------------------------
Bug #5605: Prefetch doesnt work when resourcetype uses composite keys
https://projects.puppetlabs.com/issues/5605

Author: Stefan Schulte
Status: Needs More Information
Priority: Normal
Assignee: Jesse Wolfe
Category: transactions
Target version: Statler
Affected Puppet version: 2.6.0
Keywords: transaction, prefetch, provider
Branch: https://github.com/stschulte/puppet/tree/ticket/2.6.x/5605


One can create types with multiple keyattributes by using isnamevar multiple 
times. (Example: Port in /etc/services with the keyattributes name and 
protocol).

Unfortunately prefetching of these types is broken in transaction.rb

    def prefetch
      prefetchers = {}
      @catalog.vertices.each do |resource|
        if provider = resource.provider and 
provider.class.respond_to?(:prefetch)
          prefetchers[provider.class] ||= {}
          prefetchers[provider.class][resource.name] = resource
        end
      end
      [...]
    end

Because `resource.name` is not uniq anymore we will eventually overwrite 
existing resources in the prefetch-hash and thus not all resources are passed 
to the prefetch method of the underlying provider. So if the user defined the 
following manifest:

    port { 'telnet:tcp': name => 'telnet', protocol => 'tcp', number => '23'}
    port { 'telnet:udp': name => 'telnet', protocol => 'udp', number => '23'}

The providers defined `def self.prefetch(resources)` will only get 
`resources['telnet'] = <second resource with protocol udp>`

I have the following suggestions:

* use `resource.uniqueness_key` instead of `resource.name`. `uniqueness_key` is 
an array of all the key_attributes. This can only work if you can reliably use 
arrays as hashkeys. I don't know if thats true for all ruby versions. This 
solution will probably break every existing provider who uses prefetch
* same as firstone except use uniqueness_key[0].intern if we only have one 
keyattribute. This solution will hopefully not break existing providers
* use `prefetchers[provider.class][resource.name] << resource` so we will not 
overwrite but build an array if name is not uniq.
* build a nested hash, so in my port example we whould get 
`prefetchers[provider.class][resource[:name]][resource[:protocol]]`


-- 
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 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-bugs?hl=en.

Reply via email to