Search code examples
rubypuppetrspec-puppet

How do I fix psych module not being found or being the right version Ruby


I get the following error when trying to do anything with Ruby, specifically ruby gems:

/usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/2.4.0/yaml.rb:5:in `<top (required)>':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
/usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:130:in `require': incompatible library version - /usr/local/rvm/gems/ruby-2.4.5/gems/psych-3.1.0/lib/psych.so (LoadError)
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:130:in `rescue in require'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:34:in `require'
    from /usr/local/rvm/gems/ruby-2.4.5/gems/psych-3.1.0/lib/psych.rb:16:in `rescue in <top (required)>'
    from /usr/local/rvm/gems/ruby-2.4.5/gems/psych-3.1.0/lib/psych.rb:13:in `<top (required)>'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/2.4.0/yaml.rb:6:in `<top (required)>'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems.rb:729:in `load_yaml'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/config_file.rb:349:in `load_file'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/config_file.rb:202:in `initialize'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/gem_runner.rb:79:in `new'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/gem_runner.rb:79:in `do_configuration'
    from /usr/local/rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/rubygems/gem_runner.rb:44:in `run'
    from /usr/local/rvm/rubies/ruby-2.4.5/bin/gem:21:in `<main>'

I believe the line of note is this one:

LoadError: incompatible library version - /usr/local/rvm/gems/ruby-2.4.5/gems/psych-3.1.0/lib/psych.so

I get this from gem install puppet, gem update, etc. I tried uninstalling and reinstalling libyaml, and same with Ruby. The error happened after I did bundle uninstall puppet to get it to stop pointing to the 6.3.0 gem and point to the 4.10.2 executable. I need Ruby to be able to use Rspec to test the modules. Does anyone know how I can fix this?


Solution

  • Without steps to reproduce the broken system it is hard to say what happened, but I can say in general how you can set this up correctly to use a specific version of Puppet.

    Does this help? In the worst case, you can probably uninstall RVM and reinstall it.


    Before I continue, let me note that Puppet 4.10.2 and 4.10.3 have both been removed from Rubygems. (Although I was able to install it with PDK.)

    For the remainder I assume 4.10.4 instead (just to distinguish it from latest 4.10).


    The recommended approach is to use Puppet Development Kit (pdk). If you download and install PDK, you probably just need to do these steps:

    pdk convert
    rm Gemfile.lock
    PUPPET_GEM_VERSION=4.10.4 bundle update # If that version isn't already in PDK.
    pdk test unit --puppet-version 4.10.4
    

    If you don't want to go down the PDK path, you can try these alternatives:

    1. Hardcode the version of Puppet you want in Gemfile.
    gem 'puppet', '4.10.4'
    

    Or:

    gem 'puppet', '~> 4.10' # latest 4.10
    

    Then update your bundle:

    rm -f Gemfile.lock
    bundle update
    
    1. Or, you can implement the PUPPET_GEM_VERSION feature by adding this code (this is what I do, for what it's worth):
    if puppetversion = ENV['PUPPET_GEM_VERSION']
      gem 'puppet', puppetversion
    else
      gem 'puppet'
    end
    

    And then:

    rm -f Gemfile.lock
    PUPPET_GEM_VERSION='~> 4.10' bundle update
    

    Now you can run your unit tests against a specific version of Puppet per normal:

    bundle exec rake spec
    

    Or however you set it up.