Symlinks confuse the "What file system am I on?" logic. This patch just
runs the paths through a beefed up version of the standard 'realpath'
method.

Signed-off-by: Jesse Wolfe <[email protected]>

better realpath
---
 lib/puppet/util/selinux.rb |   27 ++++++++++++++++++++++-----
 spec/unit/util/selinux.rb  |   25 +++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/lib/puppet/util/selinux.rb b/lib/puppet/util/selinux.rb
index bdf4415..4b9f389 100644
--- a/lib/puppet/util/selinux.rb
+++ b/lib/puppet/util/selinux.rb
@@ -13,6 +13,8 @@ rescue LoadError
     # Nothing
 end
 
+require 'pathname'
+
 module Puppet::Util::SELinux
 
     def selinux_support?
@@ -185,9 +187,25 @@ module Puppet::Util::SELinux
         return mntpoint
     end
 
+    def realpath(path)
+        pn = Pathname.new(path)
+        begin
+            pn.realpath.to_s
+        rescue
+            # standard realpath fails if the file doesn't exist,
+            # so we recurse to the parent directory and try again
+            realpath(pn.dirname.to_s) + '/' + pn.basename.to_s
+        end
+    end
+
+    def parent_directory(path)
+        pn = Pathname.new(path)
+        pn.dirname.to_s
+    end
+
     # Internal helper function to return which type of filesystem a
     # given file path resides on
-    def find_fs(file)
+    def find_fs(path)
         unless mnts = read_mounts()
             return nil
         end
@@ -198,13 +216,12 @@ module Puppet::Util::SELinux
         # Just in case: return something if you're down to "/" or ""
         # Remove the last slash and everything after it,
         #   and repeat with that as the file for the next loop through.
-        ary = file.split('/')
-        while not ary.empty? do
-            path = ary.join('/')
+        path = realpath(path)
+        while not path.empty? do
             if mnts.has_key?(path)
                 return mnts[path]
             end
-            ary.pop
+            path = parent_directory(path)
         end
         return mnts['/']
     end
diff --git a/spec/unit/util/selinux.rb b/spec/unit/util/selinux.rb
index da4686e..37b15cd 100755
--- a/spec/unit/util/selinux.rb
+++ b/spec/unit/util/selinux.rb
@@ -61,6 +61,31 @@ describe Puppet::Util::SELinux do
             selinux_label_support?('/mnt/nfs/testfile').should be_false
         end
 
+        it "should follow symlinks when determining file systems" do
+            
self.stubs(:realpath).with('/mnt/symlink/testfile').returns('/mnt/nfs/dest/testfile')
+
+            selinux_label_support?('/mnt/symlink/testfile').should be_false
+        end
+
+    end
+
+    describe "realpath" do
+        it "should handle files that don't exist" do
+            # /mnt/symlink/nonexistant
+            pn_error = stubs "Pathname"
+            pn_error.stubs(:realpath).raises(Errno::ENOENT)
+            pn_error.stubs(:dirname).returns('/mnt/symlink')
+            pn_error.stubs(:basename).returns('nonexistant')
+
+            # /mnt/symlink
+            pn_symlink = stubs "Pathname"
+            pn_symlink.stubs(:realpath).returns('/mnt/nfs/dest')
+
+            
Pathname.expects(:new).with('/mnt/symlink/nonexistant').returns(pn_error)
+            Pathname.expects(:new).with('/mnt/symlink').returns(pn_symlink)
+
+            realpath('/mnt/symlink/nonexistant').should == 
'/mnt/nfs/dest/nonexistant'
+        end
     end
 
     describe "get_selinux_current_context" do
-- 
1.6.3.3

--

You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.


Reply via email to