# RE: Re: Re: Re: Re: How to detect user does exist?

**URL:** <https://discourse.chef.io/t/re-re-re-re-re-how-to-detect-user-does-exist/6464>\
**Category:** Chef Infra (archive)\
**Created:** [March 2, 2015, 4:42am UTC](https://discourse.chef.io/t/re-re-re-re-re-how-to-detect-user-does-exist/6464 "2015-03-02T04:42:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![kkeane](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@kkeane](https://discourse.chef.io/u/kkeane)\
**Post date:** [March 2, 2015, 4:42am UTC](https://discourse.chef.io/t/re-re-re-re-re-how-to-detect-user-does-exist/6464/1 "2015-03-02T04:42:54Z")

</div>

Looking over the documentation, I think this code has a file handle leak; you are supposed to call Etc.endpwent() to close the file.

It looks to me like the Etc module is too low-level to be appropriate for this use case. Also, the documentation is not clear on whether it uses nsswitch, or reads /etc/passwd directly. Using nsswitch would pick up users from sources like LDAP, winbindd or other sources.

Kevin Keane

The NetTech

[http://www.4nettech.com](http://www.4nettech.com)

Our values: Privacy, Liberty, Justice

See [https://www.4nettech.com/corp/the-nettech-values.html](https://www.4nettech.com/corp/the-nettech-values.html)

-----Original message-----  
From: Matthew Moretti [werebus@gmail.com](mailto:werebus@gmail.com)  
Sent: Sunday 1st March 2015 19:54  
To: [chef@lists.opscode.com](mailto:chef@lists.opscode.com)  
Subject: [chef] Re: Re: Re: Re: How to detect user does exist?

Documentation for Ruby’s ‘Etc’ module is here [http://ruby-doc.org/stdlib-2.0/libdoc/etc/rdoc/Etc.html](http://ruby-doc.org/stdlib-2.0/libdoc/etc/rdoc/Etc.html) . You could use it in place of your shell guard like so:

group “sensu” do  
action :modify  
members "vagrant"  
append true  
only\_if { Etc.getpwnam(‘vagrant’) rescue false }  
end

The “rescue” is required because .getpwnam raises an exception if the user can’t be found. If you want to avoid the sin of in-line “rescue”, this is a bit better:

group “sensu” do  
action :modify  
members "vagrant"  
append true  
only\_if do  
begin  
Etc.getpwnam(‘vagrant’)  
rescue ArgumentError  
false  
end  
end  
end

I’ll be honest, I prefer the “getent passwd vagrant” solution more. It’s easier to read, and isn’t any less efficient or more platform dependent than the Ruby solution as far as I can tell.

Matt Moretti

​

On Sun, Mar 1, 2015 at 8:47 PM, Anthony Kong \<[anthony.hw.kong@gmail.com](mailto:anthony.hw.kong@gmail.com) [mailto:anthony.hw.kong@gmail.com](mailto:anthony.hw.kong@gmail.com) \> wrote:  
Hi Mark,

Can you shed more light on it? Do you have a url to the documentation or some example?

Cheers,

Tony Kong  
blog: [www.ahwkong.com](http://www.ahwkong.com) [http://www.ahwkong.com](http://www.ahwkong.com)  
linkedin: [www.linkedin.com/in/anthonykong](http://www.linkedin.com/in/anthonykong) [http://www.linkedin.com/in/anthonykong](http://www.linkedin.com/in/anthonykong)

Don’t EVER make the mistake that you can design something better than what you get from ruthless massively parallel trial-and-error with a feedback cycle. That’s giving your intelligence much too much credit.

- Linus Torvalds

On Mon, Mar 2, 2015 at 4:12 AM, Mark Pimentel \<[markpimentel22@gmail.com](mailto:markpimentel22@gmail.com) [mailto:markpimentel22@gmail.com](mailto:markpimentel22@gmail.com) \> wrote:

For a more ruby-esque way you can use the built-in method Etc.

On Feb 28, 2015 5:56 PM, “Eric Helgeson” \<[erichelgeson@gmail.com](mailto:erichelgeson@gmail.com) [mailto:erichelgeson@gmail.com](mailto:erichelgeson@gmail.com) \> wrote:  
Hey Anthony,

You can use a guard in this case to check and execute the resource ‘only\_if’ the condition is true. You can use ruby or specify a command.

```auto
$ cat test.rb 
group "sensu" do
  action :modify
  members "vagrant"
  append true
  only_if "getent passwd vagrant"
end

$ chef-apply test.rb 
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * group[sensu] action modify (skipped due to only_if)

```

More info on Guards - [https://docs.chef.io/resource\_common.html#guards](https://docs.chef.io/resource_common.html#guards)

Grabbed the guard form this post - [http://stackoverflow.com/questions/24856339/chef-initialize-new-linux-user-if-it-doesnt-already-exist](http://stackoverflow.com/questions/24856339/chef-initialize-new-linux-user-if-it-doesnt-already-exist) [http://stackoverflow.com/questions/24856339/chef-initialize-new-linux-user-if-it-doesnt-already-exist](http://stackoverflow.com/questions/24856339/chef-initialize-new-linux-user-if-it-doesnt-already-exist)  
​  
HTH​

-Eric Helgeson  
@nulleric  
[http://usingchef.com](http://usingchef.com) [http://usingchef.com](http://usingchef.com)

On Sat, Feb 28, 2015 at 4:42 PM, Anthony Kong \<[anthony.hw.kong@gmail.com](mailto:anthony.hw.kong@gmail.com) [mailto:anthony.hw.kong@gmail.com](mailto:anthony.hw.kong@gmail.com) \> wrote:

Hi

I have this definition on my cookbook  
group “sensu” do

action :modify

members “vagrant”

append true

end

it will throw an exception when I run it on ec2 because there is no user vagrant

How can I avoid the exception? Is there any way to detect the user exist? I have checked the doc [https://docs.chef.io/resource\_group.html](https://docs.chef.io/resource_group.html) but there is nothing obvious

Cheers,

---

<div class="post-metadata">

**Author:** ![werebus](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/werebus/32/24_2.png) [@werebus](https://discourse.chef.io/u/werebus)\
**Post date:** [March 2, 2015, 5:40am UTC](https://discourse.chef.io/t/re-re-re-re-re-how-to-detect-user-does-exist/6464/2 "2015-03-02T05:40:45Z")

</div>

I agree on both counts. Etc.endpwent is required; I missed that. And, I  
also agree that this probably isn’t the right tool for the job. I think the  
first solution posed is better.

As far as nsswitch goes, it looks like the Ruby library interacts with  
the glibc  
function of the same name  
[http://man7.org/linux/man-pages/man3/getpwnam.3.html](http://man7.org/linux/man-pages/man3/getpwnam.3.html), whose documentation  
does imply that it’ll look in NIS, LDAP, etc. So…maybe?

Matt  
​

On Sun, Mar 1, 2015 at 11:42 PM, Kevin Keane Subscription \<  
[subscription@kkeane.com](mailto:subscription@kkeane.com)\> wrote:

> Looking over the documentation, I think this code has a file handle  
> leak; you are supposed to call Etc.endpwent() to close the file.
> 
> It looks to me like the Etc module is too low-level to be appropriate for  
> this use case. Also, the documentation is not clear on whether it uses  
> nsswitch, or reads /etc/passwd directly. Using nsswitch would pick up users  
> from sources like LDAP, winbindd or other sources.
> 
> Kevin Keane
> 
> The NetTech
> 
> [http://www.4nettech.com](http://www.4nettech.com)
> 
> Our values: Privacy, Liberty, Justice
> 
> See [https://www.4nettech.com/corp/the-nettech-values.html](https://www.4nettech.com/corp/the-nettech-values.html)
> 
> -----Original message-----  
> _From:_ Matthew Moretti [werebus@gmail.com](mailto:werebus@gmail.com)  
> _Sent:_ Sunday 1st March 2015 19:54  
> _To:_ [chef@lists.opscode.com](mailto:chef@lists.opscode.com)  
> _Subject:_ [chef] Re: Re: Re: Re: How to detect user does exist?
> 
> Documentation for Ruby’s ‘Etc’ module is here  
> [http://ruby-doc.org/stdlib-2.0/libdoc/etc/rdoc/Etc.html](http://ruby-doc.org/stdlib-2.0/libdoc/etc/rdoc/Etc.html). You could use  
> it in place of your shell guard like so:
> 
> group "sensu" do  
> action :modify  
> members "vagrant"  
> append true  
> only\_if { Etc.getpwnam('vagrant') rescue false }end
> 
> The “rescue” is required because .getpwnam raises an exception if the  
> user can’t be found. If you want to avoid the sin of in-line “rescue”, this  
> is a bit better:
> 
> group "sensu" do  
> action :modify  
> members "vagrant"  
> append true  
> only\_if do  
> begin  
> Etc.getpwnam('vagrant')  
> rescue ArgumentError  
> false  
> end  
> endend
> 
> I’ll be honest, I prefer the “getent passwd vagrant” solution more. It’s  
> easier to read, and isn’t any less efficient or more platform dependent  
> than the Ruby solution as far as I can tell.
> 
> Matt Moretti  
> ​
> 
> On Sun, Mar 1, 2015 at 8:47 PM, Anthony Kong [anthony.hw.kong@gmail.com](mailto:anthony.hw.kong@gmail.com)  
> wrote:
> 
> > Hi Mark,
> > 
> > Can you shed more light on it? Do you have a url to the documentation or  
> > some example?
> > 
> > Cheers,
> > 
> > Tony Kong  
> > _blog:_ [www.ahwkong.com](http://www.ahwkong.com)  
> > _linkedin:_ [www.linkedin.com/in/anthonykong](http://www.linkedin.com/in/anthonykong)
> > 
> > Don’t EVER make the mistake that you can design something better than  
> > what you get from ruthless massively parallel trial-and-error with a  
> > feedback cycle. That’s giving your intelligence _much_ too much credit.
> > 
> > - Linus Torvalds
> > 
> > On Mon, Mar 2, 2015 at 4:12 AM, Mark Pimentel [markpimentel22@gmail.com](mailto:markpimentel22@gmail.com)  
> > wrote:
> > 
> > > For a more ruby-esque way you can use the built-in method Etc.  
> > > On Feb 28, 2015 5:56 PM, "Eric Helgeson" [erichelgeson@gmail.com](mailto:erichelgeson@gmail.com) wrote:
> > > 
> > > > Hey Anthony,
> > > > 
> > > > You can use a guard in this case to check and execute the resource  
> > > > 'only\_if' the condition is true. You can use ruby or specify a command.
> > > > 
> > > > ```auto
> > > > $ cat test.rb
> > > > group "sensu" do
> > > > action :modify
> > > > members "vagrant"
> > > > append true
> > > > only_if "getent passwd vagrant"
> > > > end
> > > > 
> > > > $ chef-apply test.rb
> > > > Recipe: (chef-apply cookbook)::(chef-apply recipe)
> > > > * group[sensu] action modify (*skipped due to only_if*)
> > > > 
> > > > ```
> > > > 
> > > > More info on Guards - [Common Resource Functionality](https://docs.chef.io/resource_common.html#guards)
> > > > 
> > > > Grabbed the guard form this post -  
> > > > [Chef: Initialize new linux user if it doesn't already exist - Stack Overflow](http://stackoverflow.com/questions/24856339/chef-initialize-new-linux-user-if-it-doesnt-already-exist)  
> > > > ​  
> > > > HTH​
> > > > 
> > > > -Eric Helgeson  
> > > > @nulleric [https://twitter.com/nulleric](https://twitter.com/nulleric)  
> > > > [http://usingchef.com](http://usingchef.com)
> > > > 
> > > > On Sat, Feb 28, 2015 at 4:42 PM, Anthony Kong \<  
> > > > [anthony.hw.kong@gmail.com](mailto:anthony.hw.kong@gmail.com)\> wrote:
> > > > 
> > > > > Hi
> > > > > 
> > > > > I have this definition on my cookbook
> > > > > 
> > > > > group "sensu" do
> > > > > 
> > > > > action :modify
> > > > > 
> > > > > members "vagrant"
> > > > > 
> > > > > append true
> > > > > 
> > > > > end
> > > > > 
> > > > > it will throw an exception when I run it on ec2 because there is no  
> > > > > user vagrant
> > > > > 
> > > > > How can I avoid the exception? Is there any way to detect the user  
> > > > > exist? I have checked the doc [group Resource](https://docs.chef.io/resource_group.html)  
> > > > > but there is nothing obvious
> > > > > 
> > > > > Cheers,

---

<div class="post-metadata">

**Author:** ![Michael\_Glenney](https://avatars.discourse-cdn.com/v4/letter/m/a9adbd/32.png) [@Michael\_Glenney](https://discourse.chef.io/u/Michael_Glenney)\
**Post date:** [March 2, 2015, 3:31pm UTC](https://discourse.chef.io/t/re-re-re-re-re-how-to-detect-user-does-exist/6464/3 "2015-03-02T15:31:13Z")

</div>

If a node is in ec2 it'll have an ec2 attribute. So you can just do:

group "sensu" do

action :modify

members "vagrant"

append true

not\_if node['ec2']

end

You could also use chef sugar ([GitHub - sethvargo/chef-sugar](https://github.com/sethvargo/chef-sugar)) to  
check and see if you're using vagrant

group "sensu" do

action :modify

members "vagrant"

append true

only\_if { vagrant? }

end

> **[GitHub - sethvargo/chef-sugar](https://github.com/sethvargo/chef-sugar#vagrant)**
>
> Contribute to sethvargo/chef-sugar development by creating an account on GitHub.

Mike G.

New Context

On Sun, Mar 1, 2015 at 10:40 PM, Matthew Moretti [werebus@gmail.com](mailto:werebus@gmail.com) wrote:

> I agree on both counts. Etc.endpwent is required; I missed that. And, I  
> also agree that this probably isn’t the right tool for the job. I think the  
> first solution posed is better.
> 
> As far as nsswitch goes, it looks like the Ruby library interacts with the glibc  
> function of the same name  
> [http://man7.org/linux/man-pages/man3/getpwnam.3.html](http://man7.org/linux/man-pages/man3/getpwnam.3.html), whose  
> documentation does imply that it’ll look in NIS, LDAP, etc. So…maybe?
> 
> Matt  
> ​
> 
> On Sun, Mar 1, 2015 at 11:42 PM, Kevin Keane Subscription \<  
> [subscription@kkeane.com](mailto:subscription@kkeane.com)\> wrote:
> 
> > Looking over the documentation, I think this code has a file handle  
> > leak; you are supposed to call Etc.endpwent() to close the file.
> > 
> > It looks to me like the Etc module is too low-level to be appropriate for  
> > this use case. Also, the documentation is not clear on whether it uses  
> > nsswitch, or reads /etc/passwd directly. Using nsswitch would pick up users  
> > from sources like LDAP, winbindd or other sources.
> > 
> > Kevin Keane
> > 
> > The NetTech
> > 
> > [http://www.4nettech.com](http://www.4nettech.com)
> > 
> > Our values: Privacy, Liberty, Justice
> > 
> > See [https://www.4nettech.com/corp/the-nettech-values.html](https://www.4nettech.com/corp/the-nettech-values.html)
> > 
> > -----Original message-----  
> > _From:_ Matthew Moretti [werebus@gmail.com](mailto:werebus@gmail.com)  
> > _Sent:_ Sunday 1st March 2015 19:54  
> > _To:_ [chef@lists.opscode.com](mailto:chef@lists.opscode.com)  
> > _Subject:_ [chef] Re: Re: Re: Re: How to detect user does exist?
> > 
> > Documentation for Ruby’s ‘Etc’ module is here  
> > [http://ruby-doc.org/stdlib-2.0/libdoc/etc/rdoc/Etc.html](http://ruby-doc.org/stdlib-2.0/libdoc/etc/rdoc/Etc.html). You could use  
> > it in place of your shell guard like so:
> > 
> > group "sensu" do  
> > action :modify  
> > members "vagrant"  
> > append true  
> > only\_if { Etc.getpwnam('vagrant') rescue false }end
> > 
> > The “rescue” is required because .getpwnam raises an exception if the  
> > user can’t be found. If you want to avoid the sin of in-line “rescue”, this  
> > is a bit better:
> > 
> > group "sensu" do  
> > action :modify  
> > members "vagrant"  
> > append true  
> > only\_if do  
> > begin  
> > Etc.getpwnam('vagrant')  
> > rescue ArgumentError  
> > false  
> > end  
> > endend
> > 
> > I’ll be honest, I prefer the “getent passwd vagrant” solution more. It’s  
> > easier to read, and isn’t any less efficient or more platform dependent  
> > than the Ruby solution as far as I can tell.
> > 
> > Matt Moretti  
> > ​
> > 
> > On Sun, Mar 1, 2015 at 8:47 PM, Anthony Kong [anthony.hw.kong@gmail.com](mailto:anthony.hw.kong@gmail.com)  
> > wrote:
> > 
> > > Hi Mark,
> > > 
> > > Can you shed more light on it? Do you have a url to the documentation or  
> > > some example?
> > > 
> > > Cheers,
> > > 
> > > Tony Kong  
> > > _blog:_ [www.ahwkong.com](http://www.ahwkong.com)  
> > > _linkedin:_ [www.linkedin.com/in/anthonykong](http://www.linkedin.com/in/anthonykong)
> > > 
> > > Don’t EVER make the mistake that you can design something better than  
> > > what you get from ruthless massively parallel trial-and-error with a  
> > > feedback cycle. That’s giving your intelligence _much_ too much credit.
> > > 
> > > - Linus Torvalds
> > > 
> > > On Mon, Mar 2, 2015 at 4:12 AM, Mark Pimentel [markpimentel22@gmail.com](mailto:markpimentel22@gmail.com)  
> > > wrote:
> > > 
> > > > For a more ruby-esque way you can use the built-in method Etc.  
> > > > On Feb 28, 2015 5:56 PM, "Eric Helgeson" [erichelgeson@gmail.com](mailto:erichelgeson@gmail.com)  
> > > > wrote:
> > > > 
> > > > > Hey Anthony,
> > > > > 
> > > > > You can use a guard in this case to check and execute the resource  
> > > > > 'only\_if' the condition is true. You can use ruby or specify a command.
> > > > > 
> > > > > ```auto
> > > > > $ cat test.rb
> > > > > group "sensu" do
> > > > > action :modify
> > > > > members "vagrant"
> > > > > append true
> > > > > only_if "getent passwd vagrant"
> > > > > end
> > > > > 
> > > > > $ chef-apply test.rb
> > > > > Recipe: (chef-apply cookbook)::(chef-apply recipe)
> > > > > * group[sensu] action modify (*skipped due to only_if*)
> > > > > 
> > > > > ```
> > > > > 
> > > > > More info on Guards - [Common Resource Functionality](https://docs.chef.io/resource_common.html#guards)
> > > > > 
> > > > > Grabbed the guard form this post -  
> > > > > [Chef: Initialize new linux user if it doesn't already exist - Stack Overflow](http://stackoverflow.com/questions/24856339/chef-initialize-new-linux-user-if-it-doesnt-already-exist)  
> > > > > ​  
> > > > > HTH​
> > > > > 
> > > > > -Eric Helgeson  
> > > > > @nulleric [https://twitter.com/nulleric](https://twitter.com/nulleric)  
> > > > > [http://usingchef.com](http://usingchef.com)
> > > > > 
> > > > > On Sat, Feb 28, 2015 at 4:42 PM, Anthony Kong \<  
> > > > > [anthony.hw.kong@gmail.com](mailto:anthony.hw.kong@gmail.com)\> wrote:
> > > > > 
> > > > > > Hi
> > > > > > 
> > > > > > I have this definition on my cookbook
> > > > > > 
> > > > > > group "sensu" do
> > > > > > 
> > > > > > action :modify
> > > > > > 
> > > > > > members "vagrant"
> > > > > > 
> > > > > > append true
> > > > > > 
> > > > > > end
> > > > > > 
> > > > > > it will throw an exception when I run it on ec2 because there is no  
> > > > > > user vagrant
> > > > > > 
> > > > > > How can I avoid the exception? Is there any way to detect the user  
> > > > > > exist? I have checked the doc  
> > > > > > [group Resource](https://docs.chef.io/resource_group.html) but there is nothing obvious
> > > > > > 
> > > > > > Cheers,

---

<div class="post-metadata">

**Author:** ![Lamont\_Granquist](https://avatars.discourse-cdn.com/v4/letter/l/d26b3c/32.png) [@Lamont\_Granquist](https://discourse.chef.io/u/Lamont_Granquist)\
**Post date:** [March 2, 2015, 5:33pm UTC](https://discourse.chef.io/t/re-re-re-re-re-how-to-detect-user-does-exist/6464/4 "2015-03-02T17:33:52Z")

</div>

On 3/1/15 9:40 PM, Matthew Moretti wrote:

> I agree on both counts. |Etc.endpwent| is required; I missed that.  
> And, I also agree that this probably isn’t the right tool for the job.  
> I think the first solution posed is better.
> 
> As far as nsswitch goes, it looks like the Ruby library interacts with  
> the glibc function of the same name  
> [http://man7.org/linux/man-pages/man3/getpwnam.3.html](http://man7.org/linux/man-pages/man3/getpwnam.3.html), whose  
> documentation does imply that it’ll look in NIS, LDAP, etc. So…maybe?

It does. It also caches it for the lifetime of the process, so that if  
you update nsswitch.conf it'll still see the old values, which is a  
known issue. Same issue goes for updating resolv.conf
