[ Content | View menu ]

Chef and ActiveSupport

Mark Mzyk | February 18, 2012

Upfront disclaimer: While I work for Opscode, maker of Chef, this blog post reflects my personal opinion and is not company position.

Chef has a major pain point in the Ruby community: ActiveSupport.

ActiveSupport is a library of useful functions that was born from Rails, adding into Ruby all sorts of helper functions. It does so by monkey patching core classes. The monkey patching makes it easy to not even realize you’re using ActiveSupport.

ActiveSupport works great in Rails – because Rails was built from the ground up to use ActiveSupport. Where ActiveSupport falls down is in projects not built from the ground up to use it. Chef is one of those projects.

Chef does not use ActiveSupport. If you run Chef there is no need to install ActiveSupport and Chef will not install ActiveSupport. However, one of the great features of Chef is that you can use any Ruby code of your choosing in the cookbooks – including ActiveSupport, or more insidiously, a gem that pulls in ActiveSupport.

When ActiveSupport gets into Chef’s load path, it has the potential for insidious harm, due to the monkey patching it performs. With Chef this particularly strikes around json operations. Chef does a fair amount of serializing to and from json, using the json gem to accomplish this. ActiveSupport has its own opinions on how json should be serialized/deserialized and will override the json gem.

The Rails team is aware that ActiveSupport interferes with the json gem and has provided ways to defer to it. These work great, so long as you have consciously made the decision to load ActiveSupport and to tell it to use the json gem. What if your project is like Chef, which doesn’t need or want ActiveSupport, but might find it loaded? It is difficult to undo monkey patching once it is present, especially if you want to be a good citizen and not interfere with ActiveSupport when something else might be relying on it.

Opscode has tried to devise fixes that work around ActiveSupport when it is present, without changing the behavior of ActiveSupport. These should go out in a future Chef release. My recommendation is, even after the fixes go out, to run Chef without ActiveSupport. If you must use ActiveSupport and you see an error that can be traced to strange json, try setting ActiveSupport to use the json gem for its backend. It’s also possible that you won’t notice anything wrong with ActiveSupport present, as Chef is fairly promiscuous in the json it allows and will often correctly interpret the json.

If all else fails, file a bug with Opscode and we’ll do our best to keep working around ActiveSupport, since it isn’t going away anytime soon.