This content has been moved to docs.opscode.comSee the following links:
Overview
In Chef, Resources represent a piece of system state and Providers are the underlying implementation which brings them into that state. For example, all database vendors support the abstract concept of database creation, but the underlying implementation is different for each.While typical Resources and Providers are implemented in Chef's core using Ruby classes, implementing Lightweight Resources and Providers (LWRP) is quick and easy, requiring less Ruby knowledge than their heavier counterparts. (LWRP's also become Ruby classes, but this is done for you, behind the scenes).
For the Light-weight Resources and Providers (LWRPs) in Opscode's public open source cookbooks, see Opscode LWRP Resources. File LocationsLightweight Resources and Providers are loaded from files in a Cookbook's "resources" and "providers" directories. Resource and Provider names combine the cookbook name and the file name with an underscore. The only exception to this convention are files named 'default.rb'. In this case, the Resource or Provider is named according to the cookbook name only. ExamplesNote: there is no default LWRP for the AWS cookbook; they are referenced only for illustrating how names correspond.
|
|
ResourcesA Resource can be thought of as an abstract interface. Each is defined by its attributes and their validation rules, as well as the names of the actions it can take. Keyword: actionsActions are specified using the "actions" keyword followed by a comma-separated list of names. For example, the line specifies that the list of allowed actions for this resource should include foo and bar and ultimately corresponds to the implementing Provider's "action_foo" and "action_bar" methods. Note: several "actions" declarations will append to, not overwrite, the list of allowed actions. Keyword: attributeAttributes are specified using the "attribute" keyword followed by the attribute's name and an optional set of validation rules. For example, the line creates an attribute named foo, accessible to the implementing Provider via the resource's "foo" method, with no validation; whereas, the line creates an attribute named bar (accessible to the implementing Provider via the resource's "bar" method) that enforces that values specified in recipes must be of type String. Validation parametersThe full set of options that can be passed to the attribute keyword in order to validate a parameter set on a Resource in a Recipe is:
Default Provider when invoking an LWR in a RecipeIf you omit the provider attribute when using an LWR in a recipe, Chef will look for an LWP of the same name in the same cookbook by default. So, you can write: "Example LWR usage without an explicit Provider" instead of: "Example LWR usage with an explicit Provider" Example, creating a Lightweight ResourceIn order to demonstrate, let's contrast the implementation of the existing (heavyweight) File Resource with a Lightweight Resource of the same functionality: "Chef::Resource::File circa Chef 0.7.8" The above code is simple, traditional ruby--no magic at all. We are creating a number of getter/setter methods and validating that the inputs match some criteria (a regex, a string, true/false, etc.). The lightweight version looks like: Lightweight File Resource Hopefully this is simpler to write and understand. ProvidersA provider is the underlying implementation which brings the resource into the desired state. BackgroundThe chef-client runs in two stages
Keyword: actionActions are defined using the "action" keyword. Attributes from the originating Resource are accessible through the Default ActionAs of version 0.10.10 specifying a default_action can be done using The above code will create a valid resource with no default action on versions prior to 0.10.10.
In-line Resources in Provider ActionsThe Recipe DSL has been extended to Providers, meaning Resources can be constructed and executed in-line in the bodies of Provider actions (see example using the "execute" Resource below.) ImplementationFor the curious, when a Provider references new Resources in-line, they are inserted into the ResourceCollection in order of appearance after the currently-executing Resource. For example, if after phase 1, the ResourceCollection contains the Resources [A,B] and during phase 2, the action run on A's Provider references Resources C and D in-line, the ResourceCollection (and execution order) will end up as [A,C,D,B]. Example, creating a Lightweight ProviderTaking the database example, our Resource might be defined by: /cookbooks/opscode/resources/database.rb A mysql Provider might look like: /cookbooks/opscode/providers/mysql.rb This would create a new Provider (Chef::Provider::OpscodeMysql) with a load_current_resource that does nothing, along with two methods, action_create and action_delete. When either of these methods is invoked, the corresponding block is executed, including properly resolving Using our resource in a recipe: using the database resource Would create a database called monkeynews. It would also allow you to trivially switch out the database back-end. Extending An Existing ProviderIf you'd like to write a LWP that extends another provider class, you can accomplish that as a mixin, which you would then place in a library under the library directory of the cookbook using that extended class. Your LWRP would then be written to include that library in the provider implementation to get access to the extended core resource. For an example, see the Transmission Cookbook, which includes a `transmission_torrent_file` LWRP that allows you to download a file via the BitTorrent protocol. This `transmission_torrent_file` LWRP are an extension of the existing file and remote_file resources. Further ReadingView slides from a talk on Understanding LWRP Development |
|



