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

Unable to install a Ruby gem to non-Puppet Ruby stack using the package resource type on Windows

    Details

    • Template:
    • Acceptance Criteria:
      • Ability to opt-in to behavior where Puppet's vendored Ruby is not in the PATH.
    • Team:
      Night's Watch
    • Story Points:
      3
    • Sprint:
      NW - 2019-08-21, NW - 2019-09-03, NW - 2019-09-18
    • CS Priority:
      Minor
    • CS Frequency:
      1 - 1-5% of Customers
    • CS Severity:
      2 - Annoyance
    • CS Business Value:
      3 - $$$$
    • CS Impact:
      This can be worked around via an exec. It's another tick against supporting windows as a first class citizen in our ecosystem.
    • Release Notes:
      Not Needed
    • QA Risk Assessment:
      Automate

      Description

      Puppet is unable to install a Ruby gem into anything other than Puppet's Ruby stack on Windows nodes.

      Example of the issue

      For example, say I want to install the puppet-lint gem so that I can validate Puppet code while writing modules. Normally, I'd install Ruby from http://rubyinstaller.org/ then run gem install puppet-lint. But, let's say I wanted to automate that process using Puppet! First, I would install Chocolatey then use Chocolatey to install Ruby:

      include chocolatey
      package { 'ruby':
        ensure   => present,
        provider => 'chocolatey',
        require  => Class['chocolatey'],
      }
      

      Then I'd use the gem provider to install puppet-lint:

      package { 'puppet-lint':
        ensure   => present,
        provider => 'gem',
        require  => Package['ruby'],
      }
      

      A --debug log of that package installation looks like this:

      C:\Users\Administrator>puppet resource package puppet-lint ensure=present provider=gem --debug
      (... removing Facter resolution messages ...)
      Debug: /Package[puppet-lint]: Provider gem does not support features virtual_packages; not managing attribute allow_virtual
      Debug: Loaded state in 0.03 seconds
      Debug: Evicting cache entry for environment 'production'
      Debug: Caching environment 'production' (ttl = 0 sec)
      Debug: Evicting cache entry for environment 'production'
      Debug: Caching environment 'production' (ttl = 0 sec)
      Debug: Evicting cache entry for environment 'production'
      Debug: Caching environment 'production' (ttl = 0 sec)
      Debug: Evicting cache entry for environment 'production'
      Debug: Caching environment 'production' (ttl = 0 sec)
      Debug: Failed to load library 'selinux' for feature 'selinux'
      Debug: Prefetching gem resources for package
      Debug: Executing: 'C:/Program Files/Puppet Labs/Puppet/sys/ruby/bin/gem.bat list --local'
      Debug: Finishing transaction 39019400
      Debug: Storing state
      Debug: Stored state in 0.05 seconds
      package { 'puppet-lint':
        ensure => ['1.1.0'],
      }
      

      After doing this, the puppet-lint executable is not available in %PATH%, and gem list doesn't show puppet-lint as installed:

      C:\Users\Administrator>puppet-lint
      'puppet-lint' is not recognized as an internal or external command,
      operable program or batch file.
      C:\Users\Administrator>gem list
       
      *** LOCAL GEMS ***
       
      bigdecimal (1.2.6)
      io-console (0.4.3)
      json (1.8.1)
      minitest (5.4.3)
      power_assert (0.2.2)
      psych (2.0.8)
      rake (10.4.2)
      rdoc (4.2.0)
      test-unit (3.0.8)
       
      C:\Users\Administrator>
      

      But, if I use's Puppet's gem command, I see that puppet-lint got installed into Puppet's Ruby stack:

      C:\Users\Administrator>"C:\Program Files\Puppet Labs\Puppet\sys\ruby\bin\gem.bat" list
       
      *** LOCAL GEMS ***
       
      bigdecimal (1.2.4)
      deep_merge (1.0.1)
      ffi (1.9.10 x64-mingw32)
      io-console (0.4.3, 0.4.2)
      json (1.8.1)
      minitar (0.5.4)
      minitest (4.7.5)
      psych (2.0.5)
      puppet-lint (1.1.0)
      rake (10.1.0)
      rdoc (4.1.0)
      stomp (1.3.3)
      test-unit (2.1.8.0, 2.1.7.0, 2.1.6.0, 2.1.5.0)
      win32-dir (0.4.9)
      win32-eventlog (0.6.2)
      win32-process (0.7.4)
      win32-security (0.2.5)
      win32-service (0.8.6)
      

      Likely Cause

      Puppet is putting its bin directory at the start of %PATH% during all invocations of puppet, which causes the gem provider to find Puppet's gem command rather than the gem command I installed via chocolatey.
      This is happening in environment.bat which puppet.bat always invokes:

      ...
      SET PATH=%PUPPET_DIR%\bin;%FACTERDIR%\bin;%HIERA_DIR%\bin;%MCOLLECTIVE_DIR%\bin;%PL_BASEDIR%\bin;%PL_BASEDIR%\sys\ruby\bin;%PL_BASEDIR%\sys\tools\bin;%PATH%
      ...
      

      On the command line, I can install gems into my Ruby stack from Chocolatey without issue:

      C:\Users\Administrator>where gem
      C:\tools\ruby22\bin\gem
      C:\tools\ruby22\bin\gem.bat
       
      C:\Users\Administrator>gem install gist
      Fetching: gist-4.5.0.gem (100%)
      Successfully installed gist-4.5.0
      Parsing documentation for gist-4.5.0
      Installing ri documentation for gist-4.5.0
      Done installing documentation for gist after 0 seconds
      1 gem installed
       
      C:\Users\Administrator>gem list --local
       
      *** LOCAL GEMS ***
       
      bigdecimal (1.2.6)
      gist (4.5.0)
      io-console (0.4.3)
      json (1.8.1)
      minitest (5.4.3)
      power_assert (0.2.2)
      psych (2.0.8)
      rake (10.4.2)
      rdoc (4.2.0)
      test-unit (3.0.8)
      

      But when Puppet runs, the %PATH% gets re-written to have Puppet's BIN dir at the start:

      C:\Users\Administrator>echo %PATH%
      C:\ProgramData\chocolatey\bin;C:\tools\ruby22\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Git\cmd;C:\Program Files (x86)\Git\bin;C:\Program Files\Puppet Labs\Puppet\bin
       
      C:\Users\Administrator>puppet apply -e "notice($::path)"
      Notice: Scope(Class[main]): C:/Program Files/Puppet Labs/Puppet/facter/bin;C:\Program Files\Puppet Labs\Puppet\puppet\bin;C:\Program Files\Puppet Labs\Puppet\facter\bin;C:\Program Files\Puppet Labs\Puppet\hiera\bin;C:\Program Files\Puppet Labs\Puppet\mcollective\bin;C:\Program Files\Puppet Labs\Puppet\bin;C:\Program Files\Puppet Labs\Puppet\sys\ruby\bin;C:\Progr
      am Files\Puppet Labs\Puppet\sys\tools\bin;C:\ProgramData\chocolatey\bin;C:\tools\ruby22\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Git\cmd;C:\Program Files (x86)\Git\bin;C:\Program Files\Puppet Labs\Puppet\bin
      Notice: Compiled catalog for pe-201533-agent-win2012 in environment production in 0.03 seconds
      Notice: Applied catalog in 0.09 seconds
      

        Attachments

          Issue Links

            Activity

              jsd-sla-details-panel

                People

                • Assignee:
                  gheorghe.popescu Gheorghe Popescu
                  Reporter:
                  nate.mccurdy Nate McCurdy
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  17 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved:

                    Zendesk Support