I'm trying to add the users on a system as puppet facts. I'm not a ruby programmer and the following code properly generates the users, but their uid is all the same (the uid of the last entry in the password file). If uid was out of scope, I would expect an unknown symbol error, if Facter.add was only getting called once at the end, I would expect there to be only one user, the last one, same as the uid. I don't understand how one can iterate without the other one doing so as well...
File.open("/etc/passwd", "r") do |passwords|
while pw_entry = passwords.gets
user, pw, uid, gid, gecos, home, shell = pw_entry.split(/:/)
Facter.add("user_" + user) do
setcode do
uid
end
end
end
end
In poking around, I found someone else with nearly the identical problem and this was the solution (which did work for me as well):
require 'etc'
Etc.passwd { |user|
Facter.add("user_" + user.name) {
setcode {
user.uid
}
}
}
...however I don't understand what the difference is. It acts like calls to the Facter.add block are getting buffered and run all at once at the end of the loop, and Etc loaded up all of passwd so user.uid indexes into the array and timing is irrelevant. That would be a bizarre thing for a procedural language to be doing though...