Repository: ansible/ansible

Issue:
Add a "move_home" parameter to the user module
The following playbook fails with the message `msg: usermod: directory /tmp exists`:

```

---
- hosts: server
  tasks:
  - user: name=test
          system=yes
          home=/
          state=present
  - user: name=test
          system=yes
          home=/tmp
          state=present
```

This is because the user module passes the `-m` option for modifying a user when the home directory option is passed (`user` module, line 366), which would move the contents of the previous home directory.

Would it be better to accept an argument to control this behavior?

But ideally, I'd think that the user module should simply not pass -m implicitly, instead gaining a move_home= boolean option (default false) and pass that flag only if this is true. An admin should know if they expect the home directory to move, and accidentally doing so can cause all sorts of havoc.



Discussion:
Seems it would be better to just not error out?

The `-m` option tries to move the contents of the home directory … if you want to move the home directory, I guess being unable to do so is indeed an error, while if you don't care about previous home directories, there is no need to pass `-m` in the first place. I guess not passing `-m` would be the quick and clean solution, having people take care about moving the home directory separately if they want that?

@jorgenschaefer can you clarify what you are trying to accomplish? My understanding is that you want to modify an existing user's homedirectory and set it to a directory that already exists?

I can set this behavior with a simple patch, but I'd like to confirm what you expect:

<pre>
diff --git a/library/system/user b/library/system/user
index 0528bd5..6cc213c 100644
--- a/library/system/user
+++ b/library/system/user
@@ -1358,8 +1358,10 @@ class AIX(User):
                 cmd.append('-c')
                 cmd.append(self.comment)
 
-        if self.home is not None and info[5] != self.home:
+        if self.home is not None and info[5] != self.home and not os.path.exists(self.home):
             cmd.append('-m')
+
+        if self.home is not None and info[5] != self.home:
             cmd.append('-d')
             cmd.append(self.home)
</pre>

I noticed the bug originally when I tried to change the home directory of an existing user (legacy user) to `/`, which failed because / already existed.

Your patch could cause other problems. For example, I'm very unsure about what would happen if you'd then try to change the home directory of an existing user from `/` to `/home/foo`, or similar changes (like, from `/bin/` to something else).

@jorgenschaefer Just tested successfully with this playbook:

<pre>
- hosts: el6.lab.net
  #connection: local
  gather_facts: False
  tasks:
    # clear out old user
    - shell: userdel bob 
      ignore_errors: True
    - shell: rm -rf /home/bob*
      ignore_errors: True
    - shell: fgrep bob /etc/passwd
      ignore_errors: True
    # create new user
    - user: name=bob home=/home/bob state=present
    - shell: fgrep bob /etc/passwd
      ignore_errors: True
    # change home to new dir
    - user: name=bob home=/home/bob2 state=present
    - shell: fgrep bob /etc/passwd
      ignore_errors: True
    # set home to existing dir
    - user: name=bob home=/tmp state=present
    - shell: fgrep bob /etc/passwd
      ignore_errors: True
    # set home to new dir from existing dir
    - user: name=bob home=/home/bob3 state=present
    - shell: fgrep bob /etc/passwd
      ignore_errors: True
</pre>

Let me know of any other tests I should add in there to validate the behavior, if you can think of any.

The following results in an unusable host, so be careful:

```
- hosts: vagrant
  user: vagrant
  gather_facts: False
  sudo: yes
  tasks:
    - user: name=bob state=absent
    - user: name=bob home=/bin system=yes state=present
    - user: name=bob home=/home/bob system=yes state=present
```

Setting the home directory to / first results in the error `usermod: cannot rename directory / to /home/bob`, luckily.

@jorgenschaefer I see what you mean. /bin's contents is moved to /home/bob. 

Going back to the original comment ... What do you advise as the expected workflow for this situation?

I have to admit I was a bit surprised to see the `-m` option passed to `usermod` implicitly. I expected it to only modify the home directory entry in `/etc/passwd`.

That flag should likely be avoided _at least_ for system users, as they do not get a home directory by default. But ideally, I'd think that the `user` module should simply not pass `-m` implicitly, instead gaining a `move_home=` boolean option (default false) and pass that flag only if this is true. An admin should know if they expect the home directory to move, and accidentally doing so can cause all sorts of havoc.

@jorgenschaefer I'm going to move this from a bug to a feature request. I agree with you on a new move_home option, which will require some refactoring.

https://github.com/ansible/ansible/pull/5811 has been merged, so I believe this issue should be resolved, but I don't have permissions to close it.

@aclindsa thank you!


Resolving patch:
diff --git a/lib/ansible/modules/cloud/azure/azure_rm_virtualmachine.py b/lib/ansible/modules/cloud/azure/azure_rm_virtualmachine.py
--- a/lib/ansible/modules/cloud/azure/azure_rm_virtualmachine.py
+++ b/lib/ansible/modules/cloud/azure/azure_rm_virtualmachine.py
@@ -1243,7 +1243,7 @@ def create_default_nic(self):
 
         if self.subnet_name:
             try:
-                subnet = self.network_client.subnets.get(self.resource_group, virtual_network_name)
+                subnet = self.network_client.subnets.get(self.resource_group, virtual_network_name, self.subnet_name)
                 subnet_id = subnet.id
             except Exception as exc:
                 self.fail("Error: fetching subnet {0} - {1}".format(self.subnet_name, str(exc)))


Test patch: