In Chef 12, three behavior changes will be noted:
method_missing(and will instead contain the name of the resources).
In Chef 13, deprecated behavior will be removed (along with method_missing). All of these have deprecation warnings enabled for Chef 12 (see Deprecations section).
As a Chef user, I want resources declared in my own namespace to be in recipe DSL automatically, so that I don't have to write the name of the resource twice. As a Chef user, I want to declare resources in my own namespace, So that I get better error messages when there is a resource conflict. As a Chef developer, I want meaningful names in stack traces for methods, So that I can actually read the debug output. As a Chef developer, I want less if statements, case statements and metaprogramming in DSL method calls, So that I can debug and follow logic more easily.
When looking up resources, there is no method anywhere that corresponds to the actual resource name. This can lead to a lot of unnecessarily heavy thinking when following some very typical stack traces. It also means that the name of the resource being declared is often not on the stack, making debugging harder.
Here we propose that all resource and definition DSL be added to
Chef::DSL::Recipe as actual methods, as they are created, so that they can be
subject to inspection and the stack traces can be followed. This will happen
automatically when the user declares resources and definitions.
Presently, when you create a class under
Chef::Resource, a magical Chef DSL
based on the class name (
my_resource) will automatically work. Now you will
need to use
provides to explicitly mark the DSL you provide:
class MyPackage::MyResource < Chef::Resource provides :shazam end # Now `shazam` will work fine in a recipe, but `my_resource` will not.
We will ensure that all existing core Chef classes in the
chef-provisioning* gems use
provides to avoid warnings. LWRPs will
automatically do this as well.
When resource DSL becomes explicit, the idea that a class has a single DSL name
no longer makes sense. We will remove
With Chef::Resource no longer a special place for class lookup, LWRPs no longer need to be given a namespace. We will now make resources/x.rb and providers/x.rb an anonymous class, with string methods to make it easy to see where they come from. This avoids a number of potential errors and warnings that can happen in the case of conflicts, and gives us control over how we handle conflicts.
Users who wish to set the class of the resource can assign it directly in the
Namespace::MyResource = self.
method_missing means several methods of creating resource names cannot
be caught. These are the cases. We will issue deprecation warnings for each one
and remove them (and method_missing) come Chef 13.
When you have a class in the
Chef::Resource namespace without
DSL will no longer work in Chef 13. In 12 we will issue a deprecation warning
whenever the user tries to use a DSL class without corresponding DSL.
There is a backwards compatibility break related to moving a
class from not having
provides, to having
provides. Specifically, in Chef 12
we don't check for
Chef::Resource::FooBar until after we have asked all
provides? is true. This gave
provides classes an implicit
priority over non-provides
If someone is (knowingly or unknowingly) taking advantage of this implicit
priority, and adds
provides :foo_bar to
Chef::Resource::FooBar, it would be
considered (and possibly selected) along with other classes that say things like
provides :foo_bar, os: 'linux'. If there are multiple matches, we pick the
first class alphabetically. This would change behavior.
The correct workaround for the user in this case is to use
Chef.set_resource_priority_array :foo_bar [Linux::FooBar, Chef::Resource::FooBar], which will bring the correct version into ascendancy
If people call
method_missing directly to invoke DSL methods, and we don't
define it anymore, it obviously won't actually invoke the methods. We will
detect this in methodmissing, issue a warning telling people to call the
actual method instead or use publicsend(), and remove it come Chef 13.
If someone creates a resource class with a custom
provides? method, they can
class MyResource < Chef::Resource def provides?(node, name) name == :blah end end
The implications of this are that we have to scan every single resource when
blah in a recipe, just so we can catch this one. In Chef 12 we will
issue a deprecation warning and tell you to do this instead:
class MyResource < Chef::Resource provides :blah end
When you create an LWRP, it is presently placed in
Chef::Resource::CookbooknameResourcename. In the spirit of not placing user
defined stuff into the core Chef namespace, this will no longer happen. Any
user that calls
Chef::Resource::MyLwrpResource.new or extends directly from
Chef::Resource::MyLwrpResource will receive a warning.
While we're trying to maintain full compatibility, there's risk here, particularly for people doing metaprogramming of resources. We will run the tests of the following packages, and make sure current versions still work (possibly emitting deprecation warnings):
This work is in the public domain. In jurisdictions that do not allow for this, this work is available under CC0. To the extent possible under law, the person who associated CC0 with this work has waived all copyright and related or neighboring rights to this work.