Wednesday, 28 March 2012

A "Hello World" from Chef

If - like me - you're a developer beginning to play around with , perhaps you've found that many quick start tutorials seem more Ops than Dev. Read on for a mixed with some opinions about development on Chef. Thanks toJonathan Otto and morethanseven for blazing this trail.

An efficient feedback loop matters to me, and isolation between projects. Installing a server and setting up a workstation for each project sounds too slow.

So use [1]
$ chef-solo --version
Chef: 0.10.8

in a workspace for project hello

$ mkdir --parents chef-workspace/hello
$ cd chef-workspace/hello

under version control

$ git init 

Isolate the new project from its environment by grouping the configuration files together

$ mkdir config

and separate them from the code

$ mkdir cookbooks

A minimal configuration to wire in this project layout, setting the conventional cookbook_path, may be written in

cookbook_path File.expand_path(File.join(File.dirname(__FILE__), '..', "cookbooks"))

Save this into config/chef-solo-config.rb, a reasonable naming convention for the configuration file passed to chef-solo. Attributes declaring the exercise are passed through a second file, encoded in JSON. A minimal Hello, World exercise, running just the default recipe from a cookbook called hello_world, is

{"run_list": ["recipe[hello_world]"]}

Save this config/from-hello_world-run-default.json, a conventional name for an exercise that runs the default recipe from the hello_world cookbook. Create a directory for this cookbook

$ mkdir cookbooks/hello_world

with space ready for a recipe

$ mkdir cookbooks/hello_world/recipes

Chef supports logging out-of-the-box, and so an easy way to say hello is

log("Hello, World") { level :info }

Save this into cookbooks/example/recipes/default.rb, and Chef will run this when the no recipe name is given (for this cookbook).


Ready to cook[2]

$ sudo chef-solo --config config/chef-solo-config.rb 
   --json-attributes config/from-hello_world-run-default.json
[...] INFO: Starting Chef Solo Run
[...] INFO: Replacing the run_list with ["recipe[hello_world]"] from JSON
[...] INFO: Hello, World
[...] INFO: Chef Run complete in 0.885143 seconds

Hello, World — served up by Chef.


Simple.

A few more sophisticated examples are queued in the draft pipeline, so check back later for more on Chef - or subscribe to the feed.


[1] Chef moves fast: install the lates
[2] unless you forget to sudo
$ chef-solo --config config/chef-solo-config.rb 
     --json-attributes config/from-hello_world-run-default.json

[...] FATAL: Failed to read the private key /etc/chef/client.pem: 
#<Errno::EACCES: Permission denied - /etc/chef/client.pem>, 
/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:59:in 
 `read'/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:59:in 
 `load_signing_key'/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:33:in 
 `initialize'/usr/lib/ruby/1.8/chef/rest.rb:40:in 
 `new'/usr/lib/ruby/1.8/chef/rest.rb:40:in 
 `initialize'/usr/lib/ruby/1.8/chef/client.rb:54:in 
  `new'/usr/lib/ruby/1.8/chef/client.rb:54:in 
 `initialize'/usr/lib/ruby/1.8/chef/application/solo.rb:180:in 
 `new'/usr/lib/ruby/1.8/chef/application/solo.rb:180:in 
 `setup_application'/usr/lib/ruby/1.8/chef/application.rb:61:in 
  `run'/usr/bin/chef-solo:24
/usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:62:in 
 `load_signing_key': I cannot read /etc/chef/client.pem, 
   which you told me to use to sign requests! 
    (Chef::Exceptions::PrivateKeyMissing)
 from /usr/lib/ruby/1.8/chef/rest/auth_credentials.rb:33:in `initialize'
 from /usr/lib/ruby/1.8/chef/rest.rb:40:in `new'
 from /usr/lib/ruby/1.8/chef/rest.rb:40:in `initialize'
 from /usr/lib/ruby/1.8/chef/client.rb:54:in `new'
 from /usr/lib/ruby/1.8/chef/client.rb:54:in `initialize'
 from /usr/lib/ruby/1.8/chef/application/solo.rb:180:in `new'
 from /usr/lib/ruby/1.8/chef/application/solo.rb:180:in `setup_application'
 from /usr/lib/ruby/1.8/chef/application.rb:61:in `run'
 from /usr/bin/chef-solo:24

Tuesday, 27 March 2012

Starting with ember.js and Rails

For a new project, I've been investigating frameworks for a richer front-end. I settled on because it provides a reasonably understandable object model and it has features like templating baked in, rather than needing to be added manually like in many other javascript frameworks. Ember.js also has the ability to define bindings that automatically update your view by manipulating the bound javascript objects.

After some investigation, I found some useful posts on setting up an Ember.js application, one rails specific and one that introduces a layout system and a routing system. This prompted some experimentation to set up a front end that is manageable, suits the project and allows us to quickly add to the front-end.

The end result is a set of generators and asset-pipeline suitable gems for quickly getting started with Ember.js. The first thing to note is that the generators are opinionated - they assume you are using and within the Rails asset pipeline. To help with this, the bootstrap generator adds the appropriate gems to your Gemfile.

More details can be found in the git repositories for the 4 gems created for the project: