I’m writing a cookbook to set up a host that runs a custom fork of Github’s hubot, reverse proxied through nginx, with redis, nodjes via nvm, and a custom “hubot” user.
For some reason, I cannot get the nvm recipe to run/install BEFORE the other recipes, since one of the other recipes I’ve written (provisioning the hubot user) depends on sourcing the nvm.sh file that the nvm cookbook installs.
How can I compel Chef to first run the nvm cookbook before running the “execute” for sourcing the nvm.sh file and then “npm install”-ing in that directory?
I essentially need help understanding how Chef orders resources to execute, and how I can influence/manipulate resource execution ordering.
Resources should be executed in the order that they appear in the run list. There are two phases however, the compile and the execute phase (there’s a good explanation on the site https://docs.chef.io/chef_client.html#the-chef-client-title-run), it sounds like you may be running into issues there?
I could be way off the mark, would you be able to post a snippet of your cookbook that is failing?
See https://coderanger.net/two-pass/ for a more detailed dive into the execution process. Chances are you want to use include_recipe to force one recipe to compile before another.
I just had a quick check and it looks like the execute resource doesn’t load your .bashrc (at least on Ubuntu 14.04). Also, I think .bashrc doesn’t load for non-interactive sessions.
You could try sourcing /etc/profile.d/nvm.sh in your install block directly (you’ll have to change it to a bash resource though).
E.g.
# Install dependencies bash "install gravbot dependencies" do user 'gravbot' code "source /etc/profile.d/nvm.sh && npm install" cwd "/opt/gravbot" creates "/opt/gravbot/node_modules" end
@kdoonan - I tried what you suggested, however I’m still hitting the issue where the chef run first wants to complete the _botapp recipe before installing nodejs/nvm.
Essentially, it’s still ordering the _botapp recipe ahead of the nodejs wrapper recipe.
It can’t source a file that doesn’t exist (/etc/profile.d/nvm.sh is created when you install nodejs via nvm), whether you use the “bash” resource or the “command” resource.
Your error gist says ‘npm not found’, are you sure npm is installed?
I think the nodejs cookbook can manage npm packages, so you might want to
give that a look.
Also, as Coderanger said, you should map cookbook dependencies.
So if you have cookbookA that creates /etc/profile.d/nvm.sh (say in
recipe1.rb) and cookbookB depends on /etc/profile.d/nvm.sh in recipe2.rb
then you should be putting this in the metadata.rb of cookbookB
The logic of the cookbook I’m writing is the following:
Install redis, nginx, and some ssh keys for a user
then install nodejs via nvm
then source the nvm.sh file, and execute npm install…
The reason it doesn’t find npm is because it tries to source the nvm.sh file that the nvm recipe is supposed to drop off in the /etc/profile.d/ directory. It’s attempting to execute the _botapp recipe before nodejs is even installed, even though those recipes are not included in that order.