Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-7772

Puppet fails to create error message when an exec fails

    XMLWordPrintable

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Fixed
    • PUP 4.10.2, PUP 4.10.3, PUP 4.10.4, PUP 5.0.0
    • PUP 4.10.5, PUP 5.0.1
    • 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

          Activity

            People

              qa qa
              glenn.sarti Glenn Sarti
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Zendesk Support