(MODULES-3690) Wait on process thread during exit
- When the process exits or the manager factory method has detected a bad manager instance that requires reconstruction, wait for the existing watcher thread to terminate cleanly after asking for a PowerShell child process shutdown. Wait up to 2 seconds before giving up.
(MODULES-3690) Redirect PS stdout to TextWriter
- In 7ff10bf code was added to redirect System.Console.Error to a TextWriter, so that the parent Ruby process shouldn't expect that anything is written over the normal stderr. - This commit adds the same behavior to System.Console.Out - in this case, collecting anything written over this normal .NET mechanism for writing to stdout, and capturing it inside the PowerShell host like Write-XXX cmdlets. The underlying StringWriter instance is actually shared between the PowerShell host and the .NET redirection, so that ordering is preserved (like one would typically see at the console) - Write a test ensuring that any output going through native stdout and the Write-XXX cmdlets is interleaved properly
(MODULES-3690) Add currently failing UTF-8 Tests
- These tests demonstrate that UTF-8 is currently unsupported with the current manager implementation
(MODULES-3690) Reimplement PS with named pipes
- Instead of using the stdin present by popen3, create a separate
NamedPipe listener directly inside the PowerShell code. This can
be written to from Ruby by calling File.Open with a Windows style
.\\.\pipe\ path to the pipe. This File is a Ruby IO instance that
behaves just like the existing streams returned by popen3.
Send commands through this mechanism for several reasons:
- Guarantee the protocol between Ruby client and PowerShell host,
so that any normal PowerShell stdin processing problems are
averted. WMF 5.1 (Windows 10 anniversary update / Windows Server
2016) accidentally made some breaking changes to the stdin
parsing which causes existing code to completely fail. This new
implementation works around that problem completely.
- Strictly control the encoding so that passing UTF-8 values is
not a problem. By using binary data in the pipe, and not
converting to a string until the data has been fully read, this
ensures there are no problems buffering the pipe data / treating
it as a string.
Re-enable previously failing UTF-8 tests as they now pass.
- All values passed to PowerShell from Ruby are length prefixed
in number of bytes (of the current encoding, UTF-8) and lengths
are passed as 32-bit Little Endian.
- The PowerShell code now supports an encoding being passed in, in
addition to the name of the named pipe that is being used. The
encoding defaults to UTF-8 and the named pipe name must be passed
in via Ruby.
Some minor changes have been made to accomodate the new workflow
- The manager, upon creation, must know whether it is operating in
debug mode, so that it can pass that parameter through to the
PowerShell bootstrap process, so that option has been added to
its initializer.
- While prior commits have redirected output written over
[Console]::Out / [Console]::Error to internal StringWriter
instances in the custom PowerShell host, the possibility still
exists that a native binary may access the underlying stdout /
stderr streams, subverting the .NET driven redirection.
While that remains unlikely, ensure that those streams continue to
be drained, so that a deadlock never occurs. This output is
captured and returned so that the provider may emit it if a user
asks for it (via --debug or logoutput parameter).
- If the number of bytes written to the pipe are less than expected
throw an error indicating a broken pipe.
The EPIPE thrown will be caught in exec_read_result like the
existing pipe breakages.
Some tests have been written to demonstrate this behavior.(MODULES-3690) Remove Read-BytesFromStream
- A buffering cmdlet is not necessary here - PipeStream.Read will block until all bytes are ready or an EOF / broken pipe occurs. This function was unnecessary work.
(MODULES-3690) Create PowerShell response protocol
- Length prefix binary responses back to Ruby from PowerShell so that a blocking read can be used within Ruby to wait on response. This removes the need to signal an event from PowerShell that Ruby waits on before it can stop draining pipes. That previous implementation was very Win32 specific, which is a problem for making this module cross-platform. - Make an effort to always wait on completion of all threads inside the read_streams method. Even in the face of crashes / unexpected behavior when reading the pipe, stdout or stderr, all reader threads are expected to cleanly exit. - Mark testing pending that seems to be triggering a w32_reset_event related segfault in Ruby when thread teardown occurs. It's unknown why this crash it triggered by closing the stdout handle, but not the stderr handle. The crash occurs intermittently.
(MODULES-3690) Remove PowerShell to Ruby signal
- Previously, an event name was passed to PowerShell, and it signaled the event when the pipe listener was ready. A simple File.Open style loop can instead be performed against the pipe path to poll it until it's ready. This removes a host of Win32 specific code, and the usage of FFI, which would prevent a cross-platform implementation. Adjustments will still have to be made to the code to make it fully cross-platform, but this code removal is a good start.
(MODULES-3690) Remove XML from IPC comms
- With a binary pipe, there is no reason to use XML anymore as newline terminators are irrelevant. Instead of calling a method that reads until an EOL terminator, length prefix the response, then send an arbitrary number of key value pairs in the format: - length of name (in UTF-8 bytes) - name - length of value (in UTF-8 bytes) - value - PowerShell no longer needs to use literal XML when building a response. - Ruby no longer needs to do anything with REXML
(MODULES-3690) Drain pipes with readpartial
- There's no guarantee that anything written outside of PowerShell Write-XXX cmdlets or .NET [Console]::Out / []Console]::Error has a newline terminator. The IO.gets API in Ruby is a blocking read until the newline terminator is received, and hence may not be appropriate for draining these pipes that are receiving out of band output. Change the behavior so that stdout / stderr pipes are drained with readpartial - that method will read up to the max number of bytes requested, and won't wait until a specific terminator is received. Because the bytes should be UTF-8, which is a multibyte encoding, the string should not have force_encoding called until all the bytes have been received. - This can change the output from stdout / stderr readers to be a single string inside of an array, instead of an array of newline separated strings that was previously created by IO.gets
(MODULES-3690) Remove invalid test comments
- With a move to binary pipes that are not controlled by Ruby, line ending processing is not performed.
Merge pull request #142 from Iristyle/ticket/stable/MODULES-3690-WMF5…
….1-hangs-powershell_manager-custom-IPC (MODULES-3690) Use custom binary pipe IPC
Merge pull request #154 from bmjen/update_stable
DOC-2960: new limitation and a bit of editing
(MODULES-3690) PowerShell Version module
Bring the ability to detect the PowerShell version over from the PowerShell DSC module. Make the adjustment that this version uses `PuppetX::PuppetLabs::PowerShell::PowerShellVersion` instead of just `PuppetX::PuppetLabs::PowerShellVersion` like the DSC module to be more proper and avoid conflicts.
(MODULES-3690) Determine Compatible PowerShell
Determine if the PowerShell version installed is compatible with module. When folks are using PowerShell 3+, they are on .NET Framework 4+, so they are completely compatible with the PowerShell Manager. When folks are using PowerShell v2 and .NET 3.5, they are also compatible, as `System.IO.Pipes` requires at least .NET Framework 3.5. However if they are running PowerShell v2 with .NET 2.0 (which is not going to happen very often, but it represents a base install on Windows Server 2008 and R2), it is not compatible with the PowerShell Manager.
(MODULES-3690) Use v1 functionality in .NET 2.0
If PowerShell v2 and .NET Framework 2.0, the PowerShell manager is not supported.
(MODULES-3690)(doc) Upgrade Message Adjustments
- Rework the wording a bit to make it a bit more succinct. - Add PowerShell v2 with .NET Framework 2.0 as another limitation - Update CTA with ensuring that at least .NET Framework 3.5 is installed.
Merge pull request #155 from ferventcoder/ticket/stable/MODULES-3690-…
…disable_net2.0 (MODULES-3690) PowerShell v2 + .NET Framework less than 3.5 is unsupported for PowerShell Manager
Merge pull request #157 from jpogran/ticket/stable/FM-5728-release-2.0.4
(FM-5728) Update changelog for 2.1.0
(FM-5728) Update changelog date
Release needed a few more days to tie up loose ends
Merge pull request #161 from jpogran/ticket/stable/FM-5728-update-cha…
…nglog-date (FM-5728) Update Changlog Date