catalog access from provider class methods?

22 views
Skip to first unread message

Joshua hoblitt

unread,
Apr 15, 2015, 12:14:38 PM4/15/15
to puppe...@googlegroups.com
I desire the ability to access DSL class parameters from within a
provider. Similar to the pattern that is frequently seen with DSL
defined types and a controlling class within a module. AFAIK, the
alternatives for sharing data are ugly. Including: forcing the user to
declare facts via ENC or an external fact source, using a file resource
for "local IPC" (or sysv shm...), or adding parameters to the type and
using a DSL defined type as wrapper. The later is the least
objectionable but feels like it should be unnecessary; the data is
already in the catalog.

Accessing the catalog from within a provider instance isn't very
difficult since the instantiated resource has an accessor for it. Eg.
`resource.catalog` Where I've hit a roadblock is trying to access the
catalog from a class method. I've spent several hours poking at classes
looking for an instance I could pry into or a singleton I could access
without much luck. There was a suggestion on #puppet that it might be
possible to obtain it via the indirector. I don't understand the
indirection facility but I don't believe it has knowledge beyond the
name of the catalog class. Eg.
`Puppet::Indirector::Indirection.instance(:catalog).instance_variable_get(:@indirected_class).class`
Perhaps I'm in error? I also failed to identify a reference back to the
current transaction.

My last resort was to try passing the catalog from the resource to the
provider as class data. This is problematic in that I can't identify a
place to "hook" in that runs after both
`Puppet::Util::ClassGen.genclass` and the providers are associated with
a type but before the provider's class instances method is called. I've
been resisting the temptation to stuff something into the
`Puppet::Type.provide` method's option hash and monkey patching my way
to victory...

I did have some limited success in that I was able to get into the
catalog from `::prefetch` by adding class accessors for `catalog` to the
provider and dropping this snippet into an autorequire block.

if provider.class.respond_to?(:catalog)
provider.class.catalog = catalog
end

Of course, where I want access to the catalog data is from
`::instances`. Have I missed something obvious?

Cheers,

-Josh

--

Branan Riley

unread,
Apr 15, 2015, 12:42:32 PM4/15/15
to puppe...@googlegroups.com
In the past I have done this with `Puppet::Face[:catalog, :current]`

I did this in a prototype back for Puppet 2.7, so I have no idea if it still works, and I can't promise that it will continue to work in the future.

-- Branna



--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/552DD1D6.5060005%40hoblitt.com.
For more options, visit https://groups.google.com/d/optout.

Joshua Hoblitt

unread,
Apr 15, 2015, 1:28:40 PM4/15/15
to puppe...@googlegroups.com
On 04/14/2015 07:49 PM, Joshua hoblitt wrote:
> I desire the ability to access DSL class parameters from within a
> provider. Similar to the pattern that is frequently seen with DSL
> defined types and a controlling class within a module. AFAIK, the
> alternatives for sharing data are ugly. Including: forcing the user to
> declare facts via ENC or an external fact source, using a file resource
> for "local IPC" (or sysv shm...), or adding parameters to the type and
> using a DSL defined type as wrapper. The later is the least
> objectionable but feels like it should be unnecessary; the data is
> already in the catalog.

On second thought, type parameters aren't an option as ::instances
inherently runs before there are any resource instances, besides the
fact that what I'm after is data that's need to fetch all the provider
instances. Ie., it is global for the type. I've since discovered
#pre_run_check via pry but it also runs too late to be help with
::instances.

-Josh

--

Joshua Hoblitt

unread,
Apr 15, 2015, 1:57:18 PM4/15/15
to puppe...@googlegroups.com
Hi Branna,

Under 3.7.5, that gives me a Puppet::Indirector::Face object.
https://github.com/puppetlabs/puppet/blob/3.7.5/lib/puppet/indirector/face.rb

I'm not sure where to go from there as I don't want to download a new
new catalog, and at least from pry under the resource face, #find seems
to generate garbage catalogs. Any ideas?

-Josh

--
>> email to puppet-dev+...@googlegroups.com.

Branan Riley

unread,
Apr 15, 2015, 2:03:43 PM4/15/15
to puppe...@googlegroups.com


To view this discussion on the web visit https://groups.google.com/d/
msgid/puppet-dev/552DD1D6.5060005%40hoblitt.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/552EA6AD.2030606%40cpan.org.

Joshua Hoblitt

unread,
Apr 15, 2015, 2:08:51 PM4/15/15
to puppe...@googlegroups.com
I take that back... I get something that looks "more real" when passing
a manifest to apply. However, I'm not at all clear what I'm supposed to
be passing to find. The code seems to suggest it should be call with
`Puppet[:certname]` but I seem to get back essentially the same object
that has a #name of anything I pass to #find.

[8] pry(clihelper)> foo.find(:foobar).name
Debug: Loading external facts from /home/vagrant/.puppet/var/facts.d
Info: Loading facts
Debug: Loading facts from /home/vagrant/puppet-jenkins/lib/facter/jenkins.rb
Info: Loading facts
Debug: Loading facts from /home/vagrant/jenkins/lib/facter/jenkins.rb
Notice: Compiled catalog for foobar in environment production in 0.01
seconds
=> :foobar

?

-Josh

--

Joshua Hoblitt

unread,
Apr 15, 2015, 2:15:32 PM4/15/15
to puppe...@googlegroups.com
That seems to work! The message about the compiler being invoked is a
bit worrying through.

Amusingly, I'm also working on types for jenkins but with the cli jar
and groovy script fragments instead of the rest API.

-Josh

--
>>>> email to puppet-dev+...@googlegroups.com.
>>>> To view this discussion on the web visit https://groups.google.com/d/
>>>> msgid/puppet-dev/552DD1D6.5060005%40hoblitt.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>>
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Puppet Developers" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to puppet-dev+...@googlegroups.com.
>> To view this discussion on the web visit https://groups.google.com/d/
>> msgid/puppet-dev/552EA6AD.2030606%40cpan.org.
Reply all
Reply to author
Forward
0 new messages