Because of ruby bug:
http://rubyforge.org/tracker/?group_id=426&atid=1698&func=detail&aid=8886
and
http://redmine.ruby-lang.org/issues/show/1331

YAML dump of hashes using ruby objects as keys is incorrect leading
to an error when deserializing the YAML in puppetd.

The error is easy to correct by a post-process fix-up of
the generated YAML, which transforms:
&id004 !ruby/object:Puppet::Relationship ?

to the correct:
? &id004 !ruby/object:Puppet::Relationship

Signed-off-by: Brice Figureau <[email protected]>
---
 lib/puppet/network/formats.rb  |   17 +++++++++++++++--
 lib/puppet/resource/catalog.rb |   14 --------------
 lib/puppet/simple_graph.rb     |   14 --------------
 spec/unit/network/formats.rb   |   21 +++++++++++++++++++++
 spec/unit/resource/catalog.rb  |    4 ----
 5 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/lib/puppet/network/formats.rb b/lib/puppet/network/formats.rb
index 85e8ce6..51354b0 100644
--- a/lib/puppet/network/formats.rb
+++ b/lib/puppet/network/formats.rb
@@ -12,18 +12,31 @@ Puppet::Network::FormatHandler.create(:yaml, :mime => 
"text/yaml") do
     end
 
     def render(instance)
-        instance.to_yaml
+        yaml = instance.to_yaml
+
+        yaml = fixup(yaml) unless yaml.nil?
+        yaml
     end
 
     # Yaml monkey-patches Array, so this works.
     def render_multiple(instances)
-        instances.to_yaml
+        yaml = instances.to_yaml
+
+        yaml = fixup(yaml) unless yaml.nil?
+        yaml
     end
 
     # Everything's supported
     def supported?(klass)
         true
     end
+
+    # fixup invalid yaml as per:
+    # http://redmine.ruby-lang.org/issues/show/1331
+    def fixup(yaml)
+        yaml.gsub!(/((?:&id\d+\s+)?!ruby\/object:.*?)\s*\?/) { "? #{$1}" }
+        yaml
+    end
 end
 
 
diff --git a/lib/puppet/resource/catalog.rb b/lib/puppet/resource/catalog.rb
index 32fbc38..4f60f6e 100644
--- a/lib/puppet/resource/catalog.rb
+++ b/lib/puppet/resource/catalog.rb
@@ -417,20 +417,6 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph
         super
     end
 
-    def to_yaml_properties
-        result = instance_variables
-
-        # There's a ruby bug that hits us without this:
-        # 
http://rubyforge.org/tracker/?group_id=426&atid=1698&func=detail&aid=8886
-        # We need our resources to show up in as values in a hash
-        # before they show up as keys, because otherwise
-        # the loading fails.
-        result.delete "@resource_table"
-        result.unshift "@resource_table"
-
-        result
-    end
-
     private
 
     def cleanup
diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb
index c5b0f49..5d6f729 100644
--- a/lib/puppet/simple_graph.rb
+++ b/lib/puppet/simple_graph.rb
@@ -360,20 +360,6 @@ class Puppet::SimpleGraph
         end
     end
 
-    def to_yaml_properties
-        result = instance_variables
-
-        # There's a ruby bug that hits us without this:
-        # 
http://rubyforge.org/tracker/?group_id=426&atid=1698&func=detail&aid=8886
-        # We need our resources to show up in as values in a hash
-        # before they show up as keys, because otherwise
-        # the loading fails.
-        result.delete "@edges"
-        result.unshift "@edges"
-
-        result
-    end
-
     # Just walk the tree and pass each edge.
     def walk(source, direction)
         # Use an iterative, breadth-first traversal of the graph. One could do
diff --git a/spec/unit/network/formats.rb b/spec/unit/network/formats.rb
index 0e21fef..b472cbf 100755
--- a/spec/unit/network/formats.rb
+++ b/spec/unit/network/formats.rb
@@ -28,12 +28,29 @@ describe "Puppet Network Format" do
             @yaml.render(instance).should == "foo"
         end
 
+        it "should fixup generated yaml on render" do
+            instance = mock 'instance', :to_yaml => "foo"
+
+            @yaml.expects(:fixup).with("foo").returns "bar"
+
+            @yaml.render(instance).should == "bar"
+        end
+
         it "should render multiple instances by calling 'to_yaml' on the 
array" do
             instances = [mock('instance')]
             instances.expects(:to_yaml).returns "foo"
             @yaml.render_multiple(instances).should == "foo"
         end
 
+        it "should fixup generated yaml on render" do
+            instances = [mock('instance')]
+            instances.stubs(:to_yaml).returns "foo"
+
+            @yaml.expects(:fixup).with("foo").returns "bar"
+
+            @yaml.render(instances).should == "bar"
+        end
+
         it "should intern by calling 'YAML.load'" do
             text = "foo"
             YAML.expects(:load).with("foo").returns "bar"
@@ -45,6 +62,10 @@ describe "Puppet Network Format" do
             YAML.expects(:load).with("foo").returns "bar"
             @yaml.intern_multiple(String, text).should == "bar"
         end
+
+        it "should fixup incorrect yaml to correct" do
+            @yaml.fixup("&id004 !ruby/object:Puppet::Relationship ?").should 
== "? &id004 !ruby/object:Puppet::Relationship"
+        end
     end
 
     it "should include a marshal format" do
diff --git a/spec/unit/resource/catalog.rb b/spec/unit/resource/catalog.rb
index d51f8fb..6a5922e 100755
--- a/spec/unit/resource/catalog.rb
+++ b/spec/unit/resource/catalog.rb
@@ -801,10 +801,6 @@ describe Puppet::Resource::Catalog, "when compiling" do
         it "should be able to be dumped to yaml" do
             YAML.dump(@catalog).should be_instance_of(String)
         end
-
-        it "should always have its resource table first in its yaml property 
list" do
-            @catalog.to_yaml_properties[0].should == "@resource_table"
-        end
     end
 
     describe "when converting from yaml" do
-- 
1.6.0.2


--~--~---------~--~----~------------~-------~--~----~
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