I'm writing a Chef cookbook to install Hubot. In the recipe, I do the following:

bash "install hubot" do
  user hubot_user
  group hubot_group
  cwd install_dir
  code <<-EOH
    wget https://github.com/downloads/github/hubot/hubot-#{node['hubot']['version']}.tar.gz && \
    tar xzvf hubot-#{node['hubot']['version']}.tar.gz && \
    cd hubot && \
    npm install

However, when I try to run chef-client on the server installing the cookbook, I'm getting a permission denied writing to the directory of the user that runs chef-client, not the hubot user. For some reason, npm is trying to run under the wrong user, not the user specified in the bash resource.

I am able to run sudo su - hubot -c "npm install /usr/local/hubot/hubot" manually, and this gets the result I want (installs hubot as the hubot user). However, it seems chef-client isn't executing the command as the hubot user. Below you'll find the chef-client execution. Thank you in advance.

Saving to: `hubot-2.1.0.tar.gz'

     0K ......                                                100%  563K=0.01s

2012-01-23 12:32:55 (563 KB/s) - `hubot-2.1.0.tar.gz' saved [7115/7115]

npm ERR! Could not create /home/<user-chef-client-uses>/.npm/log/1.2.0/package.tgz
npm ERR! Failed creating the tarball.
npm ERR! couldn't pack /tmp/npm-1327339976597/1327339976597-0.13104878342710435/contents/package to /home/<user-chef-client-uses>/.npm/log/1.2.0/package.tgz
npm ERR! error installing hubot@2.1.0 Error: EACCES, permission denied '/home/<user-chef-client-uses>/.npm/log'


npm not ok
---- End output of "bash"  "/tmp/chef-script20120123-25024-u9nps2-0" ----
Ran "bash"  "/tmp/chef-script20120123-25024-u9nps2-0" returned 1
  • Hang on, you're saying you're running chef-client as some non-root user? – cjc Jan 23 '12 at 19:20
  • It's a user that has sudo rights. It's the same one that I used for bootstrapping the node. – Arthur Maltson Jan 25 '12 at 14:29
  • But you're doing "sudo chef-client", right? – cjc Jan 25 '12 at 14:46
  • You probably should be running chef as root. – Mike Fiedler Jul 20 '12 at 13:57
  • Chef is running as a root user. – Arthur Maltson Feb 28 '13 at 1:28

The problem is (likely) not Chef running the command as the wrong user, but that the shell running your script is not a login shell. This means that some environment variables (like HOME) will not be set the way you expect, leading npm to try to write files in the wrong place.

The problem is discussed in issue CHEF-2288. While that remains outstanding, you could try adding HOME=/home/hubot-user in your code block, before npm is invoked.


Taken from a comment in CHEF-2288:

environment ({ 'HOME' => ::Dir.home('USERNAME'), 'USER' => 'USERNAME' })

Worked for me!

In your case:

environment ({ 'HOME' => ::Dir.home(hubot_user), 'USER' => hubot_user })

  • 1
    This assumes the hubot_user has already been created before the chef-client run. This is because the Dir.home command is run when the file is loaded, not when the recipe is executed. When creating a new machine, this will most likely be before any of your user creation recipes run and will result in a failure. – Russ Bradberry May 27 '15 at 16:58
  • For the asked question, this answer works perfectly. – look May 28 '15 at 3:52
  • 1
    not on the first bootstrap of the machine, it doesn't. it only works if the user already exists on the machine. – Russ Bradberry Jun 4 '15 at 19:22
  • I'll second that this is a non-solution if chef is also managing the user in question because this code executes in the compile phase, before any recipe execution. there are bigger hacks around it possibly to push it into the second stage, but...... doing 'HOME' => "/home/#{hubut_user}" will work since it's just string passing - but of course lacks the magic touch. – keen Jul 14 '16 at 16:51

After: https://serverfault.com/a/432916/129232

To execute a script or a command as a user, you need to combine su -l and bash -i, e.g.:

 execute "npm_install" do
    command "su vagrant -l -c 'cd /shared-with-host/helperScripts/ && bash -i npm install -g q zombie should mocha coffee-script'" 
    action :run

Because of some bugs, chef does not set properly the environment for the specified user in execute.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.