diff options
-rw-r--r-- | CHANGELOG | 5 | ||||
-rwxr-xr-x | lib/puppet/network/handler/fileserver.rb | 65 | ||||
-rwxr-xr-x | lib/puppet/type/pfile/checksum.rb | 24 | ||||
-rwxr-xr-x | lib/puppet/util/loadedfile.rb | 4 | ||||
-rwxr-xr-x | test/network/handler/fileserver.rb | 2 | ||||
-rwxr-xr-x | test/ral/types/file.rb | 1 | ||||
-rwxr-xr-x | test/ral/types/filesources.rb | 1 | ||||
-rwxr-xr-x | test/util/loadedfile.rb | 16 |
8 files changed, 89 insertions, 29 deletions
@@ -1,3 +1,8 @@ + Modified the fileserver to cache file information, so that + each file isn't being read on every connection. Also, + added londo's patch from #678 to avoid reading entire files + into memory. + Fixed environment handling in the crontab provider (#669). Added patch by trombik in #572, supporting old-style diff --git a/lib/puppet/network/handler/fileserver.rb b/lib/puppet/network/handler/fileserver.rb index 051f6747b..a96481b66 100755 --- a/lib/puppet/network/handler/fileserver.rb +++ b/lib/puppet/network/handler/fileserver.rb @@ -3,6 +3,7 @@ require 'puppet/network/authstore' require 'webrick/httpstatus' require 'cgi' require 'delegate' +require 'sync' class Puppet::Network::Handler AuthStoreError = Puppet::AuthStoreError @@ -51,15 +52,10 @@ class Puppet::Network::Handler desc = [] CHECKPARAMS.each { |check| - if property = obj.property(check) - if currentvalues[property] - desc << currentvalues[property] - else - mount.debug "Manually retrieving info for %s" % check - desc << property.retrieve - end + if value = currentvalues[check] + desc << value else - if check == "checksum" and currentvalues[obj.property(:type)] == "file" + if check == "checksum" and currentvalues[:type] == "file" mount.notice "File %s does not have data for %s" % [obj.name, check] end @@ -427,6 +423,10 @@ class Puppet::Network::Handler class Mount < Puppet::Network::AuthStore attr_reader :name + @@syncs = {} + + @@files = {} + Puppet::Util.logmethods(self, true) def getfileobject(dir, links) @@ -441,17 +441,44 @@ class Puppet::Network::Handler # Run 'retrieve' on a file. This gets the actual parameters, so # we can pass them to the client. def check(obj) - # FIXME we should really have a timeout here -- we don't - # want to actually check on every connection, maybe no more - # than every 60 seconds or something. It'd be nice if we - # could use the builtin scheduling to do this. - # Retrieval is enough here, because we don't want to cache # any information in the state file, and we don't want to generate # any state changes or anything. We don't even need to sync # the checksum, because we're always going to hit the disk # directly. - return obj.retrieve + + # We're now caching file data, using the LoadedFile to check the + # disk no more frequently than the :filetimeout. + path = obj[:path] + sync = sync(path) + unless data = @@files[path] + data = {} + sync.synchronize(Sync::EX) do + @@files[path] = data + data[:loaded_obj] = Puppet::Util::LoadedFile.new(path) + Puppet.notice "Initializing values for %s" % path + data[:values] = properties(obj) + return data[:values] + end + end + + changed = nil + sync.synchronize(Sync::SH) do + changed = data[:loaded_obj].changed? + end + + if changed + sync.synchronize(Sync::EX) do + Puppet.notice "Getting values for %s" % path + data[:values] = properties(obj) + return data[:values] + end + else + sync.synchronize(Sync::SH) do + Puppet.info "Using cached values for %s" % path + return data[:values] + end + end end # Create a map for a specific client. @@ -583,6 +610,11 @@ class Puppet::Network::Handler @path = path end + # Return the current values for the object. + def properties(obj) + obj.retrieve.inject({}) { |props, ary| props[ary[0].name] = ary[1]; props } + end + # Retrieve a specific directory relative to a mount point. # If they pass in a client, then expand as necessary. def subdir(dir = nil, client = nil) @@ -597,6 +629,11 @@ class Puppet::Network::Handler dirname end + def sync(path) + @@syncs[path] ||= Sync.new + @@syncs[path] + end + def to_s "mount[#{@name}]" end diff --git a/lib/puppet/type/pfile/checksum.rb b/lib/puppet/type/pfile/checksum.rb index 6caef23ca..b5e6ab940 100755 --- a/lib/puppet/type/pfile/checksum.rb +++ b/lib/puppet/type/pfile/checksum.rb @@ -165,21 +165,15 @@ module Puppet else begin File.open(@resource[:path]) { |file| - text = nil - case checktype - when :md5 - text = file.read - when :md5lite - text = file.read(512) - end - - if text.nil? - self.debug "Not checksumming empty file %s" % - @resource[:path] - sum = 0 - else - sum = Digest::MD5.hexdigest(text) - end + hashfunc = Digest::MD5.new + while (!file.eof) + readBuf = file.read(512) + hashfunc.update(readBuf) + if checktype == :md5lite then + break + end + end + sum = hashfunc.hexdigest } rescue Errno::EACCES => detail self.notice "Cannot checksum %s: permission denied" % diff --git a/lib/puppet/util/loadedfile.rb b/lib/puppet/util/loadedfile.rb index ceb53bca4..32a832d0f 100755 --- a/lib/puppet/util/loadedfile.rb +++ b/lib/puppet/util/loadedfile.rb @@ -15,6 +15,10 @@ module Puppet # Determine whether the file has changed and thus whether it should # be reparsed. def changed? + # Allow the timeout to be disabled entirely. + if Puppet[:filetimeout] < 0 + return true + end tmp = stamp() # We use a different internal variable than the stamp method diff --git a/test/network/handler/fileserver.rb b/test/network/handler/fileserver.rb index 339c96bde..b81262947 100755 --- a/test/network/handler/fileserver.rb +++ b/test/network/handler/fileserver.rb @@ -702,6 +702,8 @@ class TestFileServer < Test::Unit::TestCase end def test_servinglinks + # Disable the checking, so changes propagate immediately. + Puppet[:filetimeout] = -5 server = nil source = tempfile() file = File.join(source, "file") diff --git a/test/ral/types/file.rb b/test/ral/types/file.rb index 2dcfb17ec..f3e1a562d 100755 --- a/test/ral/types/file.rb +++ b/test/ral/types/file.rb @@ -31,6 +31,7 @@ class TestFile < Test::Unit::TestCase super @file = Puppet::Type.type(:file) $method = @method_name + Puppet[:filetimeout] = -1 end def teardown diff --git a/test/ral/types/filesources.rb b/test/ral/types/filesources.rb index fed5e3f2a..7c8e65d82 100755 --- a/test/ral/types/filesources.rb +++ b/test/ral/types/filesources.rb @@ -16,6 +16,7 @@ class TestFileSources < Test::Unit::TestCase @port = 12345 end @file = Puppet::Type.type(:file) + Puppet[:filetimeout] = -1 end def use_storage diff --git a/test/util/loadedfile.rb b/test/util/loadedfile.rb index 2c6b241fb..f7f9f6e23 100755 --- a/test/util/loadedfile.rb +++ b/test/util/loadedfile.rb @@ -101,6 +101,22 @@ class TestLoadedFile < Test::Unit::TestCase assert(obj.changed?, "File was not considered changed when missing") } end + + # Make sure negative values always result in change notifications. + def test_negative_always_changes + file = tempfile() + File.open(file, "w") { |f| f.puts "" } + obj = nil + assert_nothing_raised { + obj = Puppet::Util::LoadedFile.new(file) + } + + assert(! obj.changed?, "file with no change considered changed") + # Now set a negative value + Puppet[:filetimeout] = -1 + + assert(obj.changed?, "negative file timeout did not disable checking") + end end # $Id$ |