Repository: ansible/ansible

Issue:
Pip module returns unchanged when creating a venv with already installed packages
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
pip module

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.2.2.0
  config file =
  configured module search path = Default w/o overrides
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
[defaults]
hostfile = inventory
legacy_playbook_variables = false
nocows = 1
retry_files_enabled = false


##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->
Debian 9 primary, deployed to Void Linux, likely N/A

##### SUMMARY
<!--- Explain the problem briefly -->
When creating a virtualenv with only default packages i.e. pip, the pip module returns green despite the fact it created the venv.

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: Create Python Virtual Environment
  pip:
    name: pip
    virtualenv: /home/user/venv/
    virtualenv_python: python2
```
<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Even if no new python packages are installed to the venv, the pip module should return changed if the venv is created

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
The module returns unchanged

<!--- Paste verbatim command output between quotes below -->
```
TASK [server : Create Python Virtual Environment] ***********************
ok: [ctfd-testing]
```



Discussion:
cc @mattupstate
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/packaging/language/pip.py b/lib/ansible/modules/packaging/language/pip.py
--- a/lib/ansible/modules/packaging/language/pip.py
+++ b/lib/ansible/modules/packaging/language/pip.py
@@ -441,9 +441,10 @@ def main():
         out = ''
 
         env = module.params['virtualenv']
-
+        venv_created = False
         if env:
             if not os.path.exists(os.path.join(env, 'bin', 'activate')):
+                venv_created = True
                 if module.check_mode:
                     module.exit_json(changed=True)
 
@@ -582,6 +583,8 @@ def main():
                 _, out_freeze_after, _ = _get_packages(module, pip, chdir)
                 changed = out_freeze_before != out_freeze_after
 
+        changed = changed or venv_created
+
         module.exit_json(changed=changed, cmd=cmd, name=name, version=version,
                          state=state, requirements=requirements, virtualenv=env,
                          stdout=out, stderr=err)


Test patch:
diff --git a/test/integration/targets/pip/tasks/pip.yml b/test/integration/targets/pip/tasks/pip.yml
--- a/test/integration/targets/pip/tasks/pip.yml
+++ b/test/integration/targets/pip/tasks/pip.yml
@@ -166,3 +166,20 @@
   assert:
     that:
       - "not q_check_mode.changed"
+
+# ansible#23204
+- name: ensure is a fresh virtualenv
+  file:
+    state: absent
+    name: "{{ output_dir }}/pipenv"
+
+- name: install pip throught pip into fresh virtualenv
+  pip:
+    name: pip
+    virtualenv: "{{ output_dir }}/pipenv"
+  register: pip_install_venv
+
+- name: make sure pip in fresh virtualenv report changed
+  assert:
+    that:
+      - "pip_install_venv.changed"