Bug #1674
String/array comparisons cause language failures
| Status: | Accepted | Start date: | 10/22/2008 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | - | % Done: | 0% |
|
| Category: | language | |||
| Target version: | - | |||
| Affected Puppet version: | 0.24.5 | Branch: | ||
| Keywords: | ||||
| Votes: | 0 |
Description
If the ‘groups’ attribute for a user is first stored as a string, but then later changed to an array, Puppet throws an exception and complains that it can’t compare a string to an array. Here’s a trace:
/usr/lib/ruby/1.8/puppet/type/user.rb:192:in `sort' /usr/lib/ruby/1.8/puppet/type/user.rb:192:in `should' /usr/lib/ruby/1.8/puppet/type/user.rb:320 /usr/lib/ruby/1.8/puppet/metatype/relationships.rb:27:in `instance_eval' /usr/lib/ruby/1.8/puppet/metatype/relationships.rb:27:in `autorequire' /usr/lib/ruby/1.8/puppet/metatype/relationships.rb:14:in `eachautorequire' /usr/lib/ruby/1.8/puppet/metatype/relationships.rb:13:in `each' /usr/lib/ruby/1.8/puppet/metatype/relationships.rb:13:in `eachautorequire' /usr/lib/ruby/1.8/puppet/metatype/relationships.rb:22:in `autorequire' /usr/lib/ruby/1.8/puppet/node/catalog.rb:346:in `relationship_graph' /usr/lib/ruby/1.8/puppet/node/catalog.rb:345:in `each' /usr/lib/ruby/1.8/puppet/node/catalog.rb:345:in `relationship_graph' /usr/lib/ruby/1.8/puppet/transaction.rb:515:in `relationship_graph' /usr/lib/ruby/1.8/puppet/transaction.rb:511:in `prepare' /usr/lib/ruby/1.8/puppet/transaction.rb:300:in `evaluate' /usr/lib/ruby/1.8/puppet/node/catalog.rb:124:in `apply' /usr/lib/ruby/1.8/puppet/network/client/master.rb:255:in `run' /usr/lib/ruby/1.8/puppet/util.rb:212:in `benchmark' /usr/lib/ruby/1.8/benchmark.rb:293:in `measure' /usr/lib/ruby/1.8/benchmark.rb:307:in `realtime' /usr/lib/ruby/1.8/puppet/util.rb:211:in `benchmark' /usr/lib/ruby/1.8/puppet/network/client/master.rb:254:in `run' /usr/lib/ruby/1.8/sync.rb:230:in `synchronize' /usr/lib/ruby/1.8/puppet/network/client/master.rb:236:in `run' /usr/sbin/puppetd:417 err: Got an uncaught exception of type ArgumentError: comparison of String with Array failed debug: Storing state debug: Stored state in 0.04 seconds notice: Finished catalog run in 0.18 seconds
History
Updated by Andrew Shafer over 3 years ago
- Status changed from Unreviewed to Accepted
- Assignee set to Andrew Shafer
Can you include the puppet manifest that is throwing this?
The exception not being rescued is definitely an issue.
I was under the impression that groups always had to be specified as an array.
Updated by Ryan Steele over 3 years ago
Below are the classes and definitions used to reproduce this problem. And, according to the TypeReference, arrays are only needed when specifying multiple groups.
Class which realizes the user
class dev_userconf {
realize( Group["alpha"], Group["tango"], Group["charlie"], Group["bravo"] )
realize( User_account["foo"] )
}
Class which passes some user attributes to the user_accts virtual define. Start out with this, then after the client runs once, change the ‘groups’ to: [“charlie”, “bravo”], or even just [“bravo”] – any array will throw an exception.
class user_accts {
@user_account { "foo":
comment => "Foo Bar",
type => "dev",
groups => "bravo";
}
}
The virtual definition
define user_account ( ensure = present, type, comment, shell = false, groups = false ) {
# Define the appropriate shell and supplementary groups
case $type {
dev: {
$supp_groups = $groups ? {
false => ["alpha", "tango"],
default => ["alpha", "tango", $groups]
}
$user_shell = $shell ? {
false => "/bin/bash",
default => $shell
}
}
nondev: {
$supp_groups = $groups ? {
false => "charlie",
default => ["charlie", $groups]
}
$user_shell = "/sbin/nologin"
}
}
user { $name:
ensure => $ensure,
groups => $supp_groups,
comment => $comment,
shell => $user_shell,
}
}
Also worth noting is even if you start out with an array for the ‘groups’ attribute, if you ever switch to using a single string, you can never switch back.
Updated by Ryan Steele over 3 years ago
After re-reading my configuration, I see the problem: I’ve got a define that accepts an argument “groups”, which defaults to false. I use a selector to check what the value of $groups is. But, sometimes the value passed in to $groups is an array (for example, [“alpha”, “tango”]). Thus, when the selector tries to compare ‘false’ to [‘foo’, ‘bar’], it freaks out because it’s making a string to array comparison. I would have thought it would just fall back to the default when it couldn’t produce a match for ‘false’, but apparently not.
Updated by Luke Kanies over 3 years ago
- Status changed from Accepted to Rejected
rgsteele wrote:
After re-reading my configuration, I see the problem: I’ve got a define that accepts an argument “groups”, which defaults to false. I use a selector to check what the value of $groups is. But, sometimes the value passed in to $groups is an array (for example, [“alpha”, “tango”]). Thus, when the selector tries to compare ‘false’ to [‘foo’, ‘bar’], it freaks out because it’s making a string to array comparison. I would have thought it would just fall back to the default when it couldn’t produce a match for ‘false’, but apparently not.
Sounds like this isn’t a bug after all, then?
I’ll close it based on that assessment; reopen if you disagree.
Updated by Luke Kanies over 3 years ago
- Subject changed from Puppet compares string to array if 'groups' attribute of user type is changed accordingly. to String/array comparisons cause language failures
- Category changed from user to language
- Status changed from Rejected to Accepted
- Priority changed from High to Normal
This is just a language problem: If you have a case or selector statement and you try to use both arrays and strings, you’ll get a failure. Strings and arrays should be treated as not equal (although maybe an array should be considered equal to a string if its only item is equivalent to that string), but they shouldn’t cause failures.
Updated by James Turnbull 9 months ago
- Description updated (diff)
- Assignee deleted (
Andrew Shafer)