module Puppet Puppet.type(:file).newproperty(:target) do desc "The target for creating a link. Currently, symlinks are the only type supported." newvalue(:notlink) do # We do nothing if the value is absent return :nochange end # Anything else, basically newvalue(/./) do if ! @resource.should(:ensure) @resource[:ensure] = :link end # Only call mklink if ensure() didn't call us in the first place. currentensure = @resource.property(:ensure).retrieve if @resource.property(:ensure).insync?(currentensure) mklink() end end # Create our link. def mklink target = self.should # Clean up any existing objects. The argument is just for logging, # it doesn't determine what's removed. @resource.remove_existing(target) if FileTest.exists?(@resource[:path]) raise Puppet::Error, "Could not remove existing file" end Dir.chdir(File.dirname(@resource[:path])) do Puppet::Util::SUIDManager.asuser(@resource.asuser()) do mode = @resource.should(:mode) if mode Puppet::Util.withumask(000) do File.symlink(target, @resource[:path]) end else File.symlink(target, @resource[:path]) end end @resource.send(:property_fix) :link_created end end def insync?(currentvalue) if [:nochange, :notlink].include?(self.should) or @resource.recurse? return true else return super(currentvalue) end end def retrieve if stat = @resource.stat if stat.ftype == "link" return File.readlink(@resource[:path]) else return :notlink end else return :absent end end end end