Bug #6539

Inheritance of a parametrized class does not work

Added by Peter Meier about 1 year ago. Updated 28 days ago.

Status:Accepted Start date:03/01/2011
Priority:High Due date:
Assignee:Nick Lewis % Done:

0%

Category:parameterized classes
Target version:-
Affected Puppet version:2.6.5 Branch:https://github.com/nicklewis/puppet/tree/ticket/master/6539
Keywords:
Votes: 18

Description

Given the following manifest:


# cat foo.pp 
class a($m){
  include c
}

class b inherits a {
  include d
  notice $m
}

class c {
  file{'/tmp/a': content => $a::m }
}

class d inherits c {
  File['/tmp/a']{ mode => 0600 }
}

class{'b': m => 'foo' }

produces the following error:

# puppet --trace foo.pp
/usr/lib/ruby/site_ruby/1.8/puppet/util/errors.rb:60:in `fail'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/resource.rb:313:in `validate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/resource.rb:98:in `finish'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/resource.rb:70:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:151:in `evaluate_classes'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:142:in `each'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:142:in `evaluate_classes'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/resource.rb:56:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/util/errors.rb:35:in `exceptwrap'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/resource.rb:39:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/resource.rb:38:in `collect'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/resource.rb:38:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast.rb:72:in `safeevaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/astarray.rb:35:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/astarray.rb:34:in `collect'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/astarray.rb:34:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast.rb:72:in `safeevaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/resource/type.rb:76:in `evaluate_code'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/resource.rb:71:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:290:in `evaluate_main'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:101:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:18:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:77:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/util.rb:197:in `benchmark'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:75:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:34:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/indirection.rb:193:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector.rb:50:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/application/apply.rb:115:in `main'
/usr/lib/ruby/site_ruby/1.8/puppet/application/apply.rb:35:in `run_command'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:393:in `exit_on_fail'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/util/command_line.rb:55:in `execute'
/usr/bin/puppet:4
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:21:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:77:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/util.rb:197:in `benchmark'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:75:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:34:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/indirection.rb:193:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector.rb:50:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/application/apply.rb:115:in `main'
/usr/lib/ruby/site_ruby/1.8/puppet/application/apply.rb:35:in `run_command'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:393:in `exit_on_fail'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/util/command_line.rb:55:in `execute'
/usr/bin/puppet:4
Invalid parameter m at /tmp/foo.pp:18 on node foo

Changing the manifest to:

# cat foo.pp
class a($m){
  include c
}

class b($m) inherits a {
  include d
  notice $m
}

class c {
  file{'/tmp/a': content => $a::m }
}

class d inherits c {
  File['/tmp/a']{ mode => 0600 }
}

class{'b': m => 'foo' }

Produces the following error.

# puppet --trace foo.pp
/usr/lib/ruby/site_ruby/1.8/puppet/util/errors.rb:60:in `fail'
/usr/lib/ruby/site_ruby/1.8/puppet/resource/type.rb:232:in `set_resource_parameters'
/usr/lib/ruby/site_ruby/1.8/puppet/resource/type.rb:227:in `each'
/usr/lib/ruby/site_ruby/1.8/puppet/resource/type.rb:227:in `set_resource_parameters'
/usr/lib/ruby/site_ruby/1.8/puppet/resource/type.rb:74:in `evaluate_code'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/resource.rb:71:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/resource/type.rb:295:in `evaluate_parent_type'
/usr/lib/ruby/site_ruby/1.8/puppet/resource/type.rb:67:in `evaluate_code'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/resource.rb:71:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:151:in `evaluate_classes'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:142:in `each'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:142:in `evaluate_classes'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/resource.rb:56:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/util/errors.rb:35:in `exceptwrap'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/resource.rb:39:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/resource.rb:38:in `collect'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/resource.rb:38:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast.rb:72:in `safeevaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/astarray.rb:35:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/astarray.rb:34:in `collect'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast/astarray.rb:34:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/ast.rb:72:in `safeevaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/resource/type.rb:76:in `evaluate_code'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/resource.rb:71:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:290:in `evaluate_main'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:101:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:18:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:77:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/util.rb:197:in `benchmark'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:75:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:34:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/indirection.rb:193:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector.rb:50:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/application/apply.rb:115:in `main'
/usr/lib/ruby/site_ruby/1.8/puppet/application/apply.rb:35:in `run_command'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:393:in `exit_on_fail'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/util/command_line.rb:55:in `execute'
/usr/bin/puppet:4
/usr/lib/ruby/site_ruby/1.8/puppet/parser/compiler.rb:21:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:77:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/util.rb:197:in `benchmark'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:75:in `compile'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:34:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/indirection.rb:193:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector.rb:50:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/application/apply.rb:115:in `main'
/usr/lib/ruby/site_ruby/1.8/puppet/application/apply.rb:35:in `run_command'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:393:in `exit_on_fail'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/util/command_line.rb:55:in `execute'
/usr/bin/puppet:4
Must pass m to Class[A] at /tmp/foo.pp:1 on node foo

It seems like there is currently no way to inherit from a parametrized class.

Probably related to #4534


Related issues

related to Puppet - Bug #4534: Class inheritance with parameterized classes is ignored Closed 08/13/2010

History

Updated by James Turnbull about 1 year ago

  • Status changed from Unreviewed to Accepted
  • Assignee set to Nigel Kersten

Updated by Nigel Kersten 12 months ago

  • Assignee deleted (Nigel Kersten)
  • Priority changed from Normal to High

Updated by Andre Nathan 7 months ago

Is there a target version to have this fixed?

Updated by Nick Lewis 6 months ago

  • Assignee set to Nick Lewis
  • Branch set to https://github.com/nicklewis/puppet/tree/ticket/master/6539

I have a prototype partial fix to this. It doesn’t have tests, doesn’t yet support inheriting defaults in either direction (though it’s not clear whether a default for an argument in a child should be used as the value for that argument in the parent if the parent does not supply a default), and I likely has some glaring edge cases I haven’t considered (like defined types, or resource types other than classes).

In any case, if someone else wants to test whether it works, or find any problems with it, it’s available for testing now.

Updated by Howard Tyson 4 months ago

In my testing I’ve found that if you call the parent (handing in the paremeter) and then the child (handing in the parameter) it’ll work. It’s ugly, but it seems to be a reliable work around so far.

Something like with the example above:

class{'a': m => 'foo' }
class{'b': m => 'foo' }

Updated by Trevor Vaughan 3 months ago

I recently found myself looking at this exact same scenario.

The behaviour that I expect is:

  • Parent classes can be inherited (works)
  • Subclasses can add variables
  • Subclasses, when not defining a variable, will pick up the default variable from the parent
  • Variables must be referred to at the defined scope
    • $a::foo –> foo in the $a scope
    • $b::foo –> foo in the $b scope
  • It is an error to include both a class and a subclass of itself in the same scope
    • Not sure if this should be true, but it’s what I expect
  • Defines still cannot be inherited

Also available in: Atom PDF