On Mon, Aug 22, 2011 at 10:05 AM, Brian Troutwine <br...@troutwine.us> wrote:
> On Mon, Aug 22, 2011 at 11:31 AM, Gary Larizza <g...@puppetlabs.com> wrote:
>>
>>
>>> It's a function of my ignorance of writing custom facts. I have yet to
>>> find a good reference for doing so and aped entirely code examples found
>>> online. I haven't the slightest idea of what setcode does. Here's my top
>>> search result for 'factor puppet':
>>
>> Good question.  The 'setcode do" ... "end" block is executed by facter to
>> generate a custom value for your fact.
>
> What do you mean, 'generate a custom value'? In what manner is a facter
> 'custom value' different from a return value in the surrounding Facter.add
> block? Why would code outside of a setcode block make someone in the know,
> as it were, uneasy?

I'm not sure what's the objection, and there's plenty of examples in
facter source code:
https://github.com/puppetlabs/facter/tree/master/lib/facter

I think you should ask the person who gave the objection.

>>  The value of the last expression in that block is returned as the value
>> for your custom fact.
>
> Why? Which is to say, why does setcode exist at all and why is not the
> return value for the Facter.add block taken as the value for the fact? Of
> what special utility is setcode?

setcode evaluates a block of code and use the results for the value of
the custom fact. It's Ruby metaprogramming, see def setcode:
https://github.com/puppetlabs/facter/blob/master/lib/facter/util/resolution.rb

In your example, I think it's more appropriate to write it as:

require 'facter'
Facter.add("memorysize_mb") do
  confine :kernel => :Linux
  setcode do
    ram = 0
    File.open( "/proc/meminfo" , 'r' ) do |f|
    f.grep( /^MemTotal:/ ) { |mem|
      ram = mem.split( / +/ )[1].to_i / 1024
    }
    ram
  end
end

>>  There are a couple of resources here that you can check out
>> --> http://projects.puppetlabs.com/projects/1/wiki/Adding_Facts  and
>> --> http://www.puppetlabs.com/blog/facter-part-1-facter-101/ that should
>> provide some help!
>>
>
> These articles are in fact two that I aped, as pointed out in the first
> email of this thread (though I linked to the second article of the latter's
> three-part series). The blog post, especially, gives code examples and
> explains how great everything is without actually explaining how it is that
> the factor API works. The 'setcode' is sprung on the reader with no prior
> elaboration and no subsequent instruction. I could be very much mistaken;
> please do explain if I am.

Not sure if this makes it any clearer:

Facter.Add(:custom_fact_name) do
  setcode do
     ... custom code on how to obtain custom_fact_name and this is
evaluated to determine the value of Facter[:custom_fact_name] ...
  end
end

There's probably a few inaccuracies that needs update, for example %x
should be Facter::Util::Resolution.exec. When I get a chance I'm going
to do a quick revision especially if new users are referencing it. Let
me know if I should add the previous example or other clarifications.

>>> I search for 'factor' or 'fact' and get a brief reference to using
>>> pre-cooked facts. The search 'puppet custom facts' lead to the references
>>> mentioned in my previous email; none of which are API references. The phrase
>>> 'facter rdoc puppet' returns nothing apropos. Do you know of a proper
>>> reference to facter's API? If not, would you kindly explain setcode and why
>>> code being outside of it makes you nervous?
>>>
>>>>
>>>> Also, try 'notify'ing the fact value in the scope wherein you evaluate
>>>> the template.  For example,
>>>>
>>>> class example {
>>>>  notify { "maintenance_work_mem_debug":
>>>>    message => "maintenance_work_mem is '${::maintenance_work_mem}'
>>>> for kernel '${::kernel}'"
>>>>  }
>>>>
>>>>  file {"/etc/my_templated_file":
>>>>    content => template("my_template.erb")
>>>>  }
>>>> }
>>>>
>>>
>>> The issue has nondeterministically resolved itself, which is a bummer; I
>>> can no longer debug. I understand 'notify' only in the context of services
>>> or execs. What does it mean to notify a fact? Moreover, do you have a
>>> reference to the broader meaning of 'notify' that I am, apparently, missing?
>>
>> Also, 'notify' is another resource in Puppet, just like 'file', 'package',
>> and 'service' are.  You can setup a notify resource to output the contents
>> of its 'message' parameter to the screen with every puppet run.  This helps
>> you debug because you can also use string interpolation to retrieve the
>> value of variables or facts during the puppet run.  John used the following
>> example:
>>>
>>> notify { "maintenance_work_mem_debug":
>>>    message => "maintenance_work_mem is '${::maintenance_work_mem}'
>>> for kernel '${::kernel}'"
>>>  }
>>
>> Using that notify resource, it will output "maintenance_work_mem is <value
>> of that fact>" during the puppet run.
>
> Ah, so it was merely a debugging step?
>
>>
>> Hope this helps!
>
> Very much. As mentioned, the problem I reported cleared itself up: the worst
> possible way, of course, for a problem to be resolved. I wonder, in what
> circumstances might, when run on a client machine, 'facter --puppet
> some_custom_fact' return the intended value when the use of the custom
> function in a template would not? Could it be an issue of overly
> conservative caching? How would I deduce if it were and, once deduced, flush
> the cache?

There's no caching in the current version of puppet. I'm thinking the
problem might be because the code you provided only had ram in the
setcode, and the code for obtaining the actual value of ram is outside
the setcode portion. You can check using the notify resource or the
$vardir/yaml/facts on puppet master for the actual value you are
getting back for your custom fact.

HTH,

Nan

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To post to this group, send email to puppet-users@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en.

Reply via email to