Issue #21577 has been updated by Andrew Parker.
Investigation for this has taken down into a few areas of the facter and puppet
interaction that are likely the root cause of this. However, I've also
confirmed a workaround.
The workaround for the issue is to make sure that no values for the facts are
decided upon outside of the `setcode` block. Anything outside of that will not
be able to rely on the order in which facts will be available. In general this
is the right way to write facts anyway and so should not be a large
inconvenience. For the tu_gateway_default fact, the transformation is very
simple, just move the code that is outside the `Facter.add` code to be inside
the `setcode` block. For the `tu_affinity_tier.rb` file, the transformation is
a little more complicated, but not much.
The current code follows a pattern that looks like
<pre>
gateway = Facter.value(:tu_gateway_default)
octet1, octet2, octet3, octet4 = gateway.split('.')
case octet2
when '209'
case octet3
when '64'
affinity = 'some value'
tier = 'other value'
# many other cases for octet3
else
affinity = 'not_defined'
tier = 'not_defined'
end
# many other cases for octet2 and octet3
else
affinity = 'not_defined'
tier = 'not_defined'
end
Facter.add(:tu_affinity) do
setcode do
affinity
end
end
</pre>
The pattern that shows up is that the default is always the same when something
can't be found and the only two parts that matter are octet2 and octet3. This
can be easily translated into a lookup table that is then looked into
<pre>
UNKNOWN = {
:affinity => 'not_defined',
:tier => 'not_defined'
}
LOOKUP = {
'209' => {
'64' => {
:affinity => 'some value',
:tier => 'other value'
}
# other known values for the octet3
}
# all of the other combinations for octet2/octet3
}
Facter.add(:tu_affinity) do
setcode do
_, octet2, octet3, _ = Facter.value(:tu_gateway_default).split('.')
section = LOOKUP[octet2] || {}
specific = section[octect3] || UNKOWN
specific[:affinity]
end
end
Facter.add(:tu_tier) do
setcode do
_, octet2, octet3, _ = Facter.value(:tu_gateway_default).split('.')
section = LOOKUP[octet2] || {}
specific = section[octect3] || UNKOWN
specific[:tier]
end
end
</pre>
There is a little bit of duplication between the two facts, but they now don't
try to look anything up until needed. The duplication could be handled but I
decided not to in order to reduce the number of pieces needed.
----------------------------------------
Bug #21577: Facter appears to "lose" the FACTERLIB / factpath path under
certain conditions on AIX.
https://projects.puppetlabs.com/issues/21577#change-94787
* Author: Zachary Stern
* Status: Accepted
* Priority: Normal
* Assignee:
* Category:
* Target version:
* Keywords: customer
* Branch:
* Affected Facter version: 1.6.17
----------------------------------------
It appears that under a certain scenario, when using custom facts, facter on AIX
"loses" FACTERLIB / factpath during puppet runs. The setting `factpath` is
somehow not being honored.
I'm unable to figure out what the exact cause is, but I am able to
provide steps to reproduce the error.
The two attached custom facts exhibit this issue, tested with PE 2.8.1
on AIX 6.1.
When these facts are synced to the AIX agent via pluginsync, the
following is output during a run:
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/tu_affinity_tier.rb
warning: Could not load fact file
/opt/freeware/var/lib/pe-puppet/lib/facter/tu_affinity_tier.rb: private method
`split' called for nil:NilClass
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/tu_gateway_default.rb
The facts in tu_affinity_tier.rb depend on the tu_gateway_default fact.
When this fact (tu_gateway_default) is loaded inside of the
tu_affinity_tier.rb file during a puppet run, as such - `gateway =
Facter.value(:tu_gateway_default)` - it returns nil, and gateway is set
to nil.
However, the tu_gateway_default fact definitely works, and does not
return nil. `facter -p tu_gateway_default` returns the default gateway of
tha AIX system, as expected.
In addition, the two facts in tu_affinity_tier.rb also seem to work
outside of puppet. E.g. if I copy tu_affinity_tier.rb to my home directory and
modify it with a require 'facter' at the beginning, and run it in pry, I
receive the following:
bash-3.2# export FACTERLIB=`puppet agent --configprint factpath | awk '{
print $1 }'`
bash-3.2# echo $FACTERLIB
/opt/freeware/var/lib/pe-puppet/lib/facter:/opt/freeware/var/lib/pe-puppet/facts
bash-3.2# /opt/puppet/bin/ruby tu_affinity_tier.rb
bash-3.2#
As you can see, no error about calling split on nil is thrown. However,
if I remove facterlib, e.g. `unset FACTERLIB` we do get the split on nil
error, since of course facter doesn't know where the custom facts are
when we use it in this way. E.g.:
bash-3.2# unset FACTERLIB
bash-3.2# echo $FACTERLIB
bash-3.2# /opt/puppet/bin/ruby tu_affinity_tier.rb
tu_affinity_tier.rb:5: private method `split' called for nil:NilClass
(NoMethodError)
To confirm this hypothesis, I set the code in tu_affinity_tier to use
builtin fact like ipaddress, instead of the custom fact. This way,
FACTERLIB / factpath doesn't come into play. It then works perfectly
fine. E.g. if we
change `gateway = Facter.value(:tu_gateway_default)` to `gateway =
Facter.value(:ipaddress)`, and do a puppet run, the error goes away.
All this despite the fact that the tu_gateway_default fact definitely
works, and does not, on its own, return nil. E.g.:
bash-3.2# facter -p tu_gateway_default
10.16.77.1
In addition, the facts themselves work fine outside of a puppet run, when we
call them directly, e.g.:
bash-3.2# export FACTERLIB=`puppet agent --configprint factpath | awk
'{ print $1 }'`
bash-3.2# /opt/puppet/bin/pry
[1] pry(main)> require 'facter'
=> true
[2] pry(main)> Facter.value(:tu_affinity)
=> "not_defined"
(yeah, I'm using pry on AIX; what of it?)
Note that "not_defined" is a valid resuilt for that fact.
So, the code in tu_affinity_tier.rb is evaluated and no error is thrown. It
ONLY happens when the code is evaluated within the scope of a puppet run. E.g.:
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/tu_affinity_tier.rb
warning: Could not load fact file
/opt/freeware/var/lib/pe-puppet/lib/facter/tu_affinity_tier.rb: private method
`split' called for nil:NilClass
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/tu_gateway_default.rb
HOWEVER, if I do a puppet run after explictly setting facterlib as a shell
variable, there's no problem:
bash-3.2# export FACTERLIB=`puppet agent --configprint factpath | awk
'{ print $1 }'`
bash-3.2# puppet agent -t
info: Retrieving plugin
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/concat_basedir.rb
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/custom_auth_conf.rb
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/facter_dot_d.rb
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/pe_version.rb
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/puppet_vardir.rb
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/root_home.rb
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/tu_affinity_tier.rb
info: Loading facts in
/opt/freeware/var/lib/pe-puppet/lib/facter/tu_gateway_default.rb
info: Caching catalog for pe-aix-61-support
info: Applying configuration version '1372791873'
notice: Finished catalog run in 2.82 seconds
Ta-da!
So it looks like puppet on AIX is somehow "forgetting" the factpath parameter,
under some specific scenario.
--
You have received this notification because you have either subscribed to it,
or are involved in it.
To change your notification preferences, please click here:
http://projects.puppetlabs.com/my/account
--
You received this message because you are subscribed to the Google Groups
"Puppet Bugs" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-bugs.
For more options, visit https://groups.google.com/groups/opt_out.