Accessing puppet catalog in provider self.* methods

75 views
Skip to first unread message

Nan Liu

unread,
Jan 29, 2015, 8:38:24 PM1/29/15
to puppet-dev
I'm trying to use ini_setting as a parent provider. Everything works well, but to support purging, the resources provider need to specify the target file via self.file_path. Initially this seems straightforward, but the config file location can vary based on installation settings. All the examples I've seen have a hard coded filepath in self.file_path. I can't use parameter in the puppet type to provide the file path because it's only accessible in the normal setter/getter via resources[:file_path]. scope.lookupvar is definitely not available, so is there a way to access the catalog in self.* methods in the provider?

Thanks,

Nan

Trevor Vaughan

unread,
Jan 29, 2015, 9:16:36 PM1/29/15
to puppe...@googlegroups.com
Hi Nan,

Not sure if this will do what you want, but can you use 'initialize' to set up an instance variable that pulls from the catalog and then reference that instance variable later in your self.* methods?

Thanks,

Trevor

--
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/CACqVBqAVp6uLOGoQLjhCAw7gpBXu_bAdcoBu4Tyg64cVuK75KA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.



--
Trevor Vaughan
Vice President, Onyx Point, Inc
(410) 541-6699
tvau...@onyxpoint.com

-- This account not approved for unencrypted proprietary information --

Luke Kanies

unread,
Jan 30, 2015, 9:29:56 AM1/30/15
to puppe...@googlegroups.com
On Jan 30, 2015, at 1:37 AM, Nan Liu <nan...@gmail.com> wrote:

I'm trying to use ini_setting as a parent provider. Everything works well, but to support purging, the resources provider need to specify the target file via self.file_path. Initially this seems straightforward, but the config file location can vary based on installation settings. All the examples I've seen have a hard coded filepath in self.file_path. I can't use parameter in the puppet type to provide the file path because it's only accessible in the normal setter/getter via resources[:file_path]. scope.lookupvar is definitely not available, so is there a way to access the catalog in self.* methods in the provider?

The self.* methods are class methods, so they shouldn’t generally have access to per-run values like the catalog.

How are you setting the path for the file?  You could maybe have that process set the path variable on the provider.

It might be that there’s a global means of finding the catalog, too — something equivalent to Environment.current or whatever it is — but I can’t remember.

— 

Nan Liu

unread,
Jan 30, 2015, 10:37:10 AM1/30/15
to puppet-dev
On Fri, Jan 30, 2015 at 7:29 AM, Luke Kanies <lu...@puppetlabs.com> wrote:
On Jan 30, 2015, at 1:37 AM, Nan Liu <nan...@gmail.com> wrote:

I'm trying to use ini_setting as a parent provider. Everything works well, but to support purging, the resources provider need to specify the target file via self.file_path. Initially this seems straightforward, but the config file location can vary based on installation settings. All the examples I've seen have a hard coded filepath in self.file_path. I can't use parameter in the puppet type to provide the file path because it's only accessible in the normal setter/getter via resources[:file_path]. scope.lookupvar is definitely not available, so is there a way to access the catalog in self.* methods in the provider?

The self.* methods are class methods, so they shouldn’t generally have access to per-run values like the catalog.

How are you setting the path for the file?  You could maybe have that process set the path variable on the provider.

So using puppetlabs-splunk as an example [1] (for more background see inifile [2]). The provider hard codes the config file path. If the software package is installed elsewhere, this provider is not flexible enough to look for it. Ideally the file_path should be:

def self.file_path
   File.join( scope.lookupvar("splunk::params::forwader_confdir"), 'inputs.conf' )
end

But the provider is way too late in the game trying to access a value that exists during compilation. So the catalog seems like the next best place for figuring out where is splunk installed. After sleeping on it, I suppose we can also write a setting file on the client system indicating where splunk is installed, and read it back in the provider, but that seems like such a round about way to get this info.

Thanks,

Nan

Trevor Vaughan

unread,
Jan 30, 2015, 3:12:38 PM1/30/15
to puppe...@googlegroups.com
If you do access the catalog in a self.* method, it's completely compile order dependent and you'll only have access to the catalog as compiled to that point, not the entire catalog.

You have access to the entire catalog in the 'finish' method of the type, but that may be too late.

Trevor

--
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.

For more options, visit https://groups.google.com/d/optout.

Nan Liu

unread,
Jan 30, 2015, 3:24:25 PM1/30/15
to puppet-dev
On Fri, Jan 30, 2015 at 1:12 PM, Trevor Vaughan <tvau...@onyxpoint.com> wrote:
If you do access the catalog in a self.* method, it's completely compile order dependent and you'll only have access to the catalog as compiled to that point, not the entire catalog.

It should be the whole catalog since the provider is running once everything is compiled. The partial catalog problem is only with puppet functions (or anything in a manifest).

I was able to work around this by abusing self.prefetch, since the transaction layer passes in a subset of resources:

def self.prefetch(resources)
    catalog = resources[resources.keys.first].catalog
    # Note: catalog.resources != resources
    splunk_config = catalog.resources.find{|s| s.type == :splunk_config}
    confdir = splunk_config['forwarder_confdir'] || raise(Puppet::Error, 'Unknown splunk forwarder confdir')
    @file_path = File.join(confdir, 'outputs.conf')
end

The whole work around have been submitted as a PR [1]. I am open for a better solution, since this doesn't seem ideal.

Nan

1. https://github.com/puppetlabs/puppetlabs-splunk/pull/14

Trevor Vaughan

unread,
Jan 30, 2015, 3:34:31 PM1/30/15
to puppe...@googlegroups.com
That makes sense, and yeah, that whole catalog should be there unless you're dynamically injecting resources.

You might want to add a check before splunk_config['forwarder_confdir'] in case you didn't find the resource in the catalog so you don't hit a null pointer issue.

Not seeing a better way to do this right now actually.

Trevor

--
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.

For more options, visit https://groups.google.com/d/optout.

Eli Young

unread,
Jan 30, 2015, 4:34:14 PM1/30/15
to puppe...@googlegroups.com
On Friday, January 30, 2015 at 12:24:25 PM UTC-8, Nan Liu wrote:
I was able to work around this by abusing self.prefetch, since the transaction layer passes in a subset of resources:

def self.prefetch(resources)
    catalog = resources[resources.keys.first].catalog
    # Note: catalog.resources != resources
    splunk_config = catalog.resources.find{|s| s.type == :splunk_config}
    confdir = splunk_config['forwarder_confdir'] || raise(Puppet::Error, 'Unknown splunk forwarder confdir')
    @file_path = File.join(confdir, 'outputs.conf')
end

Is abusing prefetch even necessary?  I'm fairly certain that you can access the catalog from the provider via resource.catalog.

Nan Liu

unread,
Jan 30, 2015, 5:20:28 PM1/30/15
to puppet-dev
resource does not appear to be available in self.* class methods, only instance methods. 

Thanks,

Nan

Eli Young

unread,
Jan 30, 2015, 5:57:43 PM1/30/15
to puppe...@googlegroups.com
Oh, gotcha.  Sorry, forgot that you had to do this in the class context.
Reply all
Reply to author
Forward
0 new messages