Skip to content

Commit 4f19c27

Browse files
committed
(PE-20308) Pass a literal type and not a string to findresource
- `defined_with_params` calls `findresource(reference.to_s)` - `findresource` is https://github.com/puppetlabs/puppet/blob/4.8.1/lib/puppet/parser/compiler.rb#L407 and points to https://github.com/puppetlabs/puppet/blob/4.8.1/lib/puppet/resource/catalog.rb#L352 - This calls `Puppet::Resource.new` with the type https://github.com/puppetlabs/puppet/blob/4.8.1/lib/puppet/resource/catalog.rb#L366 - This ends up calling `resource_type` via https://github.com/puppetlabs/puppet/blob/4.8.1/lib/puppet/resource.rb#L317-L319 and that ends up declaring the type via the autoloader api at https://github.com/puppetlabs/puppet/blob/4.8.1/lib/puppet/resource.rb#L390 - But why does the autoloader API fail to find it in the current environment? - Okay, so when the autoloader is trying to find the type, it uses the typeloader to look it up in the current environment https://github.com/puppetlabs/puppet/blob/4.8.1/lib/puppet/metatype/manager.rb#L171 - this calls `get_file` and `mark_loaded` https://github.com/puppetlabs/puppet/blob/4.8.1/lib/puppet/util/autoload.rb#L64-L67 Suggested workaround is to pass a literal type instead of a string to `findresource` to fix in stdlib, and also to fix loading/requiring of type in core puppet. This seems to affect more recent versions of puppet, so fallback to original behavior on pre-4.5
1 parent f15cc31 commit 4f19c27

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

lib/puppet/parser/functions/defined_with_params.rb

+19-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,25 @@
2424
params = {}
2525
end
2626
ret = false
27-
if resource = findresource(reference.to_s)
27+
28+
if Puppet::Util::Package.versioncmp(Puppet.version, '4.5.0') >= 0
29+
# Workaround for PE-20308
30+
if reference.is_a?(String)
31+
type_name, title = Puppet::Resource.type_and_title(reference, nil)
32+
type = Puppet::Type.type(type_name)
33+
elsif reference.is_a?(Puppet::Resource)
34+
type = reference.resource_type
35+
title = reference.title
36+
else
37+
raise(ArgumentError, "Reference is not understood: '#{reference.class}'")
38+
end
39+
#end workaround
40+
else
41+
type = reference.to_s
42+
title = nil
43+
end
44+
45+
if resource = findresource(type, title)
2846
matches = params.collect do |key, value|
2947
# eql? avoids bugs caused by monkeypatching in puppet
3048
resource_is_undef = resource[key].eql?(:undef) || resource[key].nil?

spec/functions/defined_with_params_spec.rb

+18
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,22 @@
3737
it { is_expected.to run.with_params('File[/tmp/a]', {}).and_return(true) }
3838
it { is_expected.to run.with_params('File[/tmp/a]', { 'ensure' => 'present', 'owner' => :undef }).and_return(true) }
3939
end
40+
41+
describe 'when the reference is a' do
42+
let :pre_condition do
43+
'user { "dan": }'
44+
end
45+
context 'reference' do
46+
it { is_expected.to run.with_params(Puppet::Resource.new('User[dan]'), {}).and_return(true) }
47+
end
48+
if Puppet::Util::Package.versioncmp(Puppet.version, '4.5.0') >= 0
49+
context 'array' do
50+
it 'fails' do
51+
expect {
52+
subject.call([['User[dan]'], {}])
53+
}.to raise_error ArgumentError, /not understood: 'Array'/
54+
end
55+
end
56+
end
57+
end
4058
end

0 commit comments

Comments
 (0)