puppetlabs/puppet — pull request #864 by stschulte (2012-06-17 23:44:34+00:00)
Title: #14531 Fix default ensure value for symlinks

As mentioned in bugreport #14531 specifying `target` without `ensure` of a file resource can lead to unexpected results. Sample:

file { '/tmp/a':
target => '/tmp/b',
}

Running puppet on that manifest will *always* print the following

File[/tmp/a]/ensure: created

while in fact the link was not created. Even worse: If `/tmp/a` *does* already exist, puppet will just *remove* the link, still saying it created something.

Reading `type/file.rb` puppet should create the link even if ensure is not specified:

# If they've specified a source, we get our 'should' values
# from it.
unless self[:ensure]
if self[:target]
self[:ensure] = :symlink
elsif self[:content]
self[:ensure] = :file
end
end

@stat = :needs_stat

The problem here is: If ensure is omitted, puppet will set the should value to `:symlink` in the initialize method but the ensure property itself uses the symbol `:link` to identify a link. So puppet will always treat the above resource as out in sync. In order to fix the resource puppet will now call `sync` on the ensure property which will remove `/tmp/a` first (method `remove_existing` but the block passed to `newvalue(:link)` is never executed. Because there is no `newvalue(:symlink)` block, puppet will run the block in `newvalue(/./)` which does nothing at all.

As a result puppet will *always* say it created something while in fact making sure that the resource is *removed*.

Change the default ensure value from :symlink to :link if target is
set.