Order of execution in Chef run - Need help

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.

Thanks for the quick replies!! Here are gists of the following:

default.rb recipe - https://gist.github.com/armenr/c8d248d2995a8bc1639c

The NVM/NodeJS cookbook being used/wrapped is this one – https://github.com/phutchins/nvm

– more links in the next post (link limit to 2 on posts by new users)

_botuser.rb - https://gist.github.com/armenr/c9af67ae20d1a0849bc5

_botapp.rb - https://gist.github.com/armenr/33814cf646ed6775bfce

default.rb atrributes - https://gist.github.com/armenr/ecf96a6e2727f733cd8b

Error: https://gist.github.com/armenr/d3014b90c7f25402d091

THANKS for all of your considerate and rapid responses!

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).


# 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

depends ‘cookbookA’

and this in recipe2.rb or cookbookB

include_recipe ‘cookbookA::recipe1’

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.

I’d go with what yoshiwaan says and manage the dependencies.

Also, do you have a nvm_install block in your wrapper cookbook?