Bug #6539
Inheritance of a parametrized class does not work
| Status: | Accepted | Start date: | 03/01/2011 | |
|---|---|---|---|---|
| Priority: | High | Due date: | ||
| Assignee: | % 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
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