(#9546) Make pluginsync copy external facts to client

Pluginsync will now look in moduledir/facts/ for external facts and
copy them to the client under :pluginfactdest (default: $vardir/facts)
(#9546) Use $vardir/external_facts for storing external facts

Puppet loads local ruby facts from "$vardir/lib/facter#{File::PATH_SEPARATOR}$vardir/facts"
so we do not want to store our external facts in this directory.  I
could find no place where $vardir/facts is populated by plugin sync
or any other mechanism so this location must be for facts that do not
belong to a Puppet module and are installed locally on the destination
system.
(#9546) Load external fact directories into facter config
(#9546) Refactoring external fact source and dest to fact.d

The original implementation of this was going to use facts/ as the
source and destination directory.  It turns out the destination
directory facts/ is in use by some outdated code.  So the source and
dest will be switched to facts.d/ which also keeps the naming scheme
consistent with the existing external facts directory
/etc/facter/facts.d
(#9546) Add spec tests for external fact pluginsync
(#9546) Added external fact plugin sync support to plugin face
(#9546) Added feature detection support for external facts

External fact support in puppet core is dependent on facter commit
https://github.com/puppetlabs/facter/commit/6f19eeeef1c5c8e9cc84c44599e03a5c06a30abc
so we need to detect if the installed version of facter is capable
before executing the external fact code
(#22910) Deprecate networked access to resource

The resource indirection isn't safe to be accessible on the master, and
is not functionality that we want to continue to support for the agent.
Instead, users should use mcollective or similar systems for remote
command execution.
(#22910) Deprecate --host on puppet resource

With the networked resource access deprecated, the --host option also
needs to be deprecated so that users can easily see that it is
deprecated. Instead of using Puppet.deprecation_warning, this uses
simply Puppet.warning so that the user isn't presented with a confusing
code location on the command line. This should be ok since the
throttling of the message shouldn't be needed from the CLI environment.
(#9546) Removing PATH_SEPERATOR from pluginfactdest

This is not needed since only one direcrtory will be used for storing
and retrieving pluginsyncd external facts
(#9546) Retrieve module external fact dir from Puppet::Module

Instead of hard coding the external fact directory for modules and
globbing the directories, it would be accurate to have the
Puppet::Module type perform the lookup logic for external fact
directories.   The facts indirector just needs to make sure those
directories get added to the external fact lookup.
(#9546) Update facter specs to support request.environment.modules
(Maint) Clean up code and tests

The way the tests are currently written makes it very hard to get an
overview of all of the behaviors that the code has. This is just the
first step toward getting the tests to be clearer.
(#22918) Lock the filebucket for updates

There were 2 races in the filebucket saving logic:

  1. 2 writers could try to create the `contents` file at the same time.
     This resulted in the writer that loses the race raising an error
     because it did not have write permission to the `contents` file that
     the first writer created.
  2. 2 writers could try updating the `paths` file at the same time.
     This would result in both entering the path in the file thereby
     causing duplicate information in the file. It might also have been
     possible for the two writes to be interleaved in a manner that garbled
     the paths (for instance if the write buffers end up flushing twice in
     an interleaved fashion).

The new method (exclusively_update_file) obtains a LOCK_EX on the
`paths` file before any changes are attempted. This makes the `paths`
file the mutex, not only for updating the paths, but also setting the
contents. This requires that the filesystem supports flock.

Note: the Puppet::Settings.readwritelock method does not work as
intended. It also attempts to get an exclusive lock on a file so that
processes can update it safely, but after testing it out, it actually
does not achieve this. In writing the new method we discovered that the
exclusive lock ability is lost if the update is done using a tempfile
and atomic replace of the file that is locked. When that happens there
is an opportunity for two processes to attain locks and modify the file.
The solution to this was to *only* allow updates-in-place.
(Maint) Introduce File abstraction

Over time we have accumulated various file manipulation operations that
either deal with platform differences of the standard ruby calls or
introduce more useful abstractions for us on top of the ruby calls.
That code has not had a good place to live. Sometimes it appeared on
certain classes, never to be found for use in other areas of the code.
Other times it has been added to the ever growing Puppet::Util mess.

This introduces Puppet::FileSystem::File, which should be used as our
abstraction over ruby's File. We should strive to have it keep a minimal
interface that is geared towards the operations that puppet performs on
files. Inspiration for how to grow it should come, primarily, from uses
found in the puppet codebase as well as from other FS abstraction
systems (such as EFS from eclipse).

This iteration of Puppet::FileSystem::File grew from the file operations
that were done in the filebucket code.
(#22943) Add a spec test to reproduce the failure
(#22943) Remove 2 def_delegator's in favor of explicit method invocations.
(Maint) Allow File to work on ruby 1.8 and 1.9

Ruby 1.8 does not have the same ::File constants as ruby 1.9
(specifically it did not have ::File::BINARY). Instead of using those
constants, the File abstraction will instead use the character-based
file modes (r, r+, w, w+, wb, etc.).

Pathname on ruby 1.8 also does not support binread. To deal with this,
the File now has 2 subclasses File18 and File19 to handle the
differences on the different systems. The File::new method is now a
factory for the appropriate subclass.
(Maint) Improve readability

if ... else ... end was a bit verbose. Ternary conditional is shorter
and easier to read.
(Maint) Compare filebucket contents with streams

The old code required that we completely read into memory both the current
filebucket contents and the new contents. This doubled the amount of ram
needed when checking if the new contents were the same. Instead of
reading in the entire contents, we can instead work from streams and use
the FileUtils.compare_streams method.