1

I have defined a task such that running rake background:fetch_image as my user works as expected. It also works as expected if I run sudo -u www-data rake background:fetch_image. I do not believe the error I shall describe is caused by code I wrote in the task itself.

I am using the whenever gem to handle scheduling. After setting some variables to correct previous errors whenever is producing a line in the crontab like:

0 2 * * * /bin/bash -l -c 'cd /var/www/site && RAILS_ENV=production /usr/local/bin/bundle exec rake background:fetch_image --silent >> /var/www/site/log/whenever.log 2>&1'

When cron executes this I get this error:

/usr/local/lib/ruby/2.6.0/pathname.rb:43:in `chop_basename': undefined method `match?' for /\A(?-mix:\/)?\z/:Regexp (NoMethodError)
Did you mean?  match
        from /usr/local/lib/ruby/2.6.0/pathname.rb:359:in `plus'
        from /usr/local/lib/ruby/2.6.0/pathname.rb:351:in `+'
        from /usr/local/lib/ruby/2.6.0/pathname.rb:188:in `parent'
        from /usr/local/lib/ruby/2.6.0/bundler/shared_helpers.rb:29:in `root'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:234:in `root'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:246:in `app_config_path'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:273:in `settings'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:84:in `configured_bundle_path'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:351:in `use_system_gems?'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:541:in `configure_gem_path'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:534:in `configure_gem_home_and_path'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:66:in `configure'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:134:in `definition'
        from /usr/local/lib/ruby/2.6.0/bundler.rb:101:in `setup'
        from /usr/local/lib/ruby/2.6.0/bundler/setup.rb:20:in `<top (required)>'
        from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'

This error only occurs when the task is run via cron in this manner. I have tried including solutions that extend the PATH variable and perform an rbenv init but none corrected this issue.

Why is it that cron behaves so differently as to cause this error and how might it be fixed?

Marshall Davis
  • 3,337
  • 5
  • 39
  • 47
  • `#match?` is a new method, so it is almost certain that root is not executing the same Ruby that you are (though it seems bundler is being executed from 2.6's gem library). Are you using RVM or similar? – Amadan Mar 27 '19 at 03:31
  • Does cron run as root? I believed it ran as the user to which the crontab belonged. I am not using RVM or rbenv. I can check what happens if I try and run the task as root, I think. – Marshall Davis Mar 27 '19 at 03:33
  • Ah. Not sure, I thought it's the user who the executable belongs to. Maybe I'm wrong, been a while since I looked at it. Still, it would be good to do `x x x x x ruby --version > /tmp/rubyver.txt` or something to see what's happening. Even better, `x x x x x /bin/bash -l -c '/usr/local/bin/bundle exec ruby --version > /tmp/rubyver.txt'`, to match your case more. – Amadan Mar 27 '19 at 03:35
  • @Amadan As root `ruby -v` shows `ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-linux]` which matches my own – Marshall Davis Mar 27 '19 at 03:35
  • @Amadan via cron it logs ruby 2.3.1.p112 so you were right. Now I just need to determine why. – Marshall Davis Mar 27 '19 at 03:43

1 Answers1

1

I ended up changing the PATH variable used so that /usr/local/bin/ruby was used rather than /usr/bin/ruby. I did it by modifying the code found here to this result in schedule.rb:

job_type :rake, %Q{export PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin; cd :path && :environment_variable=:environment bundle exec rake :task --silent :output}

This brought the versions being used by cron and my users in line.

Marshall Davis
  • 3,337
  • 5
  • 39
  • 47