summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Lewis <nick@puppetlabs.com>2011-08-16 11:45:55 -0700
committerNick Lewis <nick@puppetlabs.com>2011-08-16 11:45:55 -0700
commit66d852bb2c2b66ff5e7c9966fdb510e2edd529db (patch)
treec5e682eda7956676f43091927723842c76f6802d
parent39116d4a6ed4861e46b16ba26c679a8b346fca00 (diff)
parent1049458461b5ec5e1e48ad0244d63eb24626b09d (diff)
downloadpuppet-66d852bb2c2b66ff5e7c9966fdb510e2edd529db.tar.gz
puppet-66d852bb2c2b66ff5e7c9966fdb510e2edd529db.tar.xz
puppet-66d852bb2c2b66ff5e7c9966fdb510e2edd529db.zip
Merge branch '2.7.x'
Conflicts: lib/puppet/provider/augeas/augeas.rb spec/unit/node_spec.rb
-rw-r--r--lib/puppet/provider/exec/posix.rb32
-rwxr-xr-xlib/puppet/type/exec.rb17
-rwxr-xr-xspec/integration/node_spec.rb3
-rwxr-xr-xspec/unit/application/apply_spec.rb10
-rwxr-xr-xspec/unit/node_spec.rb5
-rwxr-xr-xspec/unit/provider/exec/posix_spec.rb209
6 files changed, 142 insertions, 134 deletions
diff --git a/lib/puppet/provider/exec/posix.rb b/lib/puppet/provider/exec/posix.rb
index 157d0f28d..782f1eac6 100644
--- a/lib/puppet/provider/exec/posix.rb
+++ b/lib/puppet/provider/exec/posix.rb
@@ -76,26 +76,26 @@ Puppet::Type.type(:exec).provide :posix do
def checkexe(command)
exe = extractexe(command)
- if resource[:path]
- if Puppet.features.posix? and !File.exists?(exe)
- withenv :PATH => resource[:path].join(File::PATH_SEPARATOR) do
- exe = which(exe) || raise(ArgumentError,"Could not find command '#{exe}'")
- end
- elsif Puppet.features.microsoft_windows? and !File.exists?(exe)
- resource[:path].each do |path|
- [".exe", ".ps1", ".bat", ".com", ""].each do |extension|
- file = File.join(path, exe+extension)
- return if File.exists?(file)
- end
- end
+ if File.expand_path(exe) == exe
+ if !File.exists?(exe)
+ raise ArgumentError, "Could not find command '#{exe}'"
+ elsif !File.file?(exe)
+ raise ArgumentError, "'#{exe}' is a #{File.ftype(exe)}, not a file"
+ elsif !File.executable?(exe)
+ raise ArgumentError, "'#{exe}' is not executable"
end
+ return
end
- raise ArgumentError, "Could not find command '#{exe}'" unless File.exists?(exe)
- unless File.executable?(exe)
- raise ArgumentError,
- "'#{exe}' is not executable"
+ if resource[:path]
+ withenv :PATH => resource[:path].join(File::PATH_SEPARATOR) do
+ return if which(exe)
+ end
end
+
+ # 'which' will only return the command if it's executable, so we can't
+ # distinguish not found from not executable
+ raise ArgumentError, "Could not find command '#{exe}'"
end
def extractexe(command)
diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb
index 3ba488f19..35e0c96d7 100755
--- a/lib/puppet/type/exec.rb
+++ b/lib/puppet/type/exec.rb
@@ -311,17 +311,20 @@ module Puppet
end
newcheck(:creates, :parent => Puppet::Parameter::Path) do
- desc "A file that this command creates. If this
+ desc <<-EOT
+ A file that this command creates. If this
parameter is provided, then the command will only be run
- if the specified file does not exist:
+ if the specified file does not exist.
- exec { \"tar xf /my/tar/file.tar\":
- cwd => \"/var/tmp\",
- creates => \"/var/tmp/myfile\",
- path => [\"/usr/bin\", \"/usr/sbin\"]
+ exec { "tar -xf /Volumes/nfs02/important.tar":
+ cwd => "/var/tmp",
+ creates => "/var/tmp/myfile",
+ path => ["/usr/bin", "/usr/sbin"]
}
- "
+ In this example, if `/var/tmp/myfile` is ever deleted, the exec
+ will bring it back by re-extracting the tarball.
+ EOT
accept_arrays
diff --git a/spec/integration/node_spec.rb b/spec/integration/node_spec.rb
index 4ea6142e2..b81a1fdc3 100755
--- a/spec/integration/node_spec.rb
+++ b/spec/integration/node_spec.rb
@@ -10,6 +10,9 @@ require 'puppet/node'
describe Puppet::Node do
describe "when delegating indirection calls" do
before do
+ Puppet::Node.indirection.reset_terminus_class
+ Puppet::Node.indirection.cache_class = nil
+
@name = "me"
@node = Puppet::Node.new(@name)
end
diff --git a/spec/unit/application/apply_spec.rb b/spec/unit/application/apply_spec.rb
index f3ad893d3..1723258a6 100755
--- a/spec/unit/application/apply_spec.rb
+++ b/spec/unit/application/apply_spec.rb
@@ -12,6 +12,14 @@ describe Puppet::Application::Apply do
Puppet::Util::Log.stubs(:newdestination)
end
+ after :each do
+ Puppet::Node::Facts.indirection.reset_terminus_class
+ Puppet::Node::Facts.indirection.cache_class = nil
+
+ Puppet::Node.indirection.reset_terminus_class
+ Puppet::Node.indirection.cache_class = nil
+ end
+
[:debug,:loadclasses,:verbose,:use_nodes,:detailed_exitcodes].each do |option|
it "should declare handle_#{option} method" do
@apply.should respond_to("handle_#{option}".to_sym)
@@ -48,7 +56,6 @@ describe Puppet::Application::Apply do
end
describe "during setup" do
-
before :each do
Puppet::Log.stubs(:newdestination)
Puppet.stubs(:parse_config)
@@ -111,7 +118,6 @@ describe Puppet::Application::Apply do
end
describe "when executing" do
-
it "should dispatch to 'apply' if it was called with 'apply'" do
@apply.options[:catalog] = "foo"
diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb
index 5f3e3b44d..a47c716f4 100755
--- a/spec/unit/node_spec.rb
+++ b/spec/unit/node_spec.rb
@@ -201,11 +201,8 @@ end
describe Puppet::Node, "when indirecting" do
it "should default to the 'plain' node terminus" do
Puppet::Node.indirection.reset_terminus_class
- Puppet::Node.indirection.terminus_class.should == :plain
- end
- it "should not have a cache class defined" do
- Puppet::Node.indirection.cache_class.should be_nil
+ Puppet::Node.indirection.terminus_class.should == :plain
end
end
diff --git a/spec/unit/provider/exec/posix_spec.rb b/spec/unit/provider/exec/posix_spec.rb
index 50697d826..876b9724d 100755
--- a/spec/unit/provider/exec/posix_spec.rb
+++ b/spec/unit/provider/exec/posix_spec.rb
@@ -1,120 +1,119 @@
#!/usr/bin/env rspec
require 'spec_helper'
-provider_class = Puppet::Type.type(:exec).provider(:posix)
+describe Puppet::Type.type(:exec).provider(:posix) do
+ include PuppetSpec::Files
+
+ def make_exe
+ command = tmpfile('my_command')
+ FileUtils.touch(command)
+ File.chmod(0755, command)
+ command
+ end
+
+ let(:resource) { Puppet::Type.type(:exec).new(:title => '/foo') }
+ let(:provider) { described_class.new(resource) }
-describe provider_class do
before :each do
- @resource = Puppet::Resource.new(:exec, 'foo')
- @provider = provider_class.new(@resource)
+ Puppet.features.stubs(:posix?).returns(true)
+ Puppet.features.stubs(:microsoft_windows?).returns(false)
+ end
+
+ describe "#validatecmd" do
+ it "should fail if no path is specified and the command is not fully qualified" do
+ expect { provider.validatecmd("foo") }.to raise_error(
+ Puppet::Error,
+ "'foo' is not qualified and no path was specified. Please qualify the command or specify a path."
+ )
+ end
+
+ it "should pass if a path is given" do
+ provider.resource[:path] = ['/bogus/bin']
+ provider.validatecmd("../foo")
+ end
+
+ it "should pass if command is fully qualifed" do
+ provider.resource[:path] = ['/bogus/bin']
+ provider.validatecmd("/bin/blah/foo")
+ end
end
- ["posix", "microsoft_windows"].each do |feature|
- describe "when in #{feature} environment" do
- before :each do
- if feature == "microsoft_windows"
- Puppet.features.stubs(:microsoft_windows?).returns(true)
- Puppet.features.stubs(:posix?).returns(false)
- else
- Puppet.features.stubs(:posix?).returns(true)
- Puppet.features.stubs(:microsoft_windows?).returns(false)
- end
+ describe "#run" do
+ describe "when the command is an absolute path" do
+ let(:command) { tmpfile('foo') }
+
+ it "should fail if the command doesn't exist" do
+ expect { provider.run(command) }.to raise_error(ArgumentError, "Could not find command '#{command}'")
+ end
+
+ it "should fail if the command isn't a file" do
+ FileUtils.mkdir(command)
+ FileUtils.chmod(0755, command)
+
+ expect { provider.run(command) }.to raise_error(ArgumentError, "'#{command}' is a directory, not a file")
+ end
+
+ it "should fail if the command isn't executable" do
+ FileUtils.touch(command)
+
+ expect { provider.run(command) }.to raise_error(ArgumentError, "'#{command}' is not executable")
+ end
+ end
+
+ describe "when the command is a relative path" do
+ it "should execute the command if it finds it in the path and is executable" do
+ command = make_exe
+ provider.resource[:path] = [File.dirname(command)]
+ filename = File.basename(command)
+
+ Puppet::Util.expects(:execute).with { |cmdline, arguments| (cmdline == [filename]) && (arguments.is_a? Hash) }
+
+ provider.run(filename)
end
- describe "#validatecmd" do
- it "should fail if no path is specified and the command is not fully qualified" do
- lambda { @provider.validatecmd("foo") }.should raise_error(
- Puppet::Error,
- "'foo' is not qualified and no path was specified. Please qualify the command or specify a path."
- )
- end
-
- it "should pass if a path is given" do
- @provider.resource[:path] = ['/bogus/bin']
- @provider.validatecmd("../foo")
- end
-
- it "should pass if command is fully qualifed" do
- @provider.resource[:path] = ['/bogus/bin']
- @provider.validatecmd("/bin/blah/foo")
- end
+ it "should fail if the command isn't in the path" do
+ resource[:path] = ["/fake/path"]
+
+ expect { provider.run('foo') }.to raise_error(ArgumentError, "Could not find command 'foo'")
end
- describe "#run" do
- it "should fail if no path is specified and command does not exist" do
- lambda { @provider.run("foo") }.should raise_error(ArgumentError, "Could not find command 'foo'")
- end
-
- it "should fail if the command isn't in the path" do
- @provider.resource[:path] = ['/bogus/bin']
- lambda { @provider.run("foo") }.should raise_error(ArgumentError, "Could not find command 'foo'")
- end
-
- it "should fail if the command isn't executable" do
- @provider.resource[:path] = ['/bogus/bin']
- File.stubs(:exists?).with("foo").returns(true)
-
- lambda { @provider.run("foo") }.should raise_error(ArgumentError, "'foo' is not executable")
- end
-
- it "should not be able to execute shell builtins" do
- @provider.resource[:path] = ['/bin']
- lambda { @provider.run("cd ..") }.should raise_error(ArgumentError, "Could not find command 'cd'")
- end
-
- it "should execute the command if the command given includes arguments or subcommands" do
- @provider.resource[:path] = ['/bogus/bin']
- File.stubs(:exists?).returns(false)
- File.stubs(:exists?).with("foo").returns(true)
- File.stubs(:executable?).with("foo").returns(true)
-
- Puppet::Util.expects(:execute).with() { |command, arguments| (command == ['foo bar --sillyarg=true --blah']) && (arguments.is_a? Hash) }
- @provider.run("foo bar --sillyarg=true --blah")
- end
-
- it "should fail if quoted command doesn't exist" do
- @provider.resource[:path] = ['/bogus/bin']
- File.stubs(:exists?).returns(false)
- File.stubs(:exists?).with("foo").returns(true)
- File.stubs(:executable?).with("foo").returns(true)
-
- lambda { @provider.run('"foo bar --sillyarg=true --blah"') }.should raise_error(ArgumentError, "Could not find command 'foo bar --sillyarg=true --blah'")
- end
-
- it "should execute the command if it finds it in the path and is executable" do
- @provider.resource[:path] = ['/bogus/bin']
- File.stubs(:exists?).with("foo").returns(true)
- File.stubs(:executable?).with("foo").returns(true)
- Puppet::Util.expects(:execute).with() { |command, arguments| (command == ['foo']) && (arguments.is_a? Hash) }
-
- @provider.run("foo")
- end
-
- if feature == "microsoft_windows"
- [".exe", ".ps1", ".bat", ".com", ""].each do |extension|
- it "should check file extension #{extension} when it can't find the executable" do
- @provider.resource[:path] = ['/bogus/bin']
- File.stubs(:exists?).returns(false)
- File.stubs(:exists?).with("/bogus/bin/foo#{extension}").returns(true)
- File.stubs(:executable?).with("foo").returns(true)
- Puppet::Util.expects(:execute).with() { |command, arguments| (command == ['foo']) && (arguments.is_a? Hash) }
-
- @provider.run("foo")
- end
- end
- end
-
- it "should warn if you're overriding something in environment" do
- @provider.resource[:environment] = ['WHATEVER=/something/else', 'WHATEVER=/foo']
- File.stubs(:exists?).returns(false)
- File.stubs(:exists?).with("foo").returns(true)
- File.stubs(:executable?).with("foo").returns(true)
-
- Puppet::Util.expects(:execute).with() { |command, arguments| (command == ['foo']) && (arguments.is_a? Hash) }
- @provider.run("foo")
- @logs.map {|l| "#{l.level}: #{l.message}" }.should == ["warning: Overriding environment setting 'WHATEVER' with '/foo'"]
- end
+ it "should fail if the command is in the path but not executable" do
+ command = tmpfile('foo')
+ FileUtils.touch(command)
+ resource[:path] = [File.dirname(command)]
+ filename = File.basename(command)
+
+ expect { provider.run(filename) }.to raise_error(ArgumentError, "Could not find command '#{filename}'")
end
end
+
+ it "should not be able to execute shell builtins" do
+ provider.resource[:path] = ['/bin']
+ expect { provider.run("cd ..") }.to raise_error(ArgumentError, "Could not find command 'cd'")
+ end
+
+ it "should execute the command if the command given includes arguments or subcommands" do
+ provider.resource[:path] = ['/bogus/bin']
+ command = make_exe
+
+ Puppet::Util.expects(:execute).with { |cmdline, arguments| (cmdline == ["#{command} bar --sillyarg=true --blah"]) && (arguments.is_a? Hash) }
+ provider.run("#{command} bar --sillyarg=true --blah")
+ end
+
+ it "should fail if quoted command doesn't exist" do
+ provider.resource[:path] = ['/bogus/bin']
+ command = "/foo bar --sillyarg=true --blah"
+
+ expect { provider.run(%Q["#{command}"]) }.to raise_error(ArgumentError, "Could not find command '#{command}'")
+ end
+
+ it "should warn if you're overriding something in environment" do
+ provider.resource[:environment] = ['WHATEVER=/something/else', 'WHATEVER=/foo']
+ command = make_exe
+
+ Puppet::Util.expects(:execute).with { |cmdline, arguments| (cmdline== [command]) && (arguments.is_a? Hash) }
+ provider.run(command)
+ @logs.map {|l| "#{l.level}: #{l.message}" }.should == ["warning: Overriding environment setting 'WHATEVER' with '/foo'"]
+ end
end
end