(#19162) Execute shutdown command after puppet exits

Previously, there was a race condition between the time that puppet exited and
when the OS rebooted the system. This is because we were requesting a shutdown
(reboot) in `timeout` seconds, but puppet sends a report, which is processed
synchronously by the master. So it was possible for puppet to still be running
when the OS reboots the system.

This commit creates a Watcher class whose job is to wait for the puppet process
to complete, and then execute a command at the end.
(#19162) Create a separate catalog_apply_timeout

Previously, the reboot `timeout` parameter was used both as the maximum amount
of time to wait for puppet to apply the catalog and when the reboot is
requested, as well as the amount of time between when the reboot is requested
and when it is performed.

This commit introduces a catalog_apply_timeout, which defaults to 7200 seconds
(2 hours).
(#19162) Only execute a reboot if puppet finishes

Previously, if the watcher process timed out while waiting for puppet to
finish, or if it failed to wait on the puppet process, then the reboot would be
performed. This could cause problems if puppet was making (slow) progress when
applying the catalog.

This commit changes the watcher process to only execute the shutdown command if
the puppet process exits. If a timeout is reached or it fails to wait on the
process, then a message will be generated that the reboot has been aborted.
(#19162) Ensure parent's stdout isn't closed

Previously, the provider was calling `Open3.popen2` to pipe data to the child
process. However, some combination of popen2 and puppet, likely due to
Puppet::Util::Colors::WideIO, resulted in no additional messages being written
to the console after the call to `popen2`.

I think this is because parent's stdout handle is somehow being closed (perhaps
because it is inherited by the child process), and never reattached to the
:console log destination.

However, we don't actually need to pipe the child's stdout, so this commit
switches to using `Open3.pipeline_w`. This only pipes stdin (parent writes,
child reads). As a result, you will now see messages following the reboot
resource:

    Debug: /Stage[main]//Notify[after]: Transaction canceled, skipping
(#19162) Report on the localized last error code

If we fail to wait on the puppet process, we will now include the localized
GetLastError message, which gives more insight into why it failed.
Merge pull request #4 from joshcooper/ticket/master/19162-reboot

(#19162) Execute shutdown command after puppet exits
(#19162) Gracefully handle when shutdown.exe command cannot be found

Previously, we were executing the x86 version of the shutdown command on x64
Windows. On non-R2 Windows 2003 x64 systems, there is no x86 version and the
sysnative alias is not available without hotfix 942589 installed.

This commit changes the provider to prefer the x64 version of shutdown.exe on
x64 versions of Windows. If the sysnative alias is not available (x86 OS or
2003 x64 without the hotfix), then we fall back to the default `system32`
location. On 2003 non-R2 x64, that will not exist either, so we raise an
exeption.

Paired-with: Rob Reynolds <rob@puppetlabs.com>
(#19162) Restrict example group to systems with the shutdown command

Previously, the `when a reboot is triggered` example group would fail on
Windows 2003 (non-R2) x64, because we could not resolve shutdown.exe into a
fully qualified path, and we would correctly raise an exception.

This commit only executes those tests on systems where the shutdown command can
be resolved.

Paired-with: Rob Reynolds <rob@puppetlabs.com>
(#19162) Finish applying, then reboot

Added apply with two options: immediately (default) and finished. When
`apply => finished`, it allows puppet to finish applying resources and then
reboot the computer at the end of the catalog run.

When someone selects `apply => finished` and `when => pending`, the behavior
will be allowed but will warn that this is an unsupported scenario. I don't
always understand the needs of the users so I didn't want to constrain this
option. If a sufficiently advanced user knows exactly what they are doing and
wants to set this behavior, it should be allowed.
Merge pull request #6 from joshcooper/ticket/master/reboot-when-finished

(#19162) Finish applying, then reboot
(Maint) Handle ruby 1.8.7

Previously, the tests failed on ruby 1.8.7 because it does not reject
symbols like ruby 1.9 does. Also confine the test that uses `spawn` to
not run on ruby 1.8 as that method is not available.
(Maint) Update README.md

Updated readme to follow module guidelines, and updated module version
in preparation for release.