summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/chef/provider/lwrp_base.rb3
-rw-r--r--lib/chef/resource.rb90
-rw-r--r--lib/chef/resource/lwrp_base.rb125
-rw-r--r--lib/chef/resources.rb1
-rw-r--r--lib/chef/run_context/cookbook_compiler.rb2
-rw-r--r--spec/unit/lwrp_spec.rb14
6 files changed, 137 insertions, 98 deletions
diff --git a/lib/chef/provider/lwrp_base.rb b/lib/chef/provider/lwrp_base.rb
index 54ba23e728..1ae17e288c 100644
--- a/lib/chef/provider/lwrp_base.rb
+++ b/lib/chef/provider/lwrp_base.rb
@@ -1,7 +1,8 @@
#
# Author:: Adam Jacob (<adam@opscode.com>)
# Author:: Christopher Walters (<cw@opscode.com>)
-# Copyright:: Copyright (c) 2008, 2009 Opscode, Inc.
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2008-2012 Opscode, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 9a1b983360..c49bb6684e 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -125,6 +125,7 @@ F
include Chef::Mixin::ConvertToClassName
include Chef::Mixin::Deprecation
+ extend Chef::Mixin::ConvertToClassName
# Set or return the list of "state attributes" implemented by the Resource
# subclass. State attributes are attributes that describe the desired state
@@ -662,95 +663,6 @@ F
nil
end
- extend Chef::Mixin::ConvertToClassName
-
- def self.attribute(attr_name, validation_opts={})
- # This atrocity is the only way to support 1.8 and 1.9 at the same time
- # When you're ready to drop 1.8 support, do this:
- # define_method attr_name.to_sym do |arg=nil|
- # etc.
- shim_method=<<-SHIM
- def #{attr_name}(arg=nil)
- _set_or_return_#{attr_name}(arg)
- end
- SHIM
- class_eval(shim_method)
-
- define_method("_set_or_return_#{attr_name.to_s}".to_sym) do |arg|
- set_or_return(attr_name.to_sym, arg, validation_opts)
- end
- end
-
- def self.build_from_file(cookbook_name, filename, run_context)
- rname = filename_to_qualified_string(cookbook_name, filename)
-
- # Add log entry if we override an existing light-weight resource.
- class_name = convert_to_class_name(rname)
- overriding = Chef::Resource.const_defined?(class_name)
- Chef::Log.info("#{class_name} light-weight resource already initialized -- overriding!") if overriding
-
- new_resource_class = Class.new self do |cls|
-
- # default initialize method that ensures that when initialize is finally
- # wrapped (see below), super is called in the event that the resource
- # definer does not implement initialize
- def initialize(name, run_context)
- super(name, run_context)
- end
-
- @actions_to_create = []
-
- class << cls
- include Chef::Mixin::FromFile
-
- attr_accessor :run_context
- attr_reader :action_to_set_default
-
- def node
- self.run_context.node
- end
-
- def actions_to_create
- @actions_to_create
- end
-
- define_method(:default_action) do |action_name|
- actions_to_create.push(action_name)
- @action_to_set_default = action_name
- end
-
- define_method(:actions) do |*action_names|
- actions_to_create.push(*action_names)
- end
- end
-
- # set the run context in the class instance variable
- cls.run_context = run_context
-
- # load resource definition from file
- cls.class_from_file(filename)
-
- # create a new constructor that wraps the old one and adds the actions
- # specified in the DSL
- old_init = instance_method(:initialize)
-
- define_method(:initialize) do |name, *optional_args|
- args_run_context = optional_args.shift
- @resource_name = rname.to_sym
- old_init.bind(self).call(name, args_run_context)
- @action = self.class.action_to_set_default || @action
- allowed_actions.push(self.class.actions_to_create).flatten!
- end
- end
-
- # register new class as a Chef::Resource
- class_name = convert_to_class_name(rname)
- Chef::Resource.const_set(class_name, new_resource_class)
- Chef::Log.debug("Loaded contents of #{filename} into a resource named #{rname} defined in Chef::Resource::#{class_name}")
-
- new_resource_class
- end
-
# Resources that want providers namespaced somewhere other than
# Chef::Provider can set the namespace with +provider_base+
# Ex:
diff --git a/lib/chef/resource/lwrp_base.rb b/lib/chef/resource/lwrp_base.rb
new file mode 100644
index 0000000000..af743b000e
--- /dev/null
+++ b/lib/chef/resource/lwrp_base.rb
@@ -0,0 +1,125 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Christopher Walters (<cw@opscode.com>)
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2008-2012 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class Chef
+ class Resource
+
+ # == Chef::Resource::LWRPBase
+ # Base class for LWRP resources. Adds DSL sugar on top of Chef::Resource,
+ # so attributes, default action, etc. can be defined with pleasing syntax.
+ class LWRPBase < Resource
+
+ NULL_ARG = Object.new
+
+ extend Chef::Mixin::ConvertToClassName
+ extend Chef::Mixin::FromFile
+
+ # Evaluates the LWRP resource file and instantiates a new Resource class.
+ def self.build_from_file(cookbook_name, filename, run_context)
+ rname = filename_to_qualified_string(cookbook_name, filename)
+
+ # Add log entry if we override an existing light-weight resource.
+ class_name = convert_to_class_name(rname)
+ overriding = Chef::Resource.const_defined?(class_name)
+ Chef::Log.info("#{class_name} light-weight resource already initialized -- overriding!") if overriding
+
+ resource_class = Class.new(self)
+
+ resource_class.resource_name = rname
+ resource_class.run_context = run_context
+ resource_class.class_from_file(filename)
+
+ Chef::Resource.const_set(class_name, resource_class)
+ Chef::Log.debug("Loaded contents of #{filename} into a resource named #{rname} defined in Chef::Resource::#{class_name}")
+
+ resource_class
+ end
+
+ # Set the resource snake_case name. Should only be called via
+ # build_from_file Should only be called via build_from_file.
+ def self.resource_name=(resource_name)
+ @resource_name = resource_name
+ end
+
+ # Returns the resource snake_case name
+ def self.resource_name
+ @resource_name
+ end
+
+ # Define an attribute on this resource, including optional validation
+ # parameters.
+ def self.attribute(attr_name, validation_opts={})
+ # Ruby 1.8 doesn't support default arguments to blocks, but we have to
+ # use define_method with a block to capture +validation_opts+.
+ # Workaround this by defining two methods :(
+ class_eval(<<-SHIM, __FILE__, __LINE__)
+ def #{attr_name}(arg=nil)
+ _set_or_return_#{attr_name}(arg)
+ end
+ SHIM
+
+ define_method("_set_or_return_#{attr_name.to_s}".to_sym) do |arg|
+ set_or_return(attr_name.to_sym, arg, validation_opts)
+ end
+ end
+
+ # Sets the default action
+ def self.default_action(action_name=NULL_ARG)
+ unless action_name.equal?(NULL_ARG)
+ valid_actions.push(action_name)
+ @default_action = action_name
+ end
+ @default_action
+ end
+
+ # Adds +action_names+ to the list of valid actions for this resource.
+ def self.actions(*action_names)
+ valid_actions.push(*action_names)
+ end
+
+ def self.valid_actions
+ @valid_actions ||= []
+ end
+
+ # Set the run context on the class. Used to provide access to the node
+ # during class definition.
+ def self.run_context=(run_context)
+ @run_context = run_context
+ end
+
+ def self.run_context
+ @run_context
+ end
+
+ def self.node
+ run_context.node
+ end
+
+ # Default initializer. Sets the default action and allowed actions.
+ def initialize(name, run_context=nil)
+ super(name, run_context)
+ @resource_name = self.class.resource_name.to_sym
+ @action = self.class.default_action
+ allowed_actions.push(self.class.valid_actions).flatten!
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 7fadb17444..f4212f1498 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -65,3 +65,4 @@ require 'chef/resource/template'
require 'chef/resource/timestamped_deploy'
require 'chef/resource/user'
require 'chef/resource/yum_package'
+require 'chef/resource/lwrp_base'
diff --git a/lib/chef/run_context/cookbook_compiler.rb b/lib/chef/run_context/cookbook_compiler.rb
index 784458fdce..0b65569cbe 100644
--- a/lib/chef/run_context/cookbook_compiler.rb
+++ b/lib/chef/run_context/cookbook_compiler.rb
@@ -205,7 +205,7 @@ class Chef
def load_lwrp_resource(cookbook_name, filename)
Chef::Log.debug("Loading cookbook #{cookbook_name}'s resources from #{filename}")
- Chef::Resource.build_from_file(cookbook_name, filename, self)
+ Chef::Resource::LWRPBase.build_from_file(cookbook_name, filename, self)
@events.lwrp_file_loaded(filename)
rescue Exception => e
@events.lwrp_file_load_failed(filename, e)
diff --git a/spec/unit/lwrp_spec.rb b/spec/unit/lwrp_spec.rb
index a399ee0521..b28fd812a2 100644
--- a/spec/unit/lwrp_spec.rb
+++ b/spec/unit/lwrp_spec.rb
@@ -25,12 +25,12 @@ describe "override logging" do
it "should log if attempting to load resource of same name" do
Dir[File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "lwrp", "resources", "*"))].each do |file|
- Chef::Resource.build_from_file("lwrp", file, nil)
+ Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
end
Dir[File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "lwrp_override", "resources", "*"))].each do |file|
Chef::Log.should_receive(:info).with(/overriding/)
- Chef::Resource.build_from_file("lwrp", file, nil)
+ Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
end
end
@@ -61,11 +61,11 @@ describe "LWRP" do
before do
Dir[File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "lwrp", "resources", "*"))].each do |file|
- Chef::Resource.build_from_file("lwrp", file, nil)
+ Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
end
Dir[File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "lwrp_override", "resources", "*"))].each do |file|
- Chef::Resource.build_from_file("lwrp", file, nil)
+ Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
end
end
@@ -99,7 +99,7 @@ describe "LWRP" do
run_context = Chef::RunContext.new(node, Chef::CookbookCollection.new, @events)
Dir[File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "lwrp", "resources_with_default_attributes", "*"))].each do |file|
- Chef::Resource.build_from_file("lwrp", file, run_context)
+ Chef::Resource::LWRPBase.build_from_file("lwrp", file, run_context)
end
cls = Chef::Resource.const_get("LwrpNodeattr")
@@ -122,11 +122,11 @@ describe "LWRP" do
before(:each) do
Dir[File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "lwrp", "resources", "*"))].each do |file|
- Chef::Resource.build_from_file("lwrp", file, @run_context)
+ Chef::Resource::LWRPBase.build_from_file("lwrp", file, @run_context)
end
Dir[File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "lwrp_override", "resources", "*"))].each do |file|
- Chef::Resource.build_from_file("lwrp", file, @run_context)
+ Chef::Resource::LWRPBase.build_from_file("lwrp", file, @run_context)
end
Dir[File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "lwrp", "providers", "*"))].each do |file|