[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, upstream, updated. 0.25.5-639-g8f94f35
test branch
puppet-dev at googlegroups.com
Wed Jul 14 10:32:11 UTC 2010
The following commit has been merged in the upstream branch:
commit 86cf226916f793277e2405711993d7ccbc4e7965
Author: Luke Kanies <luke at reductivelabs.com>
Date: Fri Jan 8 17:22:49 2010 -0800
Adding virtual and exported resource support to the DSL
Also changed the internals - we're no longer using
Resource instances with the ruby block, instead
we're using a simple new class. We had to do this
because Resource has too many methods - e.g.,
'file' returned the file name rather than
created a new resource type.
Signed-off-by: Luke Kanies <luke at reductivelabs.com>
diff --git a/lib/puppet/dsl/resource_api.rb b/lib/puppet/dsl/resource_api.rb
index d4f623b..bac26d3 100644
--- a/lib/puppet/dsl/resource_api.rb
+++ b/lib/puppet/dsl/resource_api.rb
@@ -3,13 +3,32 @@
# hooking into the scope system.
require 'puppet/resource/type_collection_helper'
-module Puppet::DSL::ResourceAPI
+class Puppet::DSL::ResourceAPI
include Puppet::Resource::TypeCollectionHelper
FUNCTION_MAP = {:acquire => :include}
+ attr_reader :scope, :resource, :block
+
+ def environment
+ scope.environment
+ end
+
+ def evaluate
+ set_instance_variables
+ instance_eval(&block)
+ end
+
+ def initialize(resource, scope, block)
+ @scope = scope
+ @resource = resource
+ @block = block
+ end
+
# Try to convert a missing method into a resource type or a function.
def method_missing(name, *args)
+ raise "MethodMissing loop when searching for #{name} with #{args.inspect}" if searching_for_method?
+ @searching_for_method = true
return create_resource(name, args[0], args[1]) if valid_type?(name)
name = map_function(name)
@@ -17,10 +36,12 @@ module Puppet::DSL::ResourceAPI
return call_function(name, args) if Puppet::Parser::Functions.function(name)
super
+ ensure
+ @searching_for_method = true
end
def set_instance_variables
- eachparam do |param|
+ resource.eachparam do |param|
instance_variable_set("@#{param.name}", param.value)
end
end
@@ -37,6 +58,8 @@ module Puppet::DSL::ResourceAPI
resource[param] = value
end
+ resource.exported = true if exporting?
+ resource.virtual = true if virtualizing?
scope.compiler.add_resource(scope, resource)
resource
end
@@ -47,6 +70,28 @@ module Puppet::DSL::ResourceAPI
scope.send(method, *args)
end
+ def export(resources = nil, &block)
+ if resources
+ resources.each { |resource| resource.exported = true }
+ return resources
+ end
+ @exporting = true
+ instance_eval(&block)
+ ensure
+ @exporting = false
+ end
+
+ def virtual(resources = nil, &block)
+ if resources
+ resources.each { |resource| resource.virtual = true }
+ return resources
+ end
+ @virtualizing = true
+ instance_eval(&block)
+ ensure
+ @virtualizing = false
+ end
+
def valid_type?(name)
return true if [:class, :node].include?(name)
return true if Puppet::Type.type(name)
@@ -56,7 +101,19 @@ module Puppet::DSL::ResourceAPI
private
+ def exporting?
+ @exporting
+ end
+
def map_function(name)
return FUNCTION_MAP[name] || name
end
+
+ def searching_for_method?
+ @searching_for_method
+ end
+
+ def virtualizing?
+ @virtualizing
+ end
end
diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb
index 2acb990..1192a1a 100644
--- a/lib/puppet/resource/type.rb
+++ b/lib/puppet/resource/type.rb
@@ -220,11 +220,7 @@ class Puppet::Resource::Type
end
def evaluate_ruby_code(resource, scope)
- resource.extend(Puppet::DSL::ResourceAPI)
-
- resource.set_instance_variables
-
- resource.instance_eval(&ruby_code)
+ Puppet::DSL::ResourceAPI.new(resource, scope, ruby_code).evaluate
end
# Split an fq name into a namespace and name
diff --git a/spec/unit/dsl/resource_api.rb b/spec/unit/dsl/resource_api.rb
index 755be30..ddfc4e4 100755
--- a/spec/unit/dsl/resource_api.rb
+++ b/spec/unit/dsl/resource_api.rb
@@ -6,140 +6,176 @@ require 'puppet/dsl/resource_api'
describe Puppet::DSL::ResourceAPI do
before do
- @resource = Puppet::Parser::Resource.new(:type => :mytype, :title => "myresource", :scope => mock("scope"), :source => mock("source"))
- @resource.extend Puppet::DSL::ResourceAPI
+ @compiler = stub 'compiler', :add_resource => nil
+ @scope = stub 'scope', :source => stub("source"), :compiler => @compiler
+ @resource = Puppet::Parser::Resource.new(:type => :mytype, :title => "myresource", :scope => @scope)
+ @api = Puppet::DSL::ResourceAPI.new(@resource, @scope, proc { })
end
it "should include the resource type collection helper" do
Puppet::DSL::ResourceAPI.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper)
end
+ it "should use the scope's environment as its environment" do
+ @scope.expects(:environment).returns "myenv"
+ @api.environment.should == "myenv"
+ end
+
it "should be able to set all of its parameters as instance variables" do
@resource["foo"] = "myval"
- @resource.set_instance_variables
- @resource.instance_variable_get("@foo").should == "myval"
+ @api.set_instance_variables
+ @api.instance_variable_get("@foo").should == "myval"
end
describe "when calling a function" do
it "should return false if the function does not exist" do
Puppet::Parser::Functions.expects(:function).with("myfunc").returns nil
- @resource.call_function("myfunc", "foo").should be_false
+ @api.call_function("myfunc", "foo").should be_false
end
it "should use the scope the call the provided function with the provided arguments and return the results" do
scope = stub 'scope'
- @resource.stubs(:scope).returns scope
+ @api.stubs(:scope).returns scope
Puppet::Parser::Functions.expects(:function).with("myfunc").returns "myfunc_method"
scope.expects(:myfunc_method).with("one", "two")
- @resource.call_function("myfunc", ["one", "two"])
+ @api.call_function("myfunc", ["one", "two"])
+ end
+
+ it "should call 'include' when asked to call 'acquire'" do
+ scope = stub 'scope'
+ @api.stubs(:scope).returns scope
+ @api.stubs(:valid_type?).returns false
+
+ scope.expects(:function_include).with("one", "two")
+ @api.acquire("one", "two")
end
end
describe "when determining if a provided name is a valid type" do
it "should be valid if it's :class" do
- @resource.should be_valid_type(:class)
+ @api.should be_valid_type(:class)
end
it "should be valid if it's :node" do
- @resource.should be_valid_type(:node)
+ @api.should be_valid_type(:node)
end
it "should be valid if it's a builtin type" do
Puppet::Type.expects(:type).with(:mytype).returns "whatever"
- @resource.should be_valid_type(:mytype)
+ @api.should be_valid_type(:mytype)
end
it "should be valid if it's a defined resource type in the environment's known resource types" do
collection = stub 'collection'
- @resource.stubs(:known_resource_types).returns collection
+ @api.stubs(:known_resource_types).returns collection
collection.expects(:definition).with(:mytype).returns "whatever"
- @resource.should be_valid_type(:mytype)
+ @api.should be_valid_type(:mytype)
end
it "should not be valid unless it's a node, class, builtin type, or defined resource" do
collection = stub 'collection'
- @resource.stubs(:known_resource_types).returns collection
+ @api.stubs(:known_resource_types).returns collection
collection.expects(:definition).returns nil
Puppet::Type.expects(:type).returns nil
- @resource.should_not be_valid_type(:mytype)
+ @api.should_not be_valid_type(:mytype)
end
end
describe "when creating a resource" do
before do
- @resource.scope.stubs(:source).returns stub("source")
- @resource.scope.stubs(:compiler).returns stub("compiler", :add_resource => nil)
- @created_resource = Puppet::Parser::Resource.new(:title => "eh", :type => 'yay', :scope => @resource.scope)
+ @api.scope.stubs(:source).returns stub("source")
+ @api.scope.stubs(:compiler).returns stub("compiler", :add_resource => nil)
+ @created_resource = Puppet::Parser::Resource.new(:title => "eh", :type => 'yay', :scope => @api.scope)
end
it "should create and return a resource of the type specified" do
Puppet::Parser::Resource.expects(:new).with { |args| args[:type] == "mytype" }.returns @created_resource
- @resource.create_resource("mytype", "myname", {:foo => "bar"}).should == [@created_resource]
+ @api.create_resource("mytype", "myname", {:foo => "bar"}).should == [@created_resource]
end
it "should use the name from the first element of the provided argument array" do
Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "myname" }.returns @created_resource
- @resource.create_resource("mytype", "myname", {:foo => "bar"})
+ @api.create_resource("mytype", "myname", {:foo => "bar"})
end
it "should create multiple resources if the first element of the argument array is an array" do
- second_resource = Puppet::Parser::Resource.new(:title => "eh", :type => 'yay', :scope => @resource.scope)
+ second_resource = Puppet::Parser::Resource.new(:title => "eh", :type => 'yay', :scope => @api.scope)
Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "first" }.returns @created_resource
Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "second" }.returns @created_resource
- @resource.create_resource("mytype", ["first", "second"], {:foo => "bar"})
+ @api.create_resource("mytype", ["first", "second"], {:foo => "bar"})
end
it "should provide its scope as the scope" do
- Puppet::Parser::Resource.expects(:new).with { |args| args[:scope] == @resource.scope }.returns @created_resource
- @resource.create_resource("mytype", "myname", {:foo => "bar"})
+ Puppet::Parser::Resource.expects(:new).with { |args| args[:scope] == @api.scope }.returns @created_resource
+ @api.create_resource("mytype", "myname", {:foo => "bar"})
end
it "should set each provided argument as a parameter on the created resource" do
- result = @resource.create_resource("mytype", "myname", {"foo" => "bar", "biz" => "baz"}).shift
+ result = @api.create_resource("mytype", "myname", {"foo" => "bar", "biz" => "baz"}).shift
result["foo"].should == "bar"
result["biz"].should == "baz"
end
it "should add the resource to the scope's copmiler" do
Puppet::Parser::Resource.expects(:new).returns @created_resource
- @resource.scope.compiler.expects(:add_resource).with(@resource.scope, @created_resource)
- @resource.create_resource("mytype", "myname", {:foo => "bar"})
+ @api.scope.compiler.expects(:add_resource).with(@api.scope, @created_resource)
+ @api.create_resource("mytype", "myname", {:foo => "bar"})
end
it "should fail if the resource parameters are not a hash" do
- lambda { @resource.create_resource("mytype", "myname", %w{foo bar}) }.should raise_error(ArgumentError)
+ lambda { @api.create_resource("mytype", "myname", %w{foo bar}) }.should raise_error(ArgumentError)
end
end
describe "when an unknown method is called" do
it "should create a resource if the method name is a valid type" do
- @resource.expects(:valid_type?).with(:mytype).returns true
- @resource.expects(:create_resource).with(:mytype, "myname", {:foo => "bar"}).returns true
+ @api.expects(:valid_type?).with(:mytype).returns true
+ @api.expects(:create_resource).with(:mytype, "myname", {:foo => "bar"}).returns true
- @resource.mytype("myname", :foo => "bar")
+ @api.mytype("myname", :foo => "bar")
end
it "should call any function whose name matches the undefined method if the name is not a valid type" do
- @resource.expects(:valid_type?).with(:myfunc).returns false
- @resource.expects(:create_resource).never
+ @api.expects(:valid_type?).with(:myfunc).returns false
+ @api.expects(:create_resource).never
Puppet::Parser::Functions.expects(:function).with(:myfunc).returns true
- @resource.expects(:call_function).with(:myfunc, %w{foo bar})
+ @api.expects(:call_function).with(:myfunc, %w{foo bar})
- @resource.myfunc("foo", "bar")
+ @api.myfunc("foo", "bar")
end
it "should raise a method missing error if the method is neither a type nor a function" do
- @resource.expects(:valid_type?).with(:myfunc).returns false
- @resource.expects(:create_resource).never
+ @api.expects(:valid_type?).with(:myfunc).returns false
+ @api.expects(:create_resource).never
Puppet::Parser::Functions.expects(:function).with(:myfunc).returns false
- @resource.expects(:call_function).never
+ @api.expects(:call_function).never
- lambda { @resource.myfunc("foo", "bar") }.should raise_error(NoMethodError)
+ lambda { @api.myfunc("foo", "bar") }.should raise_error(NoMethodError)
end
end
+
+ it "should mark the specified resource as exported when creating a single exported resource" do
+ resources = @api.export @api.file("/my/file", :ensure => :present)
+ resources[0].should be_exported
+ end
+
+ it "should mark all created resources as exported when creating exported resources using a block" do
+ @compiler.expects(:add_resource).with { |s, res| res.exported == true }
+ @api.export { file "/my/file", :ensure => :present }
+ end
+
+ it "should mark the specified resource as virtual when creating a single virtual resource" do
+ resources = @api.virtual @api.file("/my/file", :ensure => :present)
+ resources[0].should be_virtual
+ end
+
+ it "should mark all created resources as virtual when creating virtual resources using a block" do
+ @compiler.expects(:add_resource).with { |s, res| res.virtual == true }
+ @api.virtual { file "/my/file", :ensure => :present }
+ end
end
diff --git a/spec/unit/resource/type.rb b/spec/unit/resource/type.rb
index d623eca..f0a0fdf 100755
--- a/spec/unit/resource/type.rb
+++ b/spec/unit/resource/type.rb
@@ -371,27 +371,13 @@ describe Puppet::Resource::Type do
end
describe "and ruby code is provided" do
- before do
+ it "should create a DSL Resource API and evaluate it" do
@type.stubs(:ruby_code).returns(proc { "foo" })
- end
-
- it "should instance evaluate the ruby code on the resource" do
- evaluated = false
- @type.stubs(:ruby_code).returns(proc { evaluated = true })
-
- @type.evaluate_code(@resource)
-
- evaluated.should be_true
- end
-
- it "should include the DSL Resource Helper module in the provided resource" do
- @type.evaluate_code(@resource)
-
- @resource.metaclass.ancestors.should be_include(Puppet::DSL::ResourceAPI)
- end
-
- it "should convert the resource's parameters to instance variables" do
- @resource.expects(:set_instance_variables)
+ scope = stub 'scope', :compiler => stub_everything
+ @type.expects(:subscope).returns(scope)
+ @api = stub 'api'
+ Puppet::DSL::ResourceAPI.expects(:new).with(@resource, scope, @type.ruby_code).returns @api
+ @api.expects(:evaluate)
@type.evaluate_code(@resource)
end
--
Puppet packaging for Debian
More information about the Pkg-puppet-devel
mailing list