I'm trying to run the following chef command:
# install zombiejs, q (promises), should, coffee-script & mocha
execute "install q and zombiejs" do
cwd "/home/vagrant"
user "vagrant"
action :run
command "npm install -g q zombie should mocha coffee-script"
end
But it keeps failing because it can't find npm
:
execute[install q and zombiejs] (chef-redtail::default line 205) had an error: Errno::ENOENT: No such file or directory - npm install -g q zombie should mocha coffee-script
Logging in to vagrant via vagrant ssh
and running the command manually works perfectly fine. Logging in as root, via sudo -i
and running the command fails for the same reason the chef recipe fails (npm is installed locally only for the vagrant user, not for root: this is what I want).
So... how can I specify this chef execute
block to run as the vagrant user and not root?
UPDATE: I think this sums up my problem:
(ssh) /vagrant git:backbone ❯ whoami
vagrant
(ssh) /vagrant git:backbone ❯ which npm
/home/vagrant/.local/bin/npm
(ssh) /vagrant git:backbone ❯ echo $PATH
/home/vagrant/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
(ssh) /vagrant git:backbone ❯ sudo -H -u vagrant -i echo $PATH
/home/vagrant/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
(ssh) /vagrant git:backbone ❯ sudo -H -u vagrant -i which npm
npm not found
via http://tickets.opscode.com/browse/CHEF-2517
ANOTHER UPDATE: So I just noticed this discrepancy:
(ssh) /vagrant git:backbone ❯ sudo -H -u vagrant -i echo $PATH
/home/vagrant/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
(ssh) /vagrant git:backbone ❯ sudo -H -u vagrant -i export
HOME=/home/vagrant
LANG=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
LOGNAME=vagrant
MAIL=/var/mail/vagrant
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
SHELL=/bin/zsh
SSH_AUTH_SOCK=/tmp/ssh-uJUopA4146/agent.4146
SUDO_COMMAND='/bin/zsh -c export'
SUDO_GID=1001
SUDO_UID=1000
SUDO_USER=vagrant
TERM=xterm
USER=vagrant
Notice the difference in PATH
? The export doesn't have the /home/vagrant/.local/bin
directory listed in it... why would the first echo return PATH
with it and the second export return PATH
without it? Is this the issue?
To execute a script or a command as a user, you need to combine su -l and bash -i:
Because of some bugs, chef does not set properly the environment for the specified user in execute. The narced133's solution will not work.
You can use
environment
to set the HOME and USER environment variables in your execute block.I use this frequently to install vagrant plugins as the vagrant user inside my VMs. You could also set other environment variables if needed by whatever command you are trying to execute.
It sounds like Chef is executing as the vagrant user but not searching the same PATH as your shell. Login using
vagrant ssh
and runwhich npm
. It will return something like/path/to/bin/npm
. Replace/path/to/bin/
below to force Chef to search the appropriate directory.