diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/type/pfile.rb | 64 | ||||
-rwxr-xr-x | lib/puppet/type/pfile/ensure.rb | 89 | ||||
-rw-r--r-- | lib/puppet/type/state.rb | 4 | ||||
-rwxr-xr-x | lib/puppet/type/symlink.rb | 4 | ||||
-rwxr-xr-x | lib/puppet/type/user.rb | 42 |
5 files changed, 155 insertions, 48 deletions
diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/pfile.rb index d23be0fca..d77da1942 100644 --- a/lib/puppet/type/pfile.rb +++ b/lib/puppet/type/pfile.rb @@ -218,8 +218,8 @@ module Puppet return children unless self[:ignore] self[:ignore].each { |ignore| ignored = [] - Dir.glob(File.join(self[:path],ignore), File::FNM_DOTMATCH) { |match| - ignored.push(File.basename(match)) + Dir.glob(File.join(self[:path],ignore), File::FNM_DOTMATCH) { + |match| ignored.push(File.basename(match)) } children = children - ignored } @@ -229,7 +229,6 @@ module Puppet def initialize(hash) # clean out as many references to any file paths as possible # this was the source of many, many bugs - @arghash = self.argclean(hash) @arghash.delete(self.class.namevar) @@ -409,11 +408,70 @@ module Puppet end self.localrecurse(recurse) + if @states.include?(:ensure) and @states[:ensure].should =~ /^#{File::SEPARATOR}/ + self.linkrecurse(recurse) + end if @states.include?(:source) self.sourcerecurse(recurse) end end + # Build a recursive map of a link source + def linkrecurse(recurse) + target = @states[:ensure].should + + method = :lstat + if self[:links] == :follow + method = :stat + end + + targetstat = nil + unless FileTest.exist?(target) + #self.info "%s does not exist; not recursing" % + # target + return + end + # Now stat our target + targetstat = File.send(method, target) + unless targetstat.ftype == "directory" + #self.info "%s is not a directory; not recursing" % + # target + return + end + + unless FileTest.readable? target + self.notice "Cannot manage %s: permission denied" % self.name + return + end + + children = Dir.entries(target).reject { |d| d =~ /^\.+$/ } + + #Get rid of ignored children + if @parameters.include?(:ignore) + children = handleignore(children) + end + + added = [] + children.each do |file| + longname = File.join(@states[:ensure].should, file) + + # Files know to create directories when recursion + # is enabled and we're making links + args = { + :recurse => recurse, + :ensure => longname + } + + if child = self.newchild(file, true, args) + unless @children.include?(child) + self.push child + added.push file + end + end + end + end + + # Build up a recursive map of what's around right now def localrecurse(recurse) unless FileTest.exist?(self[:path]) and self.stat.directory? #self.info "%s is not a directory; not recursing" % diff --git a/lib/puppet/type/pfile/ensure.rb b/lib/puppet/type/pfile/ensure.rb index 88dd20024..9f04202cb 100755 --- a/lib/puppet/type/pfile/ensure.rb +++ b/lib/puppet/type/pfile/ensure.rb @@ -3,11 +3,32 @@ module Puppet require 'etc' desc "Whether to create files that don't currently exist. Possible values are *absent*, *present* (equivalent to *file*), - **file**/*directory*. Specifying 'absent' will delete the file, + *file*, and *directory*. Specifying 'absent' will delete the file, although currently this will not recursively delete directories. + + Anything other than those values will be considered to be a symlink. + For instance, the following text creates a link:: + + # Useful on solaris + file { \"/etc/inetd.conf\": + ensure => \"/etc/inet/inetd.conf\" + } - This is the only element with an *ensure* state that does not have - a default value." + You can make relative links: + + # Useful on solaris + file { \"/etc/inetd.conf\": + ensure => \"inet/inetd.conf\" + } + + If you need to make a relative link to a file named the same + as one of the valid values, you must prefix it with ``./`` or + something similar. + + You can also make recursive symlinks, which will create a + directory structure that maps to the target directory, + with directories corresponding to each directory + and links corresponding to each file." # Most 'ensure' states have a default, but with files we, um, don't. nodefault @@ -52,6 +73,41 @@ module Puppet return :directory_created end + # Symlinks. We pretty much have to match just about anything, + # in order to match relative links. Somewhat ugly, but eh, it + # works. + newvalue(/./) do + Dir.chdir(File.dirname(@parent[:path])) do + target = self.should + unless FileTest.exists?(target) + self.debug "Not linking to non-existent '%s'" % target + nil # Grrr, can't return + else + if FileTest.directory?(target) and @parent[:recurse] + # If we're pointing to a directory and recursion is + # enabled, then make a directory instead of a link. + self.set_directory + else + Puppet::Util.asuser(@parent.asuser()) do + mode = @parent.should(:mode) + if mode + Puppet::Util.withumask(000) do + File.symlink(self.should, @parent[:path]) + end + else + File.symlink(self.should, @parent[:path]) + end + end + + # We can't use "return" here because we're in an anonymous + # block. + :link_created + end + end + end + end + + # Check that we can actually create anything def check basedir = File.dirname(@parent[:path]) @@ -68,7 +124,13 @@ module Puppet def retrieve if stat = @parent.stat(false) - @is = stat.ftype.intern + # If we're a link, set the 'is' value to the destination + # of the link + if stat.ftype == "link" + @is = File.readlink(@parent[:path]) + else + @is = stat.ftype.intern + end else if self.should == :false @is = :false @@ -76,26 +138,7 @@ module Puppet @is = :absent end end - - #self.debug "'exists' state is %s" % self.is end - - - # We can mostly rely on the superclass method, but we want other states - # to take precedence over 'ensure' if they are present. -# def sync -# # XXX This is a bad idea, because it almost guarantees bugs if we -# # introduce more states to manage content, but anything else is just -# # about as bad. -# event = nil -# #if state = @parent.state(:source) or state = @parent.state(:content) -# # event = state.sync -# #else -# event = super -# @parent.setchecksum -# #end -# return event -# end end end diff --git a/lib/puppet/type/state.rb b/lib/puppet/type/state.rb index 17a004056..05f876583 100644 --- a/lib/puppet/type/state.rb +++ b/lib/puppet/type/state.rb @@ -73,7 +73,9 @@ class State < Puppet::Parameter [value, self.class.name, detail] end elsif ary = self.class.match?(value) - event = ary[1].call(value) + # FIXME It'd be better here to define a method, so that + # the blocks could return values. + event = self.instance_eval(&ary[1]) else self.fail "%s is not a valid value for %s" % [value, self.class.name] diff --git a/lib/puppet/type/symlink.rb b/lib/puppet/type/symlink.rb index cb05c3a88..b00962b0e 100755 --- a/lib/puppet/type/symlink.rb +++ b/lib/puppet/type/symlink.rb @@ -122,10 +122,10 @@ module Puppet @stat = nil @target = @parent.state(:ensure).should - self.setparent() + self.setparent(@target) end - def setparent + def setparent(value) # we want to remove our state, because we're creating children # to do the links if FileTest.exist?(@target) diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb index ea80f7f0b..d6a75a4e5 100755 --- a/lib/puppet/type/user.rb +++ b/lib/puppet/type/user.rb @@ -19,6 +19,27 @@ module Puppet newstate(:ensure, @parentstate) do newvalue(:present) do + # Verify that they have provided everything necessary, if we + # are trying to manage the user + if @parent.managed? + @parent.class.states.each { |state| + next if stateobj = @parent.state(state.name) + next if state.name == :ensure + + unless state.autogen? or state.isoptional? + if state.method_defined?(:autogen) + @parent[state.name] = :auto + else + @parent.fail "Users require a value for %s" % + state.name + end + end + } + + #if @states.empty? + # @parent[:comment] = @parent[:name] + #end + end self.syncname(:present) end @@ -307,25 +328,8 @@ module Puppet @userinfo = nil super - # Verify that they have provided everything necessary, if we - # are trying to manage the user - if self.managed? - self.class.states.each { |state| - next if @states.include?(state.name) - next if state.name == :ensure - - unless state.autogen? or state.isoptional? - if state.method_defined?(:autogen) - self[state.name] = :auto - else - self.fail "Users require a value for %s" % state.name - end - end - } - - if @states.empty? - self[:comment] = self[:name] - end + unless defined? @states + raise "wtf?" end end |