Jira (PUP-9075) File type "replace => false" doesn't allow to remove the file if "ensure => absent"

13 views
Skip to first unread message

Vincent Lours (JIRA)

unread,
Aug 20, 2018, 10:56:05 PM8/20/18
to puppe...@googlegroups.com
Vincent Lours created an issue
 
Puppet / Bug PUP-9075
File type "replace => false" doesn't allow to remove the file if "ensure => absent"
Issue Type: Bug Bug
Affects Versions: PUP 5.5.3
Assignee: Unassigned
Components: Catalog Application
Created: 2018/08/20 7:55 PM
Priority: Normal Normal
Reporter: Vincent Lours
Original Estimate: 4 hours
Remaining Estimate: 4 hours

Puppet Version: 5.5.4
Puppet Server Version: PE-2018.1.3.1
OS Name/Version: Centos 7.5

You can manage files in puppet with the option "replace => false". Which allow you to not change the content.
However, if you decide to remove this file later, by only changing the ensure value, the file will not be removed.

How to reproduce:
From a Centos docker image, I've created a simple manifest

  • to create a file with "replace => false"
  • apply the manifest
  • change the content to check that the replace is working
  • apply the manifest, with no change
  • Set the file to be 'absent'
  • apply the manifest, file was not removed
  • Set 'replace => true' in the manifest
  • apply the manifest, the file was removed

Desired Behavior:
From my perspective any files set to "ensure => absent" should be removed, even if the option replace has been set to false.
The "ensure" option should take over the "replace" option, as "ensure" is about the presence of the file and the "replace" option is about the content of the file.

Actual Behavior:
It looks like the "replace" option is taking over the "ensure" option.

Test in a Centos Docker container

sh-4.2# pwd
/git
sh-4.2# cat replace_test/manifests/init.pp
class replace_test (
  String $file_ensure = 'file'
){
 
  file { '/tmp/puppet_test':
    ensure  => $file_ensure,
    content => 'this is a test',
    replace => false,
  }
}
sh-4.2# /opt/puppetlabs/bin/puppet apply --modulepath=/git/ -e "include replace_test"
Notice: Compiled catalog for c8f7f3fc1f75 in environment production in 0.11 seconds
Notice: /Stage[main]/Replace_test/File[/tmp/puppet_test]/ensure: defined content as '{md5}54b0c58c7ce9f2a8b551351102ee0938'
Notice: Applied catalog in 0.05 seconds
sh-4.2# cat /tmp/puppet_test
this is a testsh-4.2# date > /tmp/puppet_test
sh-4.2# cat /tmp/puppet_test
Tue Aug 21 02:46:35 UTC 2018
sh-4.2# /opt/puppetlabs/bin/puppet apply --modulepath=/git/ -e "include replace_test"
Notice: Compiled catalog for c8f7f3fc1f75 in environment production in 0.11 seconds
Notice: Applied catalog in 0.04 seconds
sh-4.2# vi replace_test/manifests/init.pp
sh-4.2# cat replace_test/manifests/init.pp
class replace_test (
  String $file_ensure = 'absent'
){
 
  file { '/tmp/puppet_test':
    ensure  => $file_ensure,
    content => 'this is a test',
    replace => false,
  }
}
sh-4.2# /opt/puppetlabs/bin/puppet apply --modulepath=/git/ -e "include replace_test"
Notice: Compiled catalog for c8f7f3fc1f75 in environment production in 0.11 seconds
Notice: Applied catalog in 0.04 seconds
sh-4.2# vi replace_test/manifests/init.pp
sh-4.2# cat replace_test/manifests/init.pp
class replace_test (
  String $file_ensure = 'absent'
){
 
  file { '/tmp/puppet_test':
    ensure  => $file_ensure,
    content => 'this is a test',
    replace => true,
  }
}
sh-4.2# /opt/puppetlabs/bin/puppet apply --modulepath=/git/ -e "include replace_test"
Notice: Compiled catalog for c8f7f3fc1f75 in environment production in 0.11 seconds
Notice: /Stage[main]/Replace_test/File[/tmp/puppet_test]/ensure: removed
Notice: Applied catalog in 0.10 seconds

Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v7.7.1#77002-sha1:e75ca93)
Atlassian logo

Eric Sorenson (JIRA)

unread,
Sep 10, 2018, 5:22:03 PM9/10/18
to puppe...@googlegroups.com
Eric Sorenson commented on Bug PUP-9075
 
Re: File type "replace => false" doesn't allow to remove the file if "ensure => absent"

I think this is happening because of this check in lib/puppet/type/file/ensure.rb

    # We have to treat :present specially, because it works with any
    # type of file.
    def insync?(currentvalue)
      unless currentvalue == :absent or resource.replace?
        return true
      end
 
      if self.should == :present
        return !(currentvalue.nil? or currentvalue == :absent)
      else
        return super(currentvalue)
      end
    end

I am reluctant to change this because it has behaved liked this since at least 2011 and there have been no other reports of a problem. So maybe there are other people who rely on the current behaviour and would experience a breaking change. Can you just remove your replace parameter when it's time to delete the files?

Eric Sorenson (JIRA)

unread,
Sep 10, 2018, 5:22:04 PM9/10/18
to puppe...@googlegroups.com

Vincent Lours (JIRA)

unread,
Sep 17, 2018, 1:56:04 AM9/17/18
to puppe...@googlegroups.com

Vincent Lours (JIRA)

unread,
Sep 17, 2018, 1:56:04 AM9/17/18
to puppe...@googlegroups.com
Vincent Lours commented on Bug PUP-9075
 
Re: File type "replace => false" doesn't allow to remove the file if "ensure => absent"

Hi Eric Sorenson,

Thanks for your answer, and I can understand why you don't want to change it.

However I cannot imagine what should be the "normal" behaviour expected by people who set a file 'absent', other than to get it removed.
I'm pretty sure that nobody already noticed that the file was not removed after changing the ensure status of this kind of "file" in the hiera config.

From my point of view the true behaviour should be to remove it, no matter what.

Furthermore, I cannot imagine to remove the "replace" from my manifest, as the file ensure can be different depending of the server type.

Vincent Lours (JIRA)

unread,
Sep 20, 2018, 7:18:05 PM9/20/18
to puppe...@googlegroups.com

Josh Cooper (JIRA)

unread,
Oct 1, 2019, 6:58:03 PM10/1/19
to puppe...@googlegroups.com
Josh Cooper commented on Bug PUP-9075
 
Re: File type "replace => false" doesn't allow to remove the file if "ensure => absent"

The original behavior comes from https://projects.puppetlabs.com/issues/1750:

If I have a File with ensure=>link and replace=>false, and it already exists as a directory, puppet correctly does not change the directory, but also logs an error about not being able to remove the existing directory.

The behavior of ensure => absent in combination with replace => false is unspecified in documentation.

However, to Eric Sorenson's point, someone is probably relying on the current behavior of never deleting (in addition to modifying) an existing file/link/directory when replace is false.

Josh Cooper (Jira)

unread,
Jun 14, 2021, 4:09:03 PM6/14/21
to puppe...@googlegroups.com
Josh Cooper commented on Bug PUP-9075

Based on the comments above, I'm to close this as won't fix.

This message was sent by Atlassian Jira (v8.13.2#813002-sha1:c495a97)
Atlassian logo
Reply all
Reply to author
Forward
0 new messages