Jira (PUP-7941) Autogenerated custom types never get all properties set

2 views
Skip to first unread message

Reinhard Vicinus (JIRA)

unread,
Sep 12, 2017, 3:58:03 AM9/12/17
to puppe...@googlegroups.com
Reinhard Vicinus created an issue
 
Puppet / Bug PUP-7941
Autogenerated custom types never get all properties set
Issue Type: Bug Bug
Affects Versions: PUP 4.10.7
Assignee: Unassigned
Created: 2017/09/12 12:57 AM
Priority: Minor Minor
Reporter: Reinhard Vicinus

Don't know if I missed something, but as far as I can tell via prefetch autogenerated resources of custom types never get all properties set.

Here is a simple example:

test/lib/puppet/type/touchfile.rb

Puppet::Type.newtype(:touchfile) do
 
  ensurable do
    defaultvalues
    defaultto :present
  end
 
  newparam(:name) do
    isnamevar
  end
 
  newproperty(:data) do
  end
 
  validate do
    Puppet.warning("validate name: #{self[:name]} ensure: #{self[:ensure]} data: #{self[:data]}")
    if self[:ensure] == :present and self[:data].nil?
      warning('data must be set if ensure is present')
    end
  end
end

test/lib/puppet/provider/touchfile/default.rb

Puppet::Type.type(:touchfile).provide(:default) do
 
  commands :touch => 'touch', :rm => 'rm'
  def self.instances
    Dir["/tmp/*.txt"].collect do |filename|
      n = filename.gsub(/^\/tmp\/(.*)\.txt$/, '\1')
      new(
        :name => n,
        :ensure => :present,
        :data => 'default',
      )
    end
  end
 
  def self.prefetch(resources)
    instances.each do |prov|
      if tf = resources[prov.name]
        tf.provider = prov
      end
    end
  end
 
  def create
    touch(["/tmp/#{@resource[:name]}.txt"])
  end
 
  def destroy
    Puppet.warning("destroy name: #{@resource[:name]} ensure: #{@resource[:ensure]} data: #{@resource[:data]}")
    rm(["/tmp/#{@resource[:name]}.txt"])
  end
 
  def exists?
    File.exist?("/tmp/#{@resource[:name]}.txt")
  end
 
  mk_resource_methods
end

As is shown in the execution below the property "data" is never set to the value 'default':

touch /tmp/a.txt; puppet apply --modulepath=/data/modules -e 'resources { "touchfile": purge => true }'
Notice: Compiled catalog for test.example.com in environment production in 0.13 seconds
Warning: validate name: a ensure: present data: 
Warning: /Touchfile[a]: data must be set if ensure is present
Warning: destroy name: a ensure: absent data: 
Notice: /Stage[main]/Main/Touchfile[a]/ensure: removed
Notice: Applied catalog in 0.32 seconds

Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v6.4.14#64029-sha1:ae256fe)
Atlassian logo

Adrien Thebo (JIRA)

unread,
Sep 18, 2017, 5:23:02 PM9/18/17
to puppe...@googlegroups.com

Josh Cooper (Jira)

unread,
Dec 2, 2021, 1:50:01 AM12/2/21
to puppe...@googlegroups.com
Josh Cooper commented on Bug PUP-7941
 
Re: Autogenerated custom types never get all properties set

Thanks for the excellent report Reinhard Vicinus. The issue is that prefetch creates instances of Puppet::Type::Touchfile::ProviderDefault and sets the properties on it:

(byebug) var instance instance
@property_hash = {:name=>"a", :ensure=>:present, :data=>"default"}
@resource = #<Puppet::Type::Touchfile:0x0000556666eb33c8 @parameters={:name=>#<Puppet::Type::Touchfile::ParameterName:0x0000556666e09e18 @resource=#<Puppet::...

And then we create an instance of Puppet::Type::Touchfile using only the name, provider and title https://github.com/puppetlabs/puppet/blob/bd47bdd08c0f6e32649052cde80cefea1f6250d2/lib/puppet/type.rb#L1199, and that triggers validation https://github.com/puppetlabs/puppet/blob/bd47bdd08c0f6e32649052cde80cefea1f6250d2/lib/puppet/type.rb#L2376

Then we metaprogram each attribute on the type, e.g. define Puppet::Type::Touchfile::Data.

So in other words, the Puppet::Type::Touchfile instances don't have all of the state that is normally set on them such as when the desired values are specified in a manifest which happens here https://github.com/puppetlabs/puppet/blob/bd47bdd08c0f6e32649052cde80cefea1f6250d2/lib/puppet/type.rb#L671.

I think the puppet resource touchfile hides this behavior, because it converts the Puppet::Type::Touchfile instance to Puppet::Resource: https://github.com/puppetlabs/puppet/blob/bd47bdd08c0f6e32649052cde80cefea1f6250d2/lib/puppet/indirector/resource/ral.rb#L17, which retrieves the "current" values from the provider.

I agree the behavior is confusing, but we're unlikely to change that anytime soon and am going to close this. Feel free to reopen if you'd like to take a pass at fixing this in a backwards compatible way.

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