Skip to content

Commit 87408be

Browse files
author
Erick Banks
authored
Merge pull request #250 from glennsarti/fix-pipe-reader
(MODULES-8748) Improve pipe reading in the PowerShell Manager
2 parents a250d39 + 1e8932d commit 87408be

File tree

12 files changed

+69
-49
lines changed

12 files changed

+69
-49
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@
2222
/convert_report.txt
2323
/update_report.txt
2424
.DS_Store
25+
.project
26+
.vscode/
27+
.envrc
28+
/inventory.yaml

.pdkignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
/convert_report.txt
2323
/update_report.txt
2424
.DS_Store
25+
.project
26+
.vscode/
27+
.envrc
28+
/inventory.yaml
2529
/appveyor.yml
2630
/.fixtures.yml
2731
/Gemfile
@@ -30,6 +34,7 @@
3034
/.gitlab-ci.yml
3135
/.pdkignore
3236
/Rakefile
37+
/rakelib/
3338
/.rspec
3439
/.rubocop.yml
3540
/.travis.yml

.project

Lines changed: 0 additions & 23 deletions
This file was deleted.

.sync.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,9 @@ spec/default_facts.yml:
2727
.travis.yml:
2828
unmanaged: true
2929

30+
# Due to https://github.com/puppetlabs/pdk-templates/issues/229 we can't manage Appveyor yet.
31+
appveyor.yml:
32+
unmanaged: true
33+
3034
.gitlab-ci.yml:
3135
delete: true

.travis.yml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
---
2+
os:
3+
- linux
4+
# OSX Only tests on the latest Puppet Gem, not the full matrix as there's no need to double up
5+
# testing effort here. We are only concerned about whether the Mac OSX edition of PowerShell Core
6+
# will work with our PowerShell manager code.
7+
- osx
8+
29
dist: trusty
310
language: ruby
411
cache: bundler
512
before_install:
613
# Additional instructions
7-
- curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
8-
- curl https://packages.microsoft.com/config/ubuntu/14.04/prod.list | sudo tee /etc/apt/sources.list.d/microsoft.list
9-
- sudo apt-get update
10-
- sudo apt-get install -y powershell
14+
- bash <(curl -s https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) -skip-sudo-check
15+
# Output the PowerShell Core version information
16+
- pwsh -NoProfile -NoLogo -NonInteractive -Command \$PSVersionTable
1117
- if [ $BUNDLER_VERSION ]; then
1218
gem install -v $BUNDLER_VERSION bundler --no-rdoc --no-ri;
1319
fi
@@ -24,18 +30,17 @@ rvm:
2430
env:
2531
global:
2632
- BEAKER_PUPPET_COLLECTION=puppet6 PUPPET_GEM_VERSION="~> 6.0"
33+
- CHECK=parallel_spec
2734
matrix:
2835
fast_finish: true
2936
include:
3037
-
3138
env: CHECK="syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop"
3239
-
33-
env: CHECK=parallel_spec
34-
-
35-
env: PUPPET_GEM_VERSION="~> 5.0" CHECK=parallel_spec
40+
env: PUPPET_GEM_VERSION="~> 5.0"
3641
rvm: 2.4.4
3742
-
38-
env: PUPPET_GEM_VERSION="~> 4.0" CHECK=parallel_spec RUBYGEMS_VERSION=2.7.8 BUNDLER_VERSION=1.17.3
43+
env: PUPPET_GEM_VERSION="~> 4.0" RUBYGEMS_VERSION=2.7.8 BUNDLER_VERSION=1.17.3
3944
rvm: 2.1.9
4045
branches:
4146
only:

Rakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ end
2222

2323
def changelog_future_release
2424
return unless Rake.application.top_level_tasks.include? "changelog"
25-
returnVal = JSON.load(File.read('metadata.json'))['version']
25+
returnVal = "v%s" % JSON.load(File.read('metadata.json'))['version']
2626
raise "unable to find the future_release (version) in metadata.json" if returnVal.nil?
2727
puts "GitHubChangelogGenerator future_release:#{returnVal}"
2828
returnVal

