(#13678) Add filename extension on absolute paths on windows
Running Facter::Util::Resolution.exec calls
Facter::Util::Resolution.which to get the absolute pathname to a binary.
If passing a relative path, puppet will check different search paths and
different filename extensions (like .com, .exe) to find the absolute
path on windows machines
For absolute paths the former behaviour was to just return true if the
path is a valid path to an executable, so "C:\Windows\System32\netsh"
was treated as invalid because it misses the correct extension
(netsh.exe) which caused the ipaddress6 fact to fail.
Change the behaviour of Facter::Util::Resolution.which to also try out
the different filename extensions if an absolute path is used.
Stefan Schulte
11 years ago
35 | 35 |
def self.which(bin)
|
36 | 36 |
if absolute_path?(bin)
|
37 | 37 |
return bin if File.executable?(bin)
|
|
38 |
if Facter::Util::Config.is_windows? and File.extname(bin).empty?
|
|
39 |
exts = ENV['PATHEXT']
|
|
40 |
exts = exts ? exts.split(File::PATH_SEPARATOR) : %w[.COM .EXE .BAT .CMD]
|
|
41 |
exts.each do |ext|
|
|
42 |
destext = bin + ext
|
|
43 |
if File.executable?(destext)
|
|
44 |
Facter.warnonce("Using Facter::Util::Resolution.which with an absolute path like #{bin} but no fileextension is deprecated. Please add the correct extension (#{ext})")
|
|
45 |
return destext
|
|
46 |
end
|
|
47 |
end
|
|
48 |
end
|
38 | 49 |
else
|
39 | 50 |
search_paths.each do |dir|
|
40 | 51 |
dest = File.join(dir, bin)
|
368 | 368 |
context "when run on windows", :as_platform => :windows do
|
369 | 369 |
before :each do
|
370 | 370 |
Facter::Util::Resolution.stubs(:search_paths).returns ['C:\Windows\system32', 'C:\Windows', 'C:\Windows\System32\Wbem' ]
|
|
371 |
ENV.stubs(:[]).with('PATHEXT').returns nil
|
371 | 372 |
end
|
372 | 373 |
|
373 | 374 |
context "and provided with an absolute path" do
|
|
378 | 379 |
Facter::Util::Resolution.which('\\\\remote\dir\foo.exe').should == '\\\\remote\dir\foo.exe'
|
379 | 380 |
end
|
380 | 381 |
|
|
382 |
it "should return the binary with added extension if executable" do
|
|
383 |
['.COM', '.BAT', '.CMD', '' ].each do |ext|
|
|
384 |
File.stubs(:executable?).with('C:\Windows\system32\netsh'+ext).returns false
|
|
385 |
end
|
|
386 |
File.expects(:executable?).with('C:\Windows\system32\netsh.EXE').returns true
|
|
387 |
|
|
388 |
Facter.expects(:warnonce).with('Using Facter::Util::Resolution.which with an absolute path like C:\\Windows\\system32\\netsh but no fileextension is deprecated. Please add the correct extension (.EXE)')
|
|
389 |
Facter::Util::Resolution.which('C:\Windows\system32\netsh').should == 'C:\Windows\system32\netsh.EXE'
|
|
390 |
end
|
|
391 |
|
381 | 392 |
it "should return nil if the binary is not executable" do
|
382 | 393 |
File.expects(:executable?).with('C:\Tools\foo.exe').returns false
|
383 | 394 |
File.expects(:executable?).with('\\\\remote\dir\foo.exe').returns false
|
|
395 | 406 |
end
|
396 | 407 |
|
397 | 408 |
it "should return the absolute path with file extension if found" do
|
398 | |
ENV.stubs(:[]).with('PATHEXT').returns nil
|
399 | 409 |
['.COM', '.EXE', '.BAT', '.CMD', '' ].each do |ext|
|
400 | 410 |
File.stubs(:executable?).with('C:\Windows\system32\foo'+ext).returns false
|
401 | 411 |
File.stubs(:executable?).with('C:\Windows\System32\Wbem\foo'+ext).returns false
|