1

I have a rake task that gets called from a controller - actually the controller calls a bash script, which calls a rake task. We do this so staff can request a database import, which reimports the data and restarts the app.

At command line, it works. ENV['HOME'] is set.

However, when we call it via the controller -> bash script, the rake task claims it is nil.

So, what could be causing this? Shouldn't $HOME always be visible?

UPDATE:

the controller (via unicorn web server) calls a bash script like so: system("#{Rails.root}/lib/cron/manual_digest.bash") in the bash script that gets called, i ran export -p and got:

declare -x BUNDLE_BIN_PATH="/usr/local/lib/ruby/gems/2.1.0/gems/bundler-1.5.3/bin/bundle"
declare -x BUNDLE_GEMFILE="/var/www/ma_staging/releases/20150319193546/Gemfile"
declare -x BUNDLE_ORIG_MANPATH="/var/www/ma_staging/shared/bundle/ruby/2.1.0/gems/unicorn-4.8.3/man"
declare -x GEM_HOME="/var/www/ma_staging/shared/bundle/ruby/2.1.0"
declare -x GEM_PATH=""
declare -x LANG="en_US.UTF-8"
declare -x MANPATH="/var/www/ma_staging/shared/bundle/ruby/2.1.0/gems/unicorn-4.8.3/man"
declare -x OLDPWD="/var/www/ma_staging/current"
declare -x OLD_PID="/var/www/ma_staging/shared/pids/unicorn.pid.oldbin"
declare -x PATH="/var/www/ma_staging/shared/bundle/ruby/2.1.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
declare -x PID="/var/www/ma_staging/shared/pids/unicorn.pid"
declare -x PWD="/home/deploy/ma_staging/current"
declare -x RACK_ENV="staging"
declare -x RAILS_ENV="staging"
declare -x RUBYLIB="/usr/local/lib/ruby/gems/2.1.0/gems/bundler-1.5.3/lib"
declare -x RUBYOPT="-rbundler/setup"
declare -x SHLVL="2"
declare -x TERM="xterm-256color"
declare -x UNICORN_FD="12,13"
declare -x _ORIGINAL_GEM_PATH=""

running this same command via a rails console:

export BUNDLE_BIN_PATH='/usr/local/lib/ruby/gems/2.1.0/gems/bundler-1.5.3/bin/bundle'
export BUNDLE_GEMFILE='/var/www/ma_staging/releases/20150319193546/Gemfile'
export BUNDLE_ORIG_MANPATH='/var/www/ma_staging/shared/bundle/ruby/2.1.0/gems/unicorn-4.8.3/man'
export COLUMNS='213'
export GEM_HOME='/var/www/ma_staging/shared/bundle/ruby/2.1.0'
export GEM_PATH=''
export HOME='/home/deploy'
export LANG='en_US.UTF-8'
export LESSCLOSE='/usr/bin/lesspipe %s %s'
export LESSOPEN='| /usr/bin/lesspipe %s'
export LINES='50'
export LOGNAME='deploy'
export MAIL='/var/mail/deploy'
export MANPATH='/var/www/ma_staging/shared/bundle/ruby/2.1.0/gems/unicorn-4.8.3/man'
export OLDPWD='/home/deploy/ma_staging/current/lib'
export PATH='/var/www/ma_staging/shared/bundle/ruby/2.1.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games'
export PS1='\u:\W\$ '
export PWD='/home/deploy/ma_staging/current'
export RAILS_ENV='staging'
export RUBYLIB='/usr/local/lib/ruby/gems/2.1.0/gems/bundler-1.5.3/lib'
export RUBYOPT='-rbundler/setup'
export SHELL='/bin/bash'
export SHLVL='1'
export SSH_AUTH_SOCK='/tmp/ssh-jkdbX19657/agent.19627'
export SSH_CLIENT='68.82.90.217 38992 22'
export SSH_CONNECTION='55.55.55.55 3322 55.55.55.55 22'
export SSH_TTY='/dev/pts/0'
export TERM='xterm'
export USER='deploy'
export _='/usr/local/bin/bundle'
export _ORIGINAL_GEM_PATH=''

I looked into "restricted shells" but that doesn't quite explain what I'm seeing, with variables missing. I also looked into "subshells" (since the first output is SHLVL=2) but that also does not specifically explain this behavior.

I'm looking for some documentation or something somewhere that says "when you do X, the variables for $HOME and $USER are not set because Z"

I am suspecting something with unicorn, but have not found anything to explain why these variables would be empty.

  • Update: the rake task *is* running as the expected user whe I view PS output –  Mar 24 '15 at 15:08
  • How does the controller execute the script? How does the script execute the rake task? What commands/etc. **exactly**? – Etan Reisner Mar 27 '15 at 11:12
  • @EtanReisner i updated my original question with more info –  Mar 27 '15 at 14:17
  • Does unicorn itself see `HOME`/etc.? I'm going to assume it doesn't and that it is running itself in an intentionally cleaned environment so when it spawns the sub-shell (`/bin/sh` most likely from `system` though that might run `bash` if there's a shebang line on the script I'm not sure) it also doesn't have those variables available. But this is just speculation. – Etan Reisner Mar 27 '15 at 14:47

3 Answers3

1

Try adding echo "USER: $USER" to your bash script to see what user controller is running under. User's can be created without a home directory so this is probably what you're running into. For example, user apache for the Apache www server has no home directory.

You could also set environment in the bash script. If $HOME is not set you could set it to /tmp??

GoinOff
  • 1,792
  • 1
  • 18
  • 37
  • Interesting; when I try to do `ENV['USER']` it also is `nil` how is that even possible? –  Mar 24 '15 at 14:57
  • Not sure on that one..Maybe try checking out the service for controller?? '/etc/init.d' entry. It might help with clues as to what is going on.. I think checking for $HOME in your bash script and setting and alternate if it's not defined is the best route. – GoinOff Mar 24 '15 at 15:26
  • Yes, we've managed to bypass the issue in another way - but we have no idea why it is behaving this way, and setting $HOME manually, while it would work, is more a hack than a fix. I'm sure there's some logical explanation of some sort for what we're seeing, but I don't know what it is. –  Mar 24 '15 at 15:28
1

Although running rake task though controller is a bad idea but still this is how you can run it and get access to all your env. variables. Give it try

system "/bin/bash -l -c 'cd #{Rails.root.to_s} && RAILS_ENV=production bundle exec rake task_namespace:it_might_work --silent'" 

Also, You can pass agruement to rake task in case if above thing failed. Refer How to pass command line arguments to a rake task

Btw, i strongly recommends to put this rake task as background script. Use it sidekiq or delayed_job etc.

Community
  • 1
  • 1
Paritosh Piplewar
  • 7,982
  • 5
  • 26
  • 41
  • ok, i gave this a go; still no dice. the variables available via `export -p` did not change, even after stopping/starting unicorn –  Mar 27 '15 at 14:23
1

ok, turns out the issue was with the way unicorn was being started up and our suoders config file, which was misconfigured. I was worried it was some bug - nope, just misconfiguration on our end.