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.

Reply via email to