1. LWRP DEVELOPMENT
Speaker:
Brian Bianco
Email: brian.bianco@gmail.com
Twitter: @brianwbianco
http://github.com/brianbianco
2. RESOURCES
• Resources represent a piece of system state
• We supply resources with data
• Ordering of resources is important
• Chef ’s Recipe DSL creates resources
• During the compile phase these resources are added to
the resource collection
Example of a resource in a recipe:
4. PROVIDERS
•Providers are the underlying implementation of a resource
•They are loaded by Chef::RunContext before Resources
• Node attributes are NOT available to them
(they can however be passed in via resource attributes)
• Normal providers are selected by Chef::Platform
6. WHAT ARE LWRPS
• A DSL provided to make writing resources and providers easier
• Useful for creating your own resources and providers
without having to implement the actual ruby classes
• LWRP has two components: Resource & Provider
• Great way to abstract some repeated pattern
7. FILE STRUCTURE
Filename paths are relative to:
/cookbooks/lwrpdemo
Filename Resource / Provider Generated Class
Name
resources/default.rb lwrpdemo Chef::Resource::Lwrpdemo
providers/default.rb lwrpdemo Chef::Provider::Lwrpdemo
resources/directory.rb lwrpdemo_directory Chef::Resource::LwrpdemoDirectory
providers/directory.rb lwrpdemo_directory Chef::Provider::LwrpdemoDirectory
9. • Resources will look for providers by the same name
(you can specify one with the provider resource attribute)
• Actions defined in the resource correspond to action methods
in the provider
• Attributes correspond to methods for the resource
(These are called parameters)
• Validation parameters:
:default
:kind_of
:required
:regex
:equal_to
:name_attribute
:callbacks
:respond_to
11. load_current_resource
•This method is responsible for loading the current state of
the resource into @current_resource
• @current_resource = Chef::Resource::LwrpdemoDirectory.new(new_resource.name)
updated_by_last_action
•Call this method when the provider changes something
• When called with true, will fire off notifications
12. ANOTHER PROVIDER EXAMPLE
Python VirtualEnv Create Action
Checking to see if the virtual env exists already
13. NESTED RESOURCES
• Resources can be nested inside of light weight providers
• If those resources call updated_by_last action your
provider will not inherit that
• Luckily there is a pattern you can use to solve this!
• You can use the updated? method on any resource in
the Chef::ResourceCollection
15. TIPS
• Check out others cookbooks, especially the opscode teams
• The default recipe should just make the resource available and
setup any necessary files and configurations
• The #chef channel on irc.freenode.org is full of helpful people
• The mailing list is a great place to ask questions
http://lists.opscode.com
Lets first talk about resources and providers in general (and their ‘non light weight’ implementations)\nResources are a great way to abstract repeatable patterns\nShorcuts I may say => ivar = instance variable, DSL = domain specific language, \n
RunContext order -> Libraries, Providers, Resources, Attributes, Definitions, Recipes\nArgument after resource name is called the “Name attribute”\n\n\n
chef-0.10.10/lib/chef/resource/directory.rb\nRegular ruby class\nresource attributes are methods\nPath is the “name” attribute\n
Chef::Platform contains a HASH of default providers based on operating systems\n\n
All resource actions are named action_<action name>\nload_current_resource is responsible for determining the current state of the resource (where we are)\nnew resource is the state we want the resource in (where we want to be)\nRegular ruby class (This one inherits from Chef::Provider::File)\n\n
\n
\n
name_attribute is populated by the name given when the resource is called\ndefault_action is chef 0.10.10 and above (Will show you later how to do 0.10.8 and below)\nall resources get the :nothing action\nTwo parameters for &#x201C;attribute&#x201D; Name of the attribute and the validation parameters\n\n\n
Resource parameters (attributes) are not to be confused with node attributes!\nprovider Chef::Provider::Cookbookname::Providername or provider :my_other_provider\nList of validation parameters\n\n\n\n
You can use other chef resources inside of your providers\nYou can access data passed into the resource via new_resource.<attribute name>\nAll resource actions are implemented here!\nOnly one method for this DSL -> action\n\n
\n
Could also use: \nmyvar = Chef::ShellOut.new(&#x201C;Some Command&#x201D;)\nmyvar.run_command (runs the command)\nmyvar.stdout (the output)\n
\n
the run_context is only needed for the case of wanting to use methods like #user, #mount, #cookbook_file\nthe sub_run_context is a subset of resource executed in the provider (since you initialize its ResourceCollection)\nany? Passes the updated function to the set of resources, returns functions that respond with anything other than (nil,false)\nrun_context loads and tracks the context of a chef run\nconverge: iterates over the resource_collection in the run_context calling run_action for each resource\n