(#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