From f21162bdbae516d2613052d35a2f8bbd34d0bf86 Mon Sep 17 00:00:00 2001 From: Ian Ward Comfort Date: Thu, 17 Feb 2011 17:23:29 -0800 Subject: (#6368) Make the File type autorequire its nearest ancestor directory The File type will now autorequire the nearest ancestor directory found in the catalog, not just the file's parent directory. This is useful for setting up transitive relationships in cases when a package or other resource creates a large directory hierarchy, e.g. package { 'foo': ensure => present } file { '/var/lib/foo': require => Package['foo'] } This will make File resources at arbitrarily deep levels under /var/lib/foo automatically (transitively) require the foo package. Only the nearest ancestor is autorequired, to prevent explosion of the relationship graph. --- lib/puppet/type/file.rb | 10 ++++++-- spec/unit/type/file_spec.rb | 57 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb index 963b9e5dd..da093921b 100644 --- a/lib/puppet/type/file.rb +++ b/lib/puppet/type/file.rb @@ -244,11 +244,17 @@ Puppet::Type.newtype(:file) do newvalues(:first, :all) end - # Autorequire any parent directories. + # Autorequire the nearest ancestor directory found in the catalog. autorequire(:file) do basedir = File.dirname(self[:path]) if basedir != self[:path] - basedir + parents = [] + until basedir == parents.last + parents << basedir + basedir = File.dirname(basedir) + end + # The filename of the first ancestor found, or nil + parents.find { |dir| catalog.resource(:file, dir) } else nil end diff --git a/spec/unit/type/file_spec.rb b/spec/unit/type/file_spec.rb index 539782fd4..223873fe3 100755 --- a/spec/unit/type/file_spec.rb +++ b/spec/unit/type/file_spec.rb @@ -169,6 +169,25 @@ describe Puppet::Type.type(:file) do reqs[0].target.must == file end + it "should autorequire its nearest ancestor directory" do + file = Puppet::Type::File.new(:path => "/foo/bar/baz") + dir = Puppet::Type::File.new(:path => "/foo") + root = Puppet::Type::File.new(:path => "/") + @catalog.add_resource file + @catalog.add_resource dir + @catalog.add_resource root + reqs = file.autorequire + reqs.length.must == 1 + reqs[0].source.must == dir + reqs[0].target.must == file + end + + it "should not autorequire anything when there is no nearest ancestor directory" do + file = Puppet::Type::File.new(:path => "/foo/bar/baz") + @catalog.add_resource file + file.autorequire.should be_empty + end + it "should not autorequire its parent dir if its parent dir is itself" do file = Puppet::Type::File.new(:path => "/") @catalog.add_resource file @@ -242,6 +261,25 @@ describe Puppet::Type.type(:file) do reqs[0].target.must == file end + it "should autorequire its nearest ancestor directory" do + file = Puppet::Type::File.new(:path => "X:/foo/bar/baz") + dir = Puppet::Type::File.new(:path => "X:/foo") + root = Puppet::Type::File.new(:path => "X:/") + @catalog.add_resource file + @catalog.add_resource dir + @catalog.add_resource root + reqs = file.autorequire + reqs.length.must == 1 + reqs[0].source.must == dir + reqs[0].target.must == file + end + + it "should not autorequire anything when there is no nearest ancestor directory" do + file = Puppet::Type::File.new(:path => "X:/foo/bar/baz") + @catalog.add_resource file + file.autorequire.should be_empty + end + it "should not autorequire its parent dir if its parent dir is itself" do file = Puppet::Type::File.new(:path => "X:/") @catalog.add_resource file @@ -303,6 +341,25 @@ describe Puppet::Type.type(:file) do reqs[0].target.must == file end + it "should autorequire its nearest ancestor directory" do + file = Puppet::Type::File.new(:path => "//server/foo/bar/baz/qux") + dir = Puppet::Type::File.new(:path => "//server/foo/bar") + root = Puppet::Type::File.new(:path => "//server/foo") + @catalog.add_resource file + @catalog.add_resource dir + @catalog.add_resource root + reqs = file.autorequire + reqs.length.must == 1 + reqs[0].source.must == dir + reqs[0].target.must == file + end + + it "should not autorequire anything when there is no nearest ancestor directory" do + file = Puppet::Type::File.new(:path => "//server/foo/bar/baz/qux") + @catalog.add_resource file + file.autorequire.should be_empty + end + it "should not autorequire its parent dir if its parent dir is itself" do file = Puppet::Type::File.new(:path => "//server/foo") @catalog.add_resource file -- cgit