appveyor.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ install:
3939
- set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
4040
- bundle install --jobs 4 --retry 2 --without system_tests
4141
- type Gemfile.lock
42+
- ps: "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri https://github.com/PowerShell/PowerShell/raw/master/tools/install-powershell.ps1 -UseBasicParsing -OutFile install-pwsh.ps1"
43+
- ps: "& ./install-pwsh.ps1"
44+
- set PATH=%LOCALAPPDATA%\Microsoft\powershell;%PATH%
45+
- pwsh -NoProfile -NoLogo -NonInteractive -Command $PSVersionTable
46+
- powershell -NoProfile -NoLogo -NonInteractive -Command $PSVersionTable
4247
build: off
4348
test_script:
4449
- bundle exec puppet -V

lib/puppet_x/puppetlabs/powershell/powershell_manager.rb

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ def self.instance_key(cmd, args, options)
274274
def self.is_readable?(stream, timeout = 0.5)
275275
raise Errno::EPIPE if !is_stream_valid?(stream)
276276
read_ready = IO.select([stream], [], [], timeout)
277-
read_ready && stream == read_ready[0][0]
277+
read_ready && stream == read_ready[0][0] && !stream.eof?
278278
end
279279

280280
# when a stream has been closed by handle, but Ruby still has a file
@@ -395,17 +395,16 @@ def read_streams
395395
# read a Little Endian 32-bit integer for length of response
396396
expected_response_length = pipe.sysread(4).unpack('V').first
397397

398-
if expected_response_length == 0
399-
nil
400-
else
401-
# reads the expected bytes as a binary string or fails
402-
buffer = ""
403-
# Reads in the pipe data 8K, or less, at a time
404-
while (buffer.length < expected_response_length)
405-
buffer << pipe.sysread([expected_response_length - buffer.length, 8192].min)
406-
end
407-
buffer
398+
next nil if expected_response_length == 0
399+
# reads the expected bytes as a binary string or fails
400+
buffer = ""
401+
# sysread may not return all of the requested bytes due to buffering or the
402+
# underlying IO system. Keep reading from the pipe until all the bytes are read
403+
loop do
404+
buffer.concat(pipe.sysread(expected_response_length - buffer.length))
405+
break if buffer.length >= expected_response_length
408406
end
407+
buffer
409408
end
410409

411410
Puppet.debug "Waited #{Time.now - start_time} total seconds."

lib/puppet_x/templates/powershell/init_ps.ps1

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -723,10 +723,23 @@ function ConvertTo-PipeCommand
723723

724724
# Read blocks until all bytes are read or EOF / broken pipe hit - tested with 5MB and worked fine
725725
$parsed.RawData = New-Object Byte[] $parsed.Length
726-
$read = $Stream.Read($parsed.RawData, 0, $parsed.Length)
727-
if ($read -lt $parsed.Length)
726+
$readBytes = 0
727+
do {
728+
$attempt = $attempt + 1
729+
# This will block if there's not enough data in the pipe
730+
$read = $Stream.Read($parsed.RawData, $readBytes, $parsed.Length - $readBytes)
731+
if ($read -eq 0)
732+
{
733+
throw "Catastrophic failure: Expected $($parsed.Length - $readBytesh) raw bytes, but the pipe reached an end of stream"
734+
}
735+
736+
$readBytes = $readBytes + $read
737+
Write-SystemDebugMessage -Message "Read $($read) bytes from the pipe"
738+
} while ($readBytes -lt $parsed.Length)
739+
740+
if ($readBytes -lt $parsed.Length)
728741
{
729-
throw "Catastrophic failure: Expected $($parsed.Length) raw bytes, only received $read"
742+
throw "Catastrophic failure: Expected $($parsed.Length) raw bytes, only received $readBytes"
730743
}
731744

732745
# turn the raw bytes into the expected encoded string!

metadata.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,5 @@
7676
],
7777
"pdk-version": "1.8.0",
7878
"template-url": "https://github.com/puppetlabs/pdk-templates",
79-
"template-ref": "heads/master-0-g7281db5"
80-
}
79+
"template-ref": "heads/master-0-ga6554ab"
80+
}

0 commit comments

Comments
 (0)