user1086419
user1086419

Reputation: 85

chef: How do I install a recipe without a chef server

I'm trying to learn chef and following the documentation for chef-solo found here https://docs.chef.io/chef_solo.html

When running chef-solo with the following environment:

name "dev"
description "Development Environment"
cookbook "vim-tutorial"

I get the following stacktrace:

ArgumentError: wrong number of arguments (1 for 2) /opt/chefdk/embedded/apps/chef/lib/chef/environment.rb:107:in cookbook' /Users/barleyj/.chef/chef-solo/environments/dev.rb:3:infrom_file' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/from_file.rb:30:in instance_eval' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/from_file.rb:30:infrom_file' /opt/chefdk/embedded/apps/chef/lib/chef/environment.rb:261:in load_from_file' /opt/chefdk/embedded/apps/chef/lib/chef/environment.rb:241:inload' /opt/chefdk/embedded/apps/chef/lib/chef/node.rb:380:in apply_expansion_attributes' /opt/chefdk/embedded/apps/chef/lib/chef/node.rb:369:inexpand!' /opt/chefdk/embedded/apps/chef/lib/chef/policy_builder/expand_node_object.rb:135:in expand_run_list' /opt/chefdk/embedded/apps/chef/lib/chef/policy_builder/expand_node_object.rb:122:inbuild_node' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:259:in build_node' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:420:indo_run' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:213:in block in run' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:207:infork' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:207:in run' /opt/chefdk/embedded/apps/chef/lib/chef/application.rb:236:inrun_chef_client' /opt/chefdk/embedded/apps/chef/lib/chef/application/solo.rb:226:in block in run_application' /opt/chefdk/embedded/apps/chef/lib/chef/application/solo.rb:218:inloop' /opt/chefdk/embedded/apps/chef/lib/chef/application/solo.rb:218:in run_application' /opt/chefdk/embedded/apps/chef/lib/chef/application.rb:55:inrun' /opt/chefdk/embedded/apps/chef/bin/chef-solo:25:in <top (required)>' /usr/bin/chef-solo:33:inload' /usr/bin/chef-solo:33:in `'

This makes sense when I look at the source code in environment.rb. The cookbook method only accepts 2 arguments.

If I add a version to the environment file:

name "dev"
description "Development Environment"
cookbook "vim-tutorial", "= 0.1.0"

Chef::Exceptions::IllegalVersionConstraint: Environment cookbook version constraints not allowed in chef-solo /opt/chefdk/embedded/apps/chef/lib/chef/environment.rb:306:in validate_cookbook_version' /opt/chefdk/embedded/apps/chef/lib/chef/environment.rb:112:inblock in cookbook' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/params_validate.rb:224:in call' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/params_validate.rb:224:inblock in _pv_callbacks' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/params_validate.rb:223:in each' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/params_validate.rb:223:in_pv_callbacks' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/params_validate.rb:70:in block (2 levels) in validate' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/params_validate.rb:67:ineach' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/params_validate.rb:67:in block in validate' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/params_validate.rb:57:ineach' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/params_validate.rb:57:in validate' /opt/chefdk/embedded/apps/chef/lib/chef/environment.rb:108:incookbook' /Users/barleyj/.chef/chef-solo/environments/dev.rb:3:in from_file' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/from_file.rb:30:ininstance_eval' /opt/chefdk/embedded/apps/chef/lib/chef/mixin/from_file.rb:30:in from_file' /opt/chefdk/embedded/apps/chef/lib/chef/environment.rb:261:inload_from_file' /opt/chefdk/embedded/apps/chef/lib/chef/environment.rb:241:in load' /opt/chefdk/embedded/apps/chef/lib/chef/node.rb:380:inapply_expansion_attributes' /opt/chefdk/embedded/apps/chef/lib/chef/node.rb:369:in expand!' /opt/chefdk/embedded/apps/chef/lib/chef/policy_builder/expand_node_object.rb:135:inexpand_run_list' /opt/chefdk/embedded/apps/chef/lib/chef/policy_builder/expand_node_object.rb:122:in build_node' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:259:inbuild_node' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:420:in do_run' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:213:inblock in run' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:207:in fork' /opt/chefdk/embedded/apps/chef/lib/chef/client.rb:207:inrun' /opt/chefdk/embedded/apps/chef/lib/chef/application.rb:236:in run_chef_client' /opt/chefdk/embedded/apps/chef/lib/chef/application/solo.rb:226:inblock in run_application' /opt/chefdk/embedded/apps/chef/lib/chef/application/solo.rb:218:in loop' /opt/chefdk/embedded/apps/chef/lib/chef/application/solo.rb:218:inrun_application' /opt/chefdk/embedded/apps/chef/lib/chef/application.rb:55:in run' /opt/chefdk/embedded/apps/chef/bin/chef-solo:25:in' /usr/bin/chef-solo:33:in load' /usr/bin/chef-solo:33:in'

This also makes sense when I look at the source code because it doesn't allow for version constraints. So how do I install a recipe or cookbook without having a chef server?

Upvotes: 3

Views: 3403

Answers (3)

sam
sam

Reputation: 1161

You can use chef-solo for this. I put the run list in a node.json (use the -j flag with this) file that in the same place along with the environments, cookbooks, and data_bags directories. You can use a tarball (as described in their documentation), but I find it just as easy to zip, scp, and then unzip on the node.

I use a separate cookbook to manage all cookbooks, internal and 3rd party, in the Berksfile and then use berks vendor to package all of them into the same folder (not my internal cookbooks folder, since it grabs the internal cookbooks the same way). This is the directory that is sent to the node.

Chef-solo gets rid of all cookbooks from the node that are not listed as dependencies at the initial run, so you will just need to list all dependencies in the appropriate metadata files. It does a recursive search so if cookbookA uses cookbookB and cookbookB uses cookbookC, then the following suffices:

# cookbookA/metadata.rb
depends 'cookbookB', '~> 0.1.0'

# cookbookB/metadata.rb
depends 'cookbookC', '~> 0.1.0'

Upvotes: 0

Saravanan G
Saravanan G

Reputation: 581

Chef client version 11+ having an option called Chef client local mode -z

That is best way to run cookbooks without Chef server.

Chef documentation for Chef-client states the below,

$ chef-client OPTION VALUE OPTION VALUE ...

-z, --local-mode
Run the chef-client in local mode. This allows all commands that work against the Chef server to also work against the local chef-repo.

Documentation also states about Chef Local Mode,

Local mode does not require a configuration file, instead it will look for a directory named /cookbooks and will set chef_repo_path to be just above that. (Local mode will honor the settings in a configuration file, if desired.) If the client.rb file is not found and no configuration file is specified, local mode will search for a knife.rb file.

Local mode will store temporary and cache files under the <chef_repo_path>/.cache directory by default. This allows a normal user to run the chef-client in local mode without requiring root access.

So please follow the instructions below,

  • Create a directory called cookbooks
  • Place all your cookbooks and it's dependent cookbooks inside the directory
  • Run the below command (one level above to the directory), to invoke the Chef client in local mode.

chef-client -z -o 'provide_your_overridden_runlist'

Further reference here

Upvotes: 3

coderanger
coderanger

Reputation: 54267

Just leave off the cookbook bit entirely. That feature can't be used with chef-solo as it doesn't do any form of version solving. I think perhaps you are assuming that the cookbook version restrictions act as some kind of run list, but that is not the case. Only roles (and nodes) can have a run list. What you can do is a role can have have a different run list for a specific environment, overriding the normal one.

Upvotes: 0

Related Questions