From: Michael Knox <[email protected]> Utilising Augeas's SAVE_NEWFILE mode (similar to augtool -n) to determine the changes that will be made be made by Augeas. Output a unified diff to info
handle non-default root, and multiple files correctly Adding tests for Augeas diff functionality Add test for non-default :root when diff'ing Ensure that multiple files are diffed if changed, not just one Signed-off-by: Mike Knox <[email protected]> --- Local-branch: feature/master/2728 lib/puppet/provider/augeas/augeas.rb | 54 +++++++++++++---- spec/unit/provider/augeas/augeas_spec.rb | 97 ++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 12 deletions(-) diff --git a/lib/puppet/provider/augeas/augeas.rb b/lib/puppet/provider/augeas/augeas.rb index a16f54b..643462e 100644 --- a/lib/puppet/provider/augeas/augeas.rb +++ b/lib/puppet/provider/augeas/augeas.rb @@ -15,9 +15,12 @@ require 'augeas' if Puppet.features.augeas? require 'strscan' +require 'puppet/util' +require 'puppet/util/diff' Puppet::Type.type(:augeas).provide(:augeas) do include Puppet::Util + include Puppet::Util::Diff confine :true => Puppet.features.augeas? @@ -25,6 +28,8 @@ Puppet::Type.type(:augeas).provide(:augeas) do SAVE_NOOP = "noop" SAVE_OVERWRITE = "overwrite" + SAVE_NEWFILE = "newfile" + SAVE_BACKUP = "backup" COMMANDS = { "set" => [ :path, :string ], @@ -287,20 +292,33 @@ Puppet::Type.type(:augeas).provide(:augeas) do # actually do the save. if return_value and get_augeas_version >= "0.3.6" debug("Will attempt to save and only run if files changed") - set_augeas_save_mode(SAVE_NOOP) + set_augeas_save_mode(SAVE_NEWFILE) do_execute_changes save_result = @aug.save saved_files = @aug.match("/augeas/events/saved") - if save_result and not files_changed? - debug("Skipping because no files were changed") - return_value = false - else + if save_result and files_changed? + root = resource[:root].sub(/^\/$/, "") + saved_files.each do |key| + saved_file = @aug.get(key).to_s.sub(/^\/files/, root) + if Puppet[:show_diff] + print diff(saved_file, saved_file + ".augnew") + end + if Puppet[:noop] + File.delete(saved_file + ".augnew") + end + end debug("Files changed, should execute") + return_value = true + else + debug("Skipping because no files were changed or save failed") + return_value = false end end end ensure - close_augeas + if not return_value or Puppet[:noop] + close_augeas + end end return_value end @@ -309,12 +327,24 @@ Puppet::Type.type(:augeas).provide(:augeas) do # Re-connect to augeas, and re-execute the changes begin open_augeas - set_augeas_save_mode(SAVE_OVERWRITE) if get_augeas_version >= "0.3.6" - - do_execute_changes - - success = @aug.save - fail("Save failed with return code #{success}") if success != true + saved_files = @aug.match("/augeas/events/saved") + if saved_files + saved_files.each do |key| + root = resource[:root].sub(/^\/$/, "") + saved_file = @aug.get(key).to_s.sub(/^\/files/, root) + if File.exists?(saved_file + ".augnew") + success = File.rename(saved_file + ".augnew", saved_file) + debug(saved_file + ".augnew moved to " + saved_file) + fail("Rename failed with return code #{success}") if success != 0 + end + end + else + debug("No saved files, re-executing augeas") + set_augeas_save_mode(SAVE_OVERWRITE) if get_augeas_version >= "0.3.6" + do_execute_changes + success = @aug.save + fail("Save failed with return code #{success}") if success != true + end ensure close_augeas end diff --git a/spec/unit/provider/augeas/augeas_spec.rb b/spec/unit/provider/augeas/augeas_spec.rb index 5bb98ea..aeeb196 100755 --- a/spec/unit/provider/augeas/augeas_spec.rb +++ b/spec/unit/provider/augeas/augeas_spec.rb @@ -249,6 +249,10 @@ describe provider_class do end describe "need to run" do + before do + File.stubs(:delete) + end + it "should handle no filters" do resource = stub("resource") resource.stubs(:[]).returns(false).then.returns("").then.returns("") @@ -339,6 +343,98 @@ describe provider_class do provider.stubs(:get_augeas_version).returns("0.3.5") provider.need_to_run?.should == false end + + # Ticket 2728 (diff files) + describe "and Puppet[:show_diff] is set" do + before do + Puppet[:show_diff] = true + end + + it "should call diff when a file is shown to have been changed" do + file = "/etc/hosts" + + resource = stub("resource") + resource.stubs(:[]).returns(false).then.returns("set /files/foo bar").then.returns("") + provider = provider_class.new(resource) + augeas_stub = stub("augeas") + augeas_stub.expects("set").with("/augeas/save", "newfile") + augeas_stub.expects("save").returns(true) + augeas_stub.expects("get").with("/augeas/events/saved").returns(["/files#{file}"]) + augeas_stub.stubs("match").with("/augeas/events/saved").returns(["/augeas/events/saved"]) + augeas_stub.stubs("close") + + provider.aug= augeas_stub + provider.stubs(:get_augeas_version).returns("0.7.2") + provider.expects(:diff).with("#{file}", "#{file}.augnew") + provider.need_to_run?.should == true + end + + it "should call diff for each file thats changed" do + file1 = "/etc/hosts" + file2 = "/etc/resolv.conf" + + resource = stub("resource") + resource.stubs(:[]).returns(false).then.returns(["set /files/foo bar", "set /files/bar foo"]).then.returns("") + provider = provider_class.new(resource) + augeas_stub = stub("augeas") + augeas_stub.expects("set").with("/augeas/save", "newfile") + augeas_stub.expects("save").returns(true) + augeas_stub.expects("get").with("/augeas/events/saved[1]").returns(["/files#{file1}"]) + augeas_stub.expects("get").with("/augeas/events/saved[2]").returns(["/files#{file2}"]) + augeas_stub.stubs("match").with("/augeas/events/saved").returns(["/augeas/events/saved[1]", "/augeas/events/saved[2]"]) + augeas_stub.stubs("close") + + provider.aug= augeas_stub + provider.stubs(:get_augeas_version).returns("0.7.2") + provider.expects(:diff).with("#{file1}", "#{file1}.augnew") + provider.expects(:diff).with("#{file2}", "#{file2}.augnew") + provider.need_to_run?.should == true + end + + describe "and resource[:root] is set" do + before do + end + + it "should call diff when a file is shown to have been changed" do + root = "/tmp/foo" + file = "/etc/hosts" + + resource = stub("resource") + resource.stubs(:root).returns("#{root}") + resource.stubs(:[]).returns(false).then.returns("set /files/foo bar").then.returns("") + provider = provider_class.new(resource) + augeas_stub = stub("augeas") + augeas_stub.expects("set").with("/augeas/save", "newfile") + augeas_stub.expects("save").returns(true) + augeas_stub.expects("get").with("/augeas/events/saved").returns(["/files#{root}#{file}"]) + augeas_stub.stubs("match").with("/augeas/events/saved").returns(["/augeas/events/saved"]) + augeas_stub.stubs("close") + + provider.aug= augeas_stub + provider.stubs(:get_augeas_version).returns("0.7.2") + provider.expects(:diff).with("#{root}#{file}", "#{root}#{file}.augnew") + provider.need_to_run?.should == true + end + end + end + + it "should not call diff if no files change" do + file = "/etc/hosts" + + resource = stub("resource") + resource.stubs(:[]).returns(false).then.returns("set /files/foo bar").then.returns("") + provider = provider_class.new(resource) + augeas_stub = stub("augeas") + augeas_stub.expects("set").with("/augeas/save", "newfile") + augeas_stub.expects("save").returns(true) + augeas_stub.stubs("match").with("/augeas/events/saved").returns([]) + augeas_stub.stubs("close") + + provider.aug= augeas_stub + provider.stubs(:get_augeas_version).returns("0.7.2") + provider.expects(:diff).never + provider.need_to_run?.should == false + end end describe "augeas execution integration" do @@ -349,6 +445,7 @@ describe provider_class do @augeas = stub("augeas") @provider.aug= @augeas @provider.stubs(:get_augeas_version).returns("0.3.5") + @augeas.stubs(:match).with("/augeas/events/saved") end it "should handle set commands" do -- 1.7.3.4 -- 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.
