Skip to content
This repository has been archived by the owner on Jun 5, 2020. It is now read-only.

Commit

Permalink
Adding a remote_resource type and provider
Browse files Browse the repository at this point in the history
The provider is a shell provider, so very simple
but sufficient for some cases.

Signed-off-by: Luke Kanies <luke@reductivelabs.com>
  • Loading branch information
Luke Kanies committed Mar 10, 2010
1 parent e24081d commit 0dfae12
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 0 deletions.
13 changes: 13 additions & 0 deletions lib/puppet/provider/remote_resource/shell.rb
@@ -0,0 +1,13 @@
require 'puppet/util'

Puppet::Type.type(:remote_resource).provide(:shell) do
desc "Check the state of a remote resource using a shell script.
If the script exits with a non-zero code, the resource is considered
to not be up."

include Puppet::Util

def perform_check(command)
execute([command])
end
end
50 changes: 50 additions & 0 deletions lib/puppet/type/remote_resource.rb
@@ -0,0 +1,50 @@
Puppet::Type.newtype(:remote_resource) do
newparam(:name) do
desc "The name of the remote resource."
end

newparam(:frequency) do
desc "How often the check should be executed, in seconds."
defaultto 10

munge { |i| Integer(i) }
end

newparam(:check) do
desc "The check to perform. Usage and specifics are determined
by the provider."
end

newparam(:timeout) do
desc "How long the resource should wait for the remote resource
to come up, in seconds."

defaultto 300

munge { |i| Integer(i) }
end

def retrieve
start = Time.now
while true
return {} if remote_resource_up?
if Time.now - start > self[:timeout]
fail "Remote resource not up within timeout #{self[:timeout]}"
end

info "Remote resource is not up; delaying for #{self[:frequency]} seconds before next check"
sleep self[:frequency]
end
end

private

def remote_resource_up?
begin
provider.perform_check(self[:check])
return true
rescue Puppet::ExecutionFailure
return false
end
end
end
22 changes: 22 additions & 0 deletions spec/unit/provider/remote_resource/shell.rb
@@ -0,0 +1,22 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }

describe Puppet::Type.type(:remote_resource).provider(:shell) do
before do
@resource = stub 'resource'
@provider = Puppet::Type.type(:remote_resource).provider(:shell).new(@resource)
end

it "should exist" do
@provider.should_not be_nil
end

it "should execute the provided shell command within an array" do
@provider.expects(:execute).with(["/my/cmd"])
@provider.perform_check("/my/cmd")
end

it "should pass on any encountered errors" do
@provider.expects(:execute).with(["/my/cmd"]).raises Puppet::ExecutionFailure.new("foo")
lambda { @provider.perform_check("/my/cmd") }.should raise_error(Puppet::ExecutionFailure)
end
end
79 changes: 79 additions & 0 deletions spec/unit/type/remote_resource.rb
@@ -0,0 +1,79 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }

describe Puppet::Type.type(:remote_resource) do
before do
@type = Puppet::Type.type(:remote_resource)
end

it "should exist" do
@type.should_not be_nil
end

it "should have a default provider" do
@type.defaultprovider.should_not be_nil
end

describe "the name parameter" do
it "should exist" do
@type.attrclass(:name).should_not be_nil
end
end

describe "the 'frequency' parameter" do
it "should exist" do
@type.attrclass(:frequency).should_not be_nil
end

it "should convert values to integers" do
@type.new(:name => "foo", :frequency => "50")[:frequency].should == 50
end

it "should default to '10'" do
@type.new(:name => "foo")[:frequency].should == 10
end
end

describe "the 'timeout' parameter" do
it "should exist" do
@type.attrclass(:timeout).should_not be_nil
end

it "should convert values to integers" do
@type.new(:name => "foo", :timeout => "10")[:timeout].should == 10
end

it "should default to '300'" do
@type.new(:name => "foo")[:timeout].should == 300
end
end

describe "when retrieving" do
before do
@resource = @type.new(:name => "foo", :check => "/bin/true")
end

it "should perform_check the check with the provider" do
@resource.provider.expects(:perform_check).with("/bin/true")
@resource.retrieve
end

it "should return '{}' if the check passes" do
@resource.provider.expects(:perform_check)
@resource.retrieve.should == {}
end

it "should sleep for the specified frequency and check again if the check fails" do
@resource.provider.expects(:perform_check).times(2).raises(Puppet::ExecutionFailure.new("foo")).then.returns true
@resource.expects(:sleep).with(@resource[:frequency])
@resource.retrieve.should == {}
end

it "should fail if the check has not passed within the timeout" do
@resource[:timeout] = 1
@resource[:frequency] = 1
@resource.provider.stubs(:perform_check).raises(Puppet::ExecutionFailure.new("foo"))
@resource.stubs(:sleep).with(@resource[:frequency])
lambda { @resource.retrieve }.should raise_error(Puppet::Error)
end
end
end

0 comments on commit 0dfae12

Please sign in to comment.