summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG5
-rwxr-xr-xlib/puppet/network/handler/fileserver.rb65
-rwxr-xr-xlib/puppet/type/pfile/checksum.rb24
-rwxr-xr-xlib/puppet/util/loadedfile.rb4
-rwxr-xr-xtest/network/handler/fileserver.rb2
-rwxr-xr-xtest/ral/types/file.rb1
-rwxr-xr-xtest/ral/types/filesources.rb1
-rwxr-xr-xtest/util/loadedfile.rb16
8 files changed, 89 insertions, 29 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 963772850..68cb87256 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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$