Issue #22944 has been updated by Josh Cooper.

Subject changed from External fact is called 6 times to External facts are 
evaluated many times
Target version set to 1.7.4

When you run `facter` it will start by trying to load all facts, e.g. 
`Facter::Util::Collection.load_all`. This walks facter's search path, calling 
`Kernel.load(file)` on each `*.rb` file. When facter loads simple facts of the 
form:

<pre>
Facter.add(:factname) do
  ...
end
</pre>

it registers a `Facter::Util::Fact` object, and appends to its list of 
resolutions for that fact. In other words, we don't actually try to evaluate 
the fact. 

However, some facts resolve other facts outside of their `add` block. For 
example, in `ec2.rb`, we effectively do:

<pre>
if !!(Facter.value(:macaddress) =~ %r{^[dD]0:0[dD]:})
  Facter.add(:ec2) do
    ...
  end
</pre>

The key issue here, is that we try to resolve the `macaddress` fact before 
we've loaded the `macaddress.rb` file and registered a `Facter::Util::Fact` for 
it (because ec2.rb comes before macaddress.rb).

As a result, in `Facter::Util::Collection.load(name)`, we call:

<pre>
    # Try to load the fact if necessary
    load(name) unless @facts[name]
</pre>

where `load(name)` causes all external facts to be evaluated:

<pre>
  def load(name)
    internal_loader.load(name)
    external_loader.load(self) # &lt;---- HERE
</pre>

But the fun doesn't stop there. The `:macaddress` fact has multiple 
resolutions, some confined by `:osfamily`, others `:operatingsystem`, each of 
which triggers all external facts to be evaluated. And actually `:osfamily` 
depends on `:operatingsystem`, so that adds another round of evaluating 
external facts.

The same issue also occurs when evaluating `blockdevices.rb` as that depends on 
the `:kernel` fact:

<pre>
if Facter.value(:kernel) == 'Linux'
  ...
  Facter.add(:blockdevices) do
</pre>

In the short-term, we should ensure we only load external facts once.

----------------------------------------
Bug #22944: External facts are evaluated many times
https://projects.puppetlabs.com/issues/22944#change-99836

* Author: Matthias Baur
* Status: Accepted
* Priority: Normal
* Assignee: 
* Category: 
* Target version: 1.7.4
* Keywords: 
* Branch: 
* Affected Facter version: 1.7.3
----------------------------------------
** Reproduction **

* Drop script /etc/facter/facts.d/test.sh:
<pre>
#!/bin/bash
echo "SCRIPT CALLED" >&2
echo "test=value"
</pre>
* Make script executeable
<pre>
chmod +x /etc/facter/facts.d/test.sh
</pre>
* Call 'facter', the following output is shown:
<pre>
root@puppet:~# facter
SCRIPT CALLED
SCRIPT CALLED
SCRIPT CALLED
SCRIPT CALLED
SCRIPT CALLED
SCRIPT CALLED
...
Regular facter output
...
</pre>

I don't see a reason why the script is called 6 times.

System information

* Ubuntu 12.04.3
* Facter 1.7.3


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

Reply via email to