Please review pull request #770: Marshal Cache catalog opened by (emilemorel)
Description:
Writing catalog in yaml format took too long. To improve that, now we can cache
the catalog in Marchal format.
- Opened: Mon May 14 07:47:33 UTC 2012
- Based on: puppetlabs:master (639f995c91289b3be9ca5347865247907c7dcb5c)
- Requested merge: emilemorel:marchal_catalog_cache (a46afd549b0565e7e00c3ed406a81d896e0c4705)
Diff follows:
diff --git a/lib/puppet/application/agent.rb b/lib/puppet/application/agent.rb
index b806e33..f11d7b5 100644
--- a/lib/puppet/application/agent.rb
+++ b/lib/puppet/application/agent.rb
@@ -458,7 +458,7 @@ def setup
# Override the default.
Puppet[:facts_terminus] = :facter
- Puppet::Resource::Catalog.indirection.cache_class = :yaml
+ Puppet::Resource::Catalog.indirection.cache_class = Puppet[:preferred_cache_format]
unless options[:fingerprint]
setup_agent
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index fae41d9..f1db660 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -1035,6 +1035,7 @@ module Puppet
can be guaranteed to support this format, but it will be used for all
classes that support it.",
},
+ :preferred_cache_format => ["yaml", "The preferred format for writing catalog on agent"],
:agent_pidfile => {
:default => "$statedir/agent.pid",
:type => :file,
diff --git a/lib/puppet/indirector/catalog/marshal.rb b/lib/puppet/indirector/catalog/marshal.rb
new file mode 100644
index 0000000..79ca6e5
--- /dev/null
+++ b/lib/puppet/indirector/catalog/marshal.rb
@@ -0,0 +1,22 @@
+require 'puppet/resource/catalog'
+require 'puppet/indirector/marshal'
+
+class Puppet::Resource::Catalog::Marshal < Puppet::Indirector::Marshal
+ desc "Store catalogs as flat files, serialized using Marshal."
+
+ private
+
+ # Override these, because yaml doesn't want to convert our self-referential
+ # objects. This is hackish, but eh.
+ def from_marshal(text)
+ if config = Marshal.load(text)
+ return config
+ end
+ end
+
+ def to_marshal(config)
+ # We can't yaml-dump classes.
+ #config.edgelist_class = nil
+ Marshal.dump(config)
+ end
+end
diff --git a/lib/puppet/indirector/marshal.rb b/lib/puppet/indirector/marshal.rb
new file mode 100644
index 0000000..7f66122
--- /dev/null
+++ b/lib/puppet/indirector/marshal.rb
@@ -0,0 +1,75 @@
+require 'puppet/indirector/terminus'
+require 'puppet/util/file_locking'
+
+# The base class for MARSHAL indirection termini.
+class Puppet::Indirector::Marshal < Puppet::Indirector::Terminus
+ include Puppet::Util::FileLocking
+
+ # Read a given name's file in and convert it from YAML.
+ def find(request)
+ file = path(request.key)
+ return nil unless FileTest.exist?(file)
+
+ marshal = nil
+ begin
+ file = File.open(file, 'r')
+ rescue => detail
+ raise Puppet::Error, "Could not read MARSHAL data for #{indirection.name} #{request.key}: #{detail}"
+ end
+ begin
+ marshal = from_marshal(file.read)
+ file.close
+ return marshal
+ rescue => detail
+ raise Puppet::Error, "Could not parse MARSHAL data for #{indirection.name} #{request.key}: #{detail}"
+ end
+ end
+
+ # Convert our object to MARSHAL and store it to the disk.
+ def save(request)
+ raise ArgumentError.new("You can only save objects that respond to :name") unless request.instance.respond_to?(:name)
+ file = path(request.key)
+
+ basedir = File.dirname(file)
+
+ # This is quite likely a bad idea, since we're not managing ownership or modes.
+ Dir.mkdir(basedir) unless FileTest.exist?(basedir)
+
+ begin
+ file = File.new(file,'w')
+ file.write to_marshal(request.instance)
+ file.close
+ rescue TypeError => detail
+ Puppet.err "Could not save #{self.name} #{request.key}: #{detail}"
+ end
+ end
+
+ # Return the path to a given node's file.
+ def path(name,ext='.marshal')
+ if name =~ Puppet::Indirector::BadNameRegexp then
+ Puppet.crit("directory traversal detected in #{self.class}: #{name.inspect}")
+ raise ArgumentError, "invalid key"
+ end
+
+ base = Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir]
+ File.join(base, self.class.indirection_name.to_s, name.to_s + ext)
+ end
+
+ def search(request)
+ Dir.glob(path(request.key,'')).collect do |file|
+ file_load = File.open(file, 'r')
+ from_marshal(file.read)
+ file.close
+ end
+ end
+
+ private
+
+ def from_marshal(text)
+ Marshal.load(text)
+ end
+
+ def to_marshal(object)
+ Marshal.dump(object)
+ end
+end
-- 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.
