-
Notifications
You must be signed in to change notification settings - Fork 291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
This makes sensu_gem work as advertised #877
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable, a couple questions/suggestions.
@@ -15,6 +15,9 @@ | |||
if RUBY_PLATFORM =~ /cygwin|mswin|mingw|bccwin|winse|emx/ | |||
"#{ENV['SYSTEMDRIVE']}\\opt\\sensu\\embedded\\bin\\gem.cmd" | |||
else | |||
# grab the newest version available of the embedded ruby | |||
embedded_rvm_version = Dir.glob(File.join('/opt/sensu/embedded/lib/ruby/gems/', '*')).max { |a,b| File.ctime(a) <=> File.ctime(b) } | |||
ENV['GEM_PATH'] = "/opt/sensu/embedded/lib/ruby/gems/#{embedded_rvm_version}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disclaimer I come from a chef world so I have very little idea on the internals of puppet. Would the ENV var be passed down to where it actually executes it? This function just gets the command not runs it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also was thinking about, "where should I put this?" My gut feeling is that if we have to use the embedded ruby, it's also appropriate to setup the ENV. Conversely we would not want to change the environment if we weren't using the sensu_gem provider. This sets up the environment only for the context of puppet, this isn't a system-wide change, so all the RVM stuff will remain untouched for everyone else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right but is that for the entire puppet process or just for this particular resource. I worry that it might interfere if say you are installing a system wide gem with rvm in puppet. Another question is chef also has it's own embedded ruby which I am not sure if puppet does, can you install gems in puppet into it's own embedded gems? If so this might also break that as well. Hopefully someone with more puppet experience than me can review and provide some better feedback.
@@ -15,6 +15,9 @@ | |||
if RUBY_PLATFORM =~ /cygwin|mswin|mingw|bccwin|winse|emx/ | |||
"#{ENV['SYSTEMDRIVE']}\\opt\\sensu\\embedded\\bin\\gem.cmd" | |||
else | |||
# grab the newest version available of the embedded ruby | |||
embedded_rvm_version = Dir.glob(File.join('/opt/sensu/embedded/lib/ruby/gems/', '*')).max { |a,b| File.ctime(a) <=> File.ctime(b) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a clever solution would you mind linking to the documentation? To those that are new to ruby this would be helpful.
Incidentally I'm not the best ruby person either but I can bang stuff out. I've added comments to the one liner to explain it a bit. |
@majormoses I know you're positively holding your breath over this. ;) I used rvm to install paperclip, which is something neither we use nor sensu uses. I verified in my vagrant installation that this is installed to the normal systemwide, rvm managed gempath. It looks like this change only affects the instantiation of sensu_gem, which is definitely what we want. |
Awesome I was watching it as I like learning stuff about different technologies. I am not a maintainer on the puppet module since there are people who know this stuff much better than I do. ping @ghoneycutt |
# rip through everything in the directory and keep the newest one per comparison, omitting . and .. | ||
# there's probably a faster/prettier way of doing this. | ||
embedded_rvm_version = Dir.glob(File.join('/opt/sensu/embedded/lib/ruby/gems/', '*')).max { |a,b| File.ctime(a) <=> File.ctime(b) } | ||
ENV['GEM_PATH'] = "/opt/sensu/embedded/lib/ruby/gems/#{embedded_rvm_version}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite get what's going on here. It seems that an environment variable is being set to look in "/opt/sensu/embedded/lib/ruby/gems/#{embedded_rvm_version}"
though then we still return a different path of "/opt/sensu/embedded/bin/gem"
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Please observe the effect on GEM PATHS...
[root@vagrant ~]# gem env
RubyGems Environment:
- RUBYGEMS VERSION: 2.6.14
- RUBY VERSION: 2.4.0 (2016-12-24 patchlevel 0) [x86_64-linux]
- INSTALLATION DIRECTORY: /usr/local/rvm/gems/ruby-2.4.0
- USER INSTALLATION DIRECTORY: /root/.gem/ruby/2.4.0
- RUBY EXECUTABLE: /usr/local/rvm/rubies/ruby-2.4.0/bin/ruby
- EXECUTABLE DIRECTORY: /usr/local/rvm/gems/ruby-2.4.0/bin
- SPEC CACHE DIRECTORY: /root/.gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /etc
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-linux
- GEM PATHS:
- /usr/local/rvm/gems/ruby-2.4.0
- /usr/local/rvm/gems/ruby-2.4.0@global
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => false
- :bulk_threshold => 1000
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /usr/local/rvm/gems/ruby-2.4.0/bin
- /usr/local/rvm/gems/ruby-2.4.0@global/bin
- /usr/local/rvm/rubies/ruby-2.4.0/bin
- /usr/local/bin
- /sbin
- /bin
- /usr/sbin
- /usr/bin
- /opt/puppetlabs/bin
- /usr/local/rvm/bin
[root@vagrant ~]# GEM_PATH=/opt/sensu/embedded/lib/ruby/gems/2.4.0 /opt/sensu/embedded/bin/gem env
RubyGems Environment:
- RUBYGEMS VERSION: 2.6.10
- RUBY VERSION: 2.4.1 (2017-03-22 patchlevel 111) [x86_64-linux]
- INSTALLATION DIRECTORY: /usr/local/rvm/gems/ruby-2.4.0
- USER INSTALLATION DIRECTORY: /root/.gem/ruby/2.4.0
- RUBY EXECUTABLE: /opt/sensu/embedded/bin/ruby
- EXECUTABLE DIRECTORY: /usr/local/rvm/gems/ruby-2.4.0/bin
- SPEC CACHE DIRECTORY: /root/.gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /opt/sensu/embedded/etc
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-linux
- GEM PATHS:
- /usr/local/rvm/gems/ruby-2.4.0
- /opt/sensu/embedded/lib/ruby/gems/2.4.0
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => false
- :bulk_threshold => 1000
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /usr/local/rvm/gems/ruby-2.4.0/bin
- /usr/local/rvm/gems/ruby-2.4.0@global/bin
- /usr/local/rvm/rubies/ruby-2.4.0/bin
- /usr/local/bin
- /sbin
- /bin
- /usr/sbin
- /usr/bin
- /opt/puppetlabs/bin
- /usr/local/rvm/bin
[root@vagrant ~]#
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
embedded_ruby_version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I submitted an update to the PR.
@majormoses @cwjohnston is RVM supported? I thought that we vendor ruby in /opt/sensu so that we can control which version of ruby is used by Sensu. This seems to go against that by allowing the user to specify a different ruby, such as one controlled by RVM. |
@ghoneycutt - RVM does not seem to be supported. Sensu does use the ruby in /opt/sensu but it also configures the environment so gems installed via RVM will not be in the search path. Using the sensu_gem provider, we need to setup the environment also so that the gems sensu_gem installs end up in the sensu ruby search path. The whole point of this PR is so that if you're using sensu_gem, it installs the gems in the correct embedded ruby search path. If you want to manage the env through RVM (disabling the embedded ruby which is enabled by default), you totally can, just don't use the sensu_gem provider. https://forge.puppet.com/sensu/sensu#installing-gems-into-the-embedded-ruby |
@ghoneycutt @tibers while it is recommended that you use embedded ruby as it provides more isolation and control we do support using system rubies if you want to though that comes with it's own set of challenges. After thinking about this more as the function is called |
@majormoses - that entire long thread I linked you to in slack was because installing gems with The PR fixes If you're foggy on the issue I would reference you to either the other issues raised around this or I would encourage you to fire up vagrant with rvm managing some gems and sensu's embedded ruby managing some different gems. |
@tibers maybe I am confusing you with someone else who had the same issues with If the problem is that having rvm installed messes with installing gems into it's embedded ruby then that makes a lot more sense. If you are installing gems into a non sensu embedded ruby it's not a sensu gem it's just a gem. Apologies if my memory on the specifics are failing me here there are several people I have helped people out with related to installing gems and into system or embedded rubies. |
re-read the PR and it seems I am confusing you with someone else this fails when wanting to install gems into embedded ruby when rvm is installed. That makes sense again. I would still prefer rather than saying this is a rvm issue I think its a more broad issue as it may affect users with rbenv. Can you change the variable names up to be more accurate? |
# ruby slight of hand explaination: Ruby truncates full paths, so join the path, then | ||
# rip through everything in the directory and keep the newest one per comparison, omitting . and .. | ||
# there's probably a faster/prettier way of doing this. | ||
embedded_rvm_version = Dir.glob(File.join('/opt/sensu/embedded/lib/ruby/gems/', '*')).max { |a,b| File.ctime(a) <=> File.ctime(b) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
embedded_ruby_version
# rip through everything in the directory and keep the newest one per comparison, omitting . and .. | ||
# there's probably a faster/prettier way of doing this. | ||
embedded_rvm_version = Dir.glob(File.join('/opt/sensu/embedded/lib/ruby/gems/', '*')).max { |a,b| File.ctime(a) <=> File.ctime(b) } | ||
ENV['GEM_PATH'] = "/opt/sensu/embedded/lib/ruby/gems/#{embedded_rvm_version}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
embedded_ruby_version
On a side note (not sure why I didn't think of this sooner) because of all the fun with installing rubygems on systems with restrictive umasks we ran into needing something similar to update permissions post install in an idempotent way. In my sensu chef wrapper I have a helper library function like this: def sensu_ruby_version(path = '/opt/sensu/embedded/bin/ruby')
if ::File.exist?(path)
ruby_version = Mixlib::ShellOut.new("#{path} --version")
ruby_version.run_command
ruby_version.error!
# extract major.minor.patch from full text version
version = ruby_version.stdout.split(' ')[1].split('p')[0]
# set patch to 0 as we only care about major & minor
version.gsub(/\.\d{1,}$/, '.0')
end
end This is more brittle than yours so I am probably gonna steal that for my internal cookbook. |
Submitted a fixed up PR where I actually rename the variable instead of just renaming the instantiation. Anyway rather than having internal cookbooks, why not open a PR? ;) |
@ghoneycutt it looks reasonable to me now, any more thoughts? |
# in your profile
# based on using https://forge.puppet.com/maestrodev/rvm
include ::rvm
rvm_gemset { 'ruby-2.4.1':
ensure => present,
}
rvm_gem { 'some_sensu_gem':
ensure => '1.2.3',
require => Rvm_gemset['ruby-2.4.1'],
}
# sensu stuff here |
re-read the above comments and it seems that installing software with rvm is not enough, since sensu_gem will not see it. I will merge this if you could provide a simple shell script for EL7 that installs RVM and shows the functionality works. We can then use this in the vagrant environment for testing. # pseudocode
cat > /tmp/install_a_gemFoo_with_sensu_gem.pp <<EOF
# puppet code
EOF
puppet apply /tmp/install_a_gemFoo_with_sensu_gem.pp
show that the gem Foo is installed
install rvm
cat > /tmp/install_a_gemBar_with_sensu_gem.pp <<EOF
# puppet code
EOF
puppet apply /tmp/install_a_gemBar_with_sensu_gem.pp
show that gem Foo is not installed and gem Bar is |
@ghoneycutt We are not looking to add support to have |
@ghoneycutt - I think you're misunderstanding this. It's not that the gem isn't installed, it's that it's installed outside of the embedded gem's GEM_PATH. This is a bugfix, not an enhancement request that adds functionality. Your existing tests actually still work. |
If we're going to ensure that it works with RVM, then we need a way to set that up in the vagrant environment to ensure that it does. We need to see that it doesn't work without this patch and then does after it is applied. |
I'm not familiar with your project - can you spin up a Centos7 VM with RVM and install some plugin, configure sensu to look for it, and validate it does not work? |
Hey @ghoneycutt, @tibers is deep on Puppet but not Sensu. Lmk if you're really pressed for time and we'll expect a delay accordingly! I'll reach out to the broader community to help out too. Tibers done all he can here (thanks Tibers!). |
Maybe my test case is flawed but this is what I'm seeing:
Basically the sensu-plugins-memory-checks gem ends up in /usr/local/rvm. The script: cat > /tmp/sensu_gem1.pp <<EOF
package { 'sensu-plugins-disk-checks':
ensure => 'installed',
provider => 'sensu_gem',
}
EOF
puppet apply /tmp/sensu_gem1.pp
/opt/sensu/embedded/bin/gem which sensu-plugins-disk-checks &>/dev/null
if [ $? -eq 0 ]; then
echo "GEM sensu-plugins-disk-checks installed"
else
echo "GEM sensu-plugins-disk-checks NOT installed"
fi
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
\curl -sSL https://get.rvm.io | bash -s stable --ruby
source /usr/local/rvm/scripts/rvm
gem which sensu-plugins-disk-checks &>/dev/null
if [ $? -ne 0 ]; then
echo "GEM sensu-plugins-disk-checks not in RVM"
else
echo "GEM sensu-plugins-disk-checks found in RVM"
fi
cat > /tmp/sensu_gem2.pp <<EOF
package { 'sensu-plugins-memory-checks':
ensure => 'installed',
provider => 'sensu_gem',
}
EOF
puppet apply /tmp/sensu_gem2.pp
/opt/sensu/embedded/bin/gem which sensu-plugins-memory-checks &>/dev/null
if [ $? -eq 0 ]; then
echo "GEM sensu-plugins-memory-checks installed"
else
echo "GEM sensu-plugins-memory-checks NOT installed"
fi
gem which sensu-plugins-memory-checks &>/dev/null
if [ $? -ne 0 ]; then
echo "GEM sensu-plugins-memory-checks not in RVM"
else
echo "GEM sensu-plugins-memory-checks found in RVM"
fi |
@ghoneycutt I'm not sure this PR solves the problem, or my test case was incorrect. My script's steps ended up with sensu-plugins-memory-checks installed into RVM path and NOT the sensu embedded path.
|
@treydock if you applied the patch, then the output of the run is what's expected, that the plugins come from RVM at the end. |
Added #987 that adds my script to verify the behavior. |
Without this patch and with RVM present, checks will be installed with RVM according to this script. Either there is nothing left to do, the test script is not functioning as intended, or I'm missing this completely. Closing. Please re-open if this is still an issue along with how we can detect how things are broken before a patch and how they work after the patch. |
Pull Request Checklist
Fixes the GEM_PATH which is causing embedded ruby to not do The Right Thing when RVM is present.
Description
Munge GEM_PATH appropriately.
Related Issue
#876
Fixes # .
Motivation and Context
Fixes installation of embedded ruby gems when RVM is present.
How Has This Been Tested?
Fired up a Vagrant instance with RVM installed, then installed the elasticsearch gems and made sure it could find the gems without further munging.
General
No testing required - it wasn't "broken" before. :)