Module to determine home directory for a named user

635 views
Skip to first unread message

Gordon Mckeown

unread,
Mar 18, 2016, 1:56:14 PM3/18/16
to Ansible Development
Hi all,

Have started playing around with Ansible over the last couple of days, and as part of my playbook to set up a new server I wanted to copy files to the home directories of some specific users. I couldn't find an existing way of reliably determining user home directories -- just grepping /etc/passwd isn't quite enough -- and so I knocked together a module to get this for me.

No idea if I've done things the "right" way, but thought the code might be useful to someone. Also would appreciate any critique or suggestions from those that know the system better. I'm more of a Perl and Java man, so I don't promise my Python code is pretty or sensible.

Call method from inside a playbook is:

- name: Get user home directory
  userhomedir
: loginid=targetuser
 
register: user

- name: Debug info
  debug
: msg="Home directory for user {{ user.loginid }} is {{ user.dest }}"


Module code:

#!/usr/bin/python

# -------
# Imports
# -------

import sys, pwd, re
from ansible.module_utils.basic import *


# --------------
# Define Globals
# --------------

module = AnsibleModule(
        argument_spec
= dict(
            loginid
= dict(required=True, type='str')
           
)
       
)

if sys.platform.startswith('linux'):
    default_home
= "/home"
    default_useradd_file
= "/etc/default/useradd"
    default_useradd_entry
= "HOME"

elif sys.platform.startswith('freebsd'):
    default_home
= "/home"
    default_useradd_file
= "/etc/adduser.conf"
    default_useradd_entry
= "homeprefix"

else:
   
module.fail_json(msg="Module does not know how to handle operating system " + sys.platform)

was_useradd_parsed
= False


# ----------------
# Define Functions
# ----------------

def getDirFromPasswd(check_username):
    pwd_homedir
= ""
   
try:
        user_entry
= pwd.getpwnam(check_username)
        pwd_homedir
= user_entry[5]
   
except:
       
pass

   
return {'method': "Password File", 'directory':pwd_homedir}


def getDirFromUseradd(check_username):
   
global was_useradd_parsed
    def_dir
= ""
    home_regex
= "^" + re.escape(default_useradd_entry) + "=(.*)"
   
try:
        default_file
= open(default_useradd_file)
        was_useradd_parsed
= True
       
for line in default_file:
            match
= re.search(home_regex, line)
           
if match:
                def_dir
= match.group(1) + "/" + check_username
               
module.exit_json(changed=False, loginid="TEST", homedir=chosen_home['directory'], source=chosen_home['method'], platform=sys.platform)
               
break
        default_file
.close()
   
except:
       
pass

   
return {'method': "Useradd Default", 'directory':def_dir}


def getDirFromFallback(check_username):
    assumed_directory
= default_home + "/" + check_username
   
return {'method': "Fall-back", 'directory': assumed_directory}


# -------------
# Main Function
# -------------

def main():
    username
= module.params['loginid']

    chosen_home
= getDirFromPasswd(username)

   
if chosen_home['directory'] == "":
        chosen_home
= getDirFromUseradd(username)

       
if chosen_home['directory'] == "":
            chosen_home
= getDirFromFallback(username)

   
module.exit_json(changed=False, loginid=username, dest=chosen_home['directory'], source=chosen_home['method'], platform=sys.platform, useradd_parsed=was_useradd_parsed)


# ------
# Run Me
# ------

if __name__ == '__main__':
    main
()


Brian Coca

unread,
Mar 18, 2016, 3:06:09 PM3/18/16
to Gordon Mckeown, Ansible Development
You can already get this info:
#> ansible -m getent -a 'database=passwd key=myuser' localhost -vv
localhost | SUCCESS => {
   "ansible_facts": {     
       "getent_passwd": {                                     
           "myuser": [                                         
               "x",                                               
               "1000",                                               
               "100",                                             
               "My User",                                  
               "/home/myuser",                            
               "/bin/bash"                               
           ]                                                 
       }            
                                                            
----------
Brian Coca

Gordon Mckeown

unread,
Mar 18, 2016, 5:05:15 PM3/18/16
to Ansible Development
Great, thanks Brian, that's really useful to know. Evidently my Google-fu failed me on this one since searching for "ansible getent" returns that module as the first result.

What I didn't make clear is that my requirement is to determine the home directory for a user, and if that user doesn't yet exist, provide an educated guess where their home folder would get created. This way I can pre-create the folder and stick authorized_keys and whatever into it on a new machine even before I've logged on with a particular account.

Perhaps it's a very unique requirement to my test lab, but as I said, I thought I'd share in case it's useful. Also, any general feedback on the module will be helpful if I do create something that has wider application :)
Reply all
Reply to author
Forward
0 new messages