Best way to bail from facter script without using confine in Facter.add ?

1,524 views
Skip to first unread message

ZJE

unread,
Aug 22, 2012, 11:49:06 AM8/22/12
to puppet...@googlegroups.com
I have a script in $FACTERLIB that queries proprietary vendor tools for RAID configuration. These tools are quite slow, so the top of my .rb file calls the program once and stores the output in a variable. Multiple Facter.add statements then populate the facts. I would like to bail on this custom fact script if it's being run on a VM or unsupported host. I don't think "confine" would work here since I have multiple Facter.add and I would ideally like to bail before it gets to any of them. If I try "exit," facter just exists and no other facts are collected. Looking at the code in facter/util/loader.rb, I could throw a ScriptError exception - but that seems hackish.

Anyone have experience or suggestions for doing something similar? I've tried searching existing code with no luck.

Nigel Kersten

unread,
Aug 22, 2012, 12:36:13 PM8/22/12
to puppet...@googlegroups.com
You can surround the Facter.add calls with explicit checks like:

if Facter.value(:kernel) == "Darwin"
Facter::Util::Macosx.hardware_overview.each do |fact, value|
Facter.add("sp_#{fact}") do
confine :kernel => :darwin
setcode do
value.to_s
end
end
end
end

(Yes, that confine there is somewhat redundant...)

Are you really seeing a significant slowdown though if you don't do
this and simply have the confine call within each Facter.add ? If so,
we should work on that.

ZJE

unread,
Aug 22, 2012, 2:13:07 PM8/22/12
to puppet...@googlegroups.com
The slowdown comes from the command that I run before any Facter.add statements. It takes roughly 1.5 seconds to run and I would need to run it roughly 64 times if I had it in each Facter.add. Many facts are generated by a loop that contains a Facter.add, so I feel like some sort of exception would make things easier.  I'd like to avoid using a "giant if statement" if possible (there are roughly 100 lines of code that would be encapsulated). One of the main issues I have is that there are two different checks that happen in different parts of the code. I recognize that some may consider adding more if-statements as increased readability, but I feel like the added indentation for large chunks of code causes confusion for readers (especially when looking at loops).

Thanks so much for your reply!

Nigel Kersten

unread,
Aug 22, 2012, 2:56:49 PM8/22/12
to puppet...@googlegroups.com
On Wed, Aug 22, 2012 at 11:13 AM, ZJE <count...@gmail.com> wrote:
> The slowdown comes from the command that I run before any Facter.add
> statements. It takes roughly 1.5 seconds to run and I would need to run it
> roughly 64 times if I had it in each Facter.add. Many facts are generated by
> a loop that contains a Facter.add, so I feel like some sort of exception
> would make things easier. I'd like to avoid using a "giant if statement" if
> possible (there are roughly 100 lines of code that would be encapsulated).
> One of the main issues I have is that there are two different checks that
> happen in different parts of the code. I recognize that some may consider
> adding more if-statements as increased readability, but I feel like the
> added indentation for large chunks of code causes confusion for readers
> (especially when looking at loops).
>
> Thanks so much for your reply!

You should be able to do something like this, which worked for the
quick test I did, but I haven't extensively tested it.

arr = ["one", "two", "three", "four"]

if true then
# exit due to conditions for not running on this host
exit
else
# run the command you'd run and store in an instance variable
end

arr.each do |e|
Facter.add("tester_#{e}") do
setcode do
"bleah"
end
end
end
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/puppet-users/-/K5Mm3du3mkQJ.
>
> To post to this group, send email to puppet...@googlegroups.com.
> To unsubscribe from this group, send email to
> puppet-users...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/puppet-users?hl=en.



--
Nigel Kersten | http://puppetlabs.com | @nigelkersten
Schedule Meetings at: http://tungle.me/nigelkersten

ZJE

unread,
Aug 23, 2012, 10:17:17 AM8/23/12
to puppet...@googlegroups.com


Hi Nigel,

Thanks again for your reply. Currently, I'm using "exit" - but I think this causes the entire facter run to stop prematurely. If my script ends up being the first custom fact run, facter actually outputs nothing. Could there be a different problem?

For example, if FACTERLIB=/opt/facter/facts and my custom fact looks like this:
---
cat /opt/facter/facts/bailfact.rb
#!/usr/bin/ruby
Facter.debug "In bailfact!"
exit
---

I get:
---
[root@testhost ~]# facter -d
Relative directory ./facter removed from search path.
Not an EC2 host
in bail fact!
---

and nothing else.

If it helps, I'm using facter 2.0.0rc4

Thanks!

Nigel Kersten

unread,
Aug 23, 2012, 12:26:59 PM8/23/12
to puppet...@googlegroups.com
heh. That makes sense :)

You're going to need to surround it all in a conditional then as far
as I can see.

Wolf Noble

unread,
Aug 23, 2012, 1:18:12 PM8/23/12
to <puppet-users@googlegroups.com>
why not check to see if the binary which you're using to talk to the raid hw exists.. if so, execute and provide facts, if not, do nothing..
That's how it's being done in the hpacucli fact I've been using.


On Aug 23, 2012, at 11:26 AM, Nigel Kersten <ni...@puppetlabs.com>
wrote:
> --
> You received this message because you are subscribed to the Google Groups "Puppet Users" group.
> To post to this group, send email to puppet...@googlegroups.com.
> To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
>


________________________________

This message may contain confidential or privileged information. If you are not the intended recipient, please advise us immediately and delete this message. See http://www.datapipe.com/legal/email_disclaimer/ for further information on confidentiality and the risks of non-secure electronic communication. If you cannot access these links, please notify us by reply message and we will send the contents to you.

ZJE

unread,
Aug 23, 2012, 3:17:22 PM8/23/12
to puppet...@googlegroups.com

On Thursday, August 23, 2012 12:18:12 PM UTC-5, Wolf Noble wrote:
why not check to see if the binary which you're using to talk to the raid hw exists.. if so, execute and provide facts, if not, do nothing..
That's how it's being done in the hpacucli fact I've been using.


That's the other route I'm thinking of going. What I've written abstracts away vendors by having different helper classes provide the information as an object and the main custom fact does all the Facter.add stuff using the data from the objects. I could just create a noop type object that would cause the script to exit. However, I was hoping for a more general solution to exiting out of facts early, but I realize that I may just be getting too nit-picky.

Thanks all for your help!
Reply all
Reply to author
Forward
0 new messages