-
Notifications
You must be signed in to change notification settings - Fork 583
(#12357) Make facter_dot_d look in Puppet[:confdir]/facts.d #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
Puppet Specific Facts | ||
===================== | ||
|
||
Facter is meant to stand alone and apart from Puppet. However, Facter often | ||
runs inside Puppet and all custom facts included in the stdlib module will | ||
almost always be evaluated in the context of Puppet and Facter working | ||
together. | ||
|
||
Still, we don't want to write custom facts that blow up in the users face if | ||
Puppet is not loaded in memory. This is often the case if the user run | ||
`facter` without also supplying the `--puppet` flag. | ||
|
||
Ah! But Jeff, the custom fact won't be in the `$LOAD_PATH` unless the user | ||
supplies `--facter`! You might say... | ||
|
||
Not (always) true I say! If the user happens to have a CWD of | ||
`<modulepath>/stdlib/lib` then the facts will automatically be evaluated and | ||
blow up. | ||
|
||
In any event, it's pretty easy to write a fact that has no value if Puppet is | ||
not loaded. Simply do it like this: | ||
|
||
Facter.add(:node_vardir) do | ||
setcode do | ||
# This will be nil if Puppet is not available. | ||
Facter::Util::PuppetSettings.with_puppet do | ||
Puppet[:vardir] | ||
end | ||
end | ||
end | ||
|
||
The `Facter::Util::PuppetSettings.with_puppet` method accepts a block and | ||
yields to it only if the Puppet library is loaded. If the Puppet library is | ||
not loaded, then the method silently returns `nil` which Facter interprets as | ||
an undefined fact value. The net effect is that the fact won't be set. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# This facter fact returns the value of the Puppet vardir setting for the node | ||
# running puppet or puppet agent. The intent is to enable Puppet modules to | ||
# automatically have insight into a place where they can place variable data, | ||
# regardless of the node's platform. | ||
# | ||
# The value should be directly usable in a File resource path attribute. | ||
require 'facter/util/puppet_settings' | ||
|
||
Facter.add(:puppet_vardir) do | ||
setcode do | ||
# This will be nil if Puppet is not available. | ||
Facter::Util::PuppetSettings.with_puppet do | ||
Puppet[:vardir] | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Facter | ||
module Util | ||
module PuppetSettings | ||
class << self | ||
def with_puppet | ||
begin | ||
Module.const_get("Puppet") | ||
rescue NameError | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a whole lot of magic, right here. It should have some comments to explain what it is all about. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this is a case where it didn't seem like magic at all when I wrote Will keep this in mind and add comments if I'm in this code again soon. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On Thu, Mar 8, 2012 at 10:12 AM, Daniel Pittman
I found myself back in the code today and this comment should be -Jeff |
||
nil | ||
else | ||
yield | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
require 'spec_helper' | ||
require 'facter/util/puppet_settings' | ||
|
||
describe Facter::Util::PuppetSettings do | ||
|
||
describe "#with_puppet" do | ||
context "Without Puppet loaded" do | ||
before(:each) do | ||
Module.expects(:const_get).with("Puppet").raises(NameError) | ||
end | ||
|
||
it 'should be nil' do | ||
subject.with_puppet { Puppet[:vardir] }.should be_nil | ||
end | ||
it 'should not yield to the block' do | ||
Puppet.expects(:[]).never | ||
subject.with_puppet { Puppet[:vardir] }.should be_nil | ||
end | ||
end | ||
context "With Puppet loaded" do | ||
module Puppet; end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is going to have lasting effects on the state of the running process. If order was randomized, and these tests run before the "without" tests, you are going to have failures. That sort of order dependency is not good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
True.
Not true. The way I'm mocking prevents these ordering issues because I'm explicitly With this information, do you think it's still an issue that I'm doing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right, that stubbing does fix things, and I missed it when I looked at the code. I am quite satisfied with this. |
||
let(:vardir) { "/var/lib/puppet" } | ||
|
||
before :each do | ||
Puppet.expects(:[]).with(:vardir).returns vardir | ||
end | ||
it 'should yield to the block' do | ||
subject.with_puppet { Puppet[:vardir] } | ||
end | ||
it 'should return the nodes vardir' do | ||
subject.with_puppet { Puppet[:vardir] }.should eq vardir | ||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def self.with_puppet
is generally preferable - because you can clearly identify each function individually.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Thu, Mar 8, 2012 at 10:13 AM, Daniel Pittman <
[email protected]
Got it, I'll keep this in mind.
For what it's worth, I was livid when I had to go learn about the
eigenclass when I was first getting started with Puppet a few years ago.
I'm surprised at myself for repeating this mistake of using class << self
with the intent of defining a class method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Thu, Mar 8, 2012 at 10:13 AM, Daniel Pittman
[email protected]
wrote:
Should be addressed in #50
-Jeff