Running bundle exec rake inside cron cannot find specific version of rake - ruby

I am setting up cron to run some rake tasks for my ruby on rails server. They are generated by whenever and look like this:
* * * * * /bin/bash -l -c 'cd /var/www && RAILS_ENV=production /usr/local/bin/bundle exec /usr/local/bin/rake my:task --silent >> /var/www/log/cron.log 2>&1'
bundle and rake executables seem to be found, but inside cron.log I find this error:
bundler: failed to load command: /usr/local/bin/rake (/usr/local/bin/rake)
Bundler::GemNotFound: Could not find rake-12.3.2 in any of the sources
/usr/local/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/spec_set.rb:91:in `block in materialize'
...
...
As I can see it tried to load rake-12.3.2, which is a correct version, from /usr/local/lib/ruby/gems/2.5.0/gems, which is not a correct path, because there is no rake-12.3.2. Correct version of rake is under another path /usr/local/bundle/gems, but I have no luck setting this path for cron to use.
I have tried adding GEM_PATH="/usr/local/bundle/gems" to cron file, but it doesn't work.
I am not using rvm or rbenv, ruby is installed directly.

Related

Jenkins, rbenv, bundler - When using Jenkins and rbenv, how does the rbenv plugin preinstall bundler, and why isn't it in my case?

I'm setting up a CI environment on OSX using Jenkins and Appium's Ruby library.
I'm using a rake task to launch my test suite in RSpec.
Using a similar configuration, I was able to run the tests with Jenkins on another machine. I'm now using rbenv (and the rbenv plugin) and having some issues.
Here's what I get when I try to run the job:
$ bash -c "[ -d \$HOME/.rbenv-jenkins ]"
$ bash -c "[ -d \$HOME/.rbenv-jenkins/plugins/ruby-build ]"
$ bash -c "cd /Users/Shared/Jenkins/Home/workspace/Tests && env RBENV_ROOT\=\$HOME/.rbenv-jenkins RBENV_VERSION\=2.2.5 CONFIGURE_OPTS\= RUBY_CONFIGURE_OPTS\= \$HOME/.rbenv-jenkins/bin/rbenv local 2>/dev/null || true"
Use local Ruby version 2.2.5.
$ bash -c "mkdir \$HOME/.rbenv-jenkins/.lock"
$ bash -c "env RBENV_ROOT\=\$HOME/.rbenv-jenkins RBENV_VERSION\=2.2.5 CONFIGURE_OPTS\= RUBY_CONFIGURE_OPTS\= \$HOME/.rbenv-jenkins/bin/rbenv versions --bare"
$ bash -c "env RBENV_ROOT\=\$HOME/.rbenv-jenkins RBENV_VERSION\=2.2.5 CONFIGURE_OPTS\= RUBY_CONFIGURE_OPTS\= \$HOME/.rbenv-jenkins/bin/rbenv rehash"
$ bash -c "env RBENV_ROOT\=\$HOME/.rbenv-jenkins RBENV_VERSION\=2.2.5 CONFIGURE_OPTS\= RUBY_CONFIGURE_OPTS\= \$HOME/.rbenv-jenkins/bin/rbenv exec gem list"
$ bash -c "env RBENV_ROOT\=\$HOME/.rbenv-jenkins RBENV_VERSION\=2.2.5 CONFIGURE_OPTS\= RUBY_CONFIGURE_OPTS\= \$HOME/.rbenv-jenkins/bin/rbenv rehash"
$ bash -c "rm -rf \$HOME/.rbenv-jenkins/.lock"
[Tests] $ bundle exec rake ios
FATAL: rake execution failed
java.io.IOException: Cannot run program "bundle" (in directory "/Users/Shared/Jenkins/Home/workspace/Tests"): error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at hudson.Proc$LocalProc.<init>(Proc.java:240)
at hudson.Proc$LocalProc.<init>(Proc.java:212)
etc.
It seems like there is an issue with bundler's exec not being where it is supposed to be.
I've tried adding
export PATH="$HOME/.rbenv-jenkins/bin:$PATH"
to the path in a few ways, but it seems like it doesn't make a difference - when it's a shell step I see it run, but I get no change.
I have preinstall rake and bundler enabled with my rbenv plugin, but I don't see them getting installed - I'm not sure why.
I am able to run tests via rspec, rake and bundle exec rake when I'm logged in to the Jenkins user.
Any idea what's not doing what it's supposed to be? Let me know if there are any missing details, and thank you!
edit:
When I add gem install bundle and gem install rake shell commands, I get the following:
+ gem install bundler
Successfully installed bundler-1.13.2
Parsing documentation for bundler-1.13.2
Done installing documentation for bundler after 4 seconds
1 gem installed
+ gem install rake
ERROR: Error installing rake:
"rake" from rake conflicts with /Users/Shared/Jenkins/.rbenv-jenkins/versions/2.2.5/bin/rake
Build step 'Execute shell' marked build as failure
Finished: FAILURE
My pre-install gems are rake,bundler - but it seems like only rake gets pre-installed correctly.
Running the job without installing rake (and with an rbenv rehash following the bundler install), I get the same error.
In this case, it turned out to be an error with gem dependencies - a bad nokogiri installation when all was said and done.
I was able to reveal the error message that got me hunting by running bundle exec rake ios (my test task) as a shell command rather than as a rake task via the plugin.
From there, I got an error about a bad version and after trying some gemfile tweaks (and nuking my Gemfile.lock), I ran bundle install as a shell line and noticed the nokogiri installation failing in familiar ways (due to some Xcode version juggling that I suspect is fairly idiosyncratic).
So, if you're lost and looking for guidance in a similar spot, try running the task as a shell line so you get more verbose errors.

Jenkins and running rake tasks

I'm having some issues running a rake task from within Jenkins (within a docker container) as part of a build process (I have the Rake plugin installed). I am getting the error
java.io.IOException: Cannot run program "rake" (in directory "/var/jenkins/workspace/HendricksFeaturesCopy"): error=2, No such file or directory
Which i don't understand as when i pwd $ECHO before the rake task is invoked i get.
/var/jenkins/workspace/HendricksFeaturesCopy
So i'm in the correct place and rake is installed as its located here
/usr/local/rvm/rubies/ruby-2.3.0/bin/rake
My Rakefile looks like
import 'lib/tasks/yard-docs.rake'
lib/tasks/yard-docs.rake
require 'yard'
namespace :yard_docs do
desc 'Generate Yard Documentation'
task :generate do
# Generate Yard Documentation
end
end
Does anyone know how to rectify this or what I am missing?
UPDATE
After doing echo $PATH
/usr/local/rvm/gems/ruby-2.3.0/bin:/usr/local/rvm/gems/ruby-2.3.0#global/bin:/usr/local/rvm/rubies/ruby-2.3.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/rvm/bin
So this means the correct gemset is being used and when I have done rvm #global do gem list
rake (10.4.2)
So, rake is available right ?
Make sure /usr/local/rvm/rubies/ruby-2.3.0/bin/ is in your $PATH.
PATH=/usr/local/rvm/rubies/ruby-2.3.0/bin/:$PATH
Alternatively, symlink /usr/local/rvm/rubies/ruby-2.3.0/bin/rake to /usr/local/bin/
ln -s /usr/local/rvm/rubies/ruby-2.3.0/bin/rake /usr/local/bin/

Missing gems for cronjob which are installed

On my server I have one cronjob for running ruby script through rake, but the script is not executed. I'm running rvm with 2.1.2 ruby and here is my crontab:
SHELL=/bin/bash
PATH=/home/deployer/.rvm/gems/ruby-2.1.2/bin:/home/deployer/.rvm/gems/ruby- 2.1.2#global/bin:/home/deployer/.rvm/rubies/ruby-2.1.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/deployer/.rvm/bin:/home/deployer/.rvm/bin
*/1 * * * * cd /var/www/cars_crawler && /home/deployer/.rvm/gems/ruby-2.1.2/bin/rake >> /var/www/cars_crawler/cron.txt 2>&1
The error from cronjob is:
/home/deployer/.rvm/rubies/ruby-2.1.2/bin/ruby get_cars.rb
/home/deployer/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- nokogiri (LoadError)
When I run manually the rake command, not through crontab everything is ok, but from cronjob the problem is present. What I noticed is this line: /home/deployer/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/ I don't have ruby 2.1.0 installed. What can cause this problem, I'm out of ideas

Using whenever gem with sinatra

#config/scheduler.rb
set :output, 'log/cron.log'
every 1.minutes do
rake 'reports:generate'
end
When I run crontab -l I get the following output:
* * * * * /bin/bash -l -c 'cd <path-to-app> bundle exec rake reports:generate --silent >> log/cron.log 2>&1'
First off, it seems to use my system ruby which is 1.8.7, is there a way to change this?
Secondly, the task is not run, but the only thing that shows up in my cron.log is the following:
Your Ruby version is 1.8.7, but your Gemfile specified 2.0.0
I've tried puts to the log with no success, so I have basically no idea what's going on. It seems the task is being initiated, but then fails without anything being written to the log. I have no idea how to go about debugging this, so please help.
I'm on OS X, and my application is running on Sinatra.
edit: I'm using rbenv to manage my ruby versions, so I guess I have to tell the cron job to load rbenv somehow? When I cd into the app's folder and run ruby -v I get
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-darwin12.5.0]
It seems the problem was with rbenv, and not necessarily sinatra or whenever. This solved my problem:
#schedlue.rb
command "cd #{Dir.pwd} && RACK_ENV=#{environment} rbenv exec bundle exec rake reports:generate"
By adding rbenv exec we successfully loaded the correct ruby version before running the rake task.

Capistrano: run_locally in separate project

I'm using capistrano for deployment. I'm trying to define a task which will:
cd other-rails-app && bundle exec rake sometask
But it's complaining about Rake not being part of the bundle (which is obviously not true in the project where I am trying to run this task). I think it must be altering the environment somehow before executing the command and assuming bundler is already loaded (which is true in the capistrano task, but it's the wrong Gemfile).
How do I run a command locally with capistrano with a clean environment?
I figured out the problem. When you run capistrano, the BUNDLE_GEMFILE environment variable gets set to the Gemfile of the current project. So when you run bundle exec rake, Bundler looks first to the Gemfile set in the environment. The solution is to "reset" this Gemfile variable. I created a script for running my rake task in the root of my other project.
So instead of doing:
run_locally "cd other-rails-app && bundle exec rake mytask"
I do this:
run_locally "cd other-rails-app && ./mytask.rb"
In the mytask.rb file I do this:
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] = File.expand_path('Gemfile', File.dirname(__FILE__))
require 'bundler/setup'
%x{rake mytask}

Resources