Details
-
Bug
-
Status: Closed
-
Critical
-
Resolution: Fixed
-
PUP 4.10.2, PUP 4.10.3, PUP 4.10.4, PUP 5.0.0
-
None
-
None
-
Windows Server 2012R2
Ruby 2.4.1 32 or 64bit
Chocolatey Module spec tests
Puppet 5.0 gem
-
- Should be a spec test to exercise this behaviour
-
Agent
-
1
-
Agent 2017-07-26
-
Automated Test
-
Bug Fix
-
Puppet 4.10.2 and 5.0.0 introduced a regression if a provider called {{execpipe}} and the external command failed. This ticket fixes puppet so that it correctly processes the execution failure.
-
No Action
-
Covered by spec tests
Description
The chocolatey module was failing spec tests on Ruby 2.4.0 and Puppet 5. example output
https://ci.appveyor.com/project/puppetlabs/puppetlabs-chocolatey/build/1.1.x.379/job/8k8kvkt9moka317t
...
|
Failures:
|
1) Puppet::Type::Package::ProviderChocolatey when fetching a package list should invoke provider listcmd
|
Failure/Error:
|
execpipe(listcmd) do |process|
|
process.each_line do |line|
|
line.chomp!
|
if line.empty? or line.match(/Reading environment variables.*/); next; end
|
raise Puppet::Error, "At least one source must be enabled." if line.match(/Unable to search for packages.*/)
|
if choco_exe
|
values = line.split('|')
|
else
|
values = line.split(' ')
|
end
|
NoMethodError:
|
undefined method `encoding' for #<IO:(closed)>
|
Did you mean? set_encoding
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/puppet-5.0.0-x86-mingw32/lib/puppet/util/character_encoding.rb:93:in `scrub'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/puppet-5.0.0-x86-mingw32/lib/puppet/error.rb:6:in `initialize'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/puppet-5.0.0-x86-mingw32/lib/puppet/util/execution.rb:86:in `exception'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/puppet-5.0.0-x86-mingw32/lib/puppet/util/execution.rb:86:in `raise'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/puppet-5.0.0-x86-mingw32/lib/puppet/util/execution.rb:86:in `execpipe'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/puppet-5.0.0-x86-mingw32/lib/puppet/provider.rb:117:in `execpipe'
|
# ./lib/puppet/provider/package/chocolatey.rb:198:in `instances'
|
# ./spec/unit/puppet/provider/package/chocolatey_spec.rb:432:in `block (3 levels) in <top (required)>'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:254:in `instance_exec'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:254:in `block in run'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:500:in `block in with_around_and_singleton_context_hooks'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:457:in `block in with_around_example_hooks'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:464:in `block in run'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:602:in `run_around_example_hooks_for'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:464:in `run'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:457:in `with_around_example_hooks'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:500:in `with_around_and_singleton_context_hooks'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:251:in `run'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:627:in `block in run_examples'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:623:in `map'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:623:in `run_examples'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:589:in `run'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590:in `block in run'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590:in `map'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590:in `run'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:118:in `block (3 levels) in run_specs'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:118:in `map'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:118:in `block (2 levels) in run_specs'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/configuration.rb:1894:in `with_suite_hooks'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:113:in `block in run_specs'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/reporter.rb:79:in `report'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:112:in `run_specs'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:87:in `run'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:71:in `run'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:45:in `invoke'
|
# C:/Ruby24/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/exe/rspec:4:in `<top (required)>'
|
# C:/Ruby24/bin/rspec:23:in `load'
|
# C:/Ruby24/bin/rspec:23:in `<main>'
|
Finished in 2.06 seconds (files took 2.91 seconds to load)
|
194 examples, 1 failure
|
Failed examples:
|
Further digging found:
1. The spec test is ending up with a nil value for the command_str which causes the open command to error
https://github.com/puppetlabs/puppet/blame/master/lib/puppet/util/execution.rb#L80
2. This error is then caught however instead of output having the output of the command, it has the output of the failed open state, i.e. an IO<closed> object
3. This is then raised as an error at
https://github.com/puppetlabs/puppet/blame/master/lib/puppet/util/execution.rb#L86
4. The error class is then initialized and the new scrub function called at;
https://github.com/puppetlabs/puppet/blame/master/lib/puppet/error.rb#L6
5. The scrub function at;
https://github.com/puppetlabs/puppet/blame/master/lib/puppet/util/character_encoding.rb#L89-L96
Then tries to scrub the object, however it assumes that it's a string, but what's passed in is an IO object. This then fails on (https://github.com/puppetlabs/puppet/blame/master/lib/puppet/util/character_encoding.rb#L89-L96) because it does not have an encoding method.
This only appears to have started in Puppet 5.
Possible resolutions:
1. Scrub function should not assume it's a string coming in. If it's not a string, just spit the original value out.
2. The execpipe should not assume the output is a string and should cast output to a string prior to raising the error message
Attachments
Issue Links
- is duplicated by
-
PUP-7782 execpipe raises method error if the command fails with no output
-
- Closed
-
- relates to
-
PUP-7498 Puppet merges two users in different encodings into one
-
- Closed
-
-
MODULES-5187 modsync for Puppet 5/Ruby 2.4
-
- Resolved
-