Repository: ansible/ansible

Issue:
Macports not recognized as package manager on OSX
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
macports, package modules

##### ANSIBLE VERSION
```
ansible 2.4.0.0
  config file = /Users/***/Dotfiles/ansible/ansible.cfg
  configured module search path = ['/Users/***/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/***/.envs/ansible/lib/python3.5/site-packages/ansible
  executable location = /Users/***/.envs/ansible/bin/ansible
  python version = 3.5.3 (default, Apr 23 2017, 18:09:27) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]

```

##### CONFIGURATION
```
DEFAULT_HOST_LIST(/Users/***/Dotfiles/ansible/ansible.cfg) = ['/Users/***/Dotfiles/ansible/hosts']
DEFAULT_ROLES_PATH(/Users/***/Dotfiles/ansible/ansible.cfg) = ['/Users/rubendibattista/Dotfiles/ansible/roles']
DEFAULT_STDOUT_CALLBACK(/Users/***/Dotfiles/ansible/ansible.cfg) = debug
```

##### OS / ENVIRONMENT
OSX 10.12.6

##### SUMMARY
When running a task using the `package` module, `macports` does not get recognized and the error ```Could not detect which package manager to use. Try gathering facts or setting the "use" option.``` is returned.

##### STEPS TO REPRODUCE
`ansible-playbook pkg.yml`

`pkg.yml`
```
- hosts: localhost
  tasks: 
    - name: Test Package
      package: 
        name: zsh
        state: present
      become: true
```

```
ansible localhost -m setup | grep pkg
        "ansible_pkg_mgr": "macports",
```

##### EXPECTED RESULTS
Ansible uses the `macports` module to install packages

##### ACTUAL RESULTS
Ansible raise an error not recognizing the installed macports as the right package manager to use

```
PLAY [localhost] ***********************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Test Package] ********************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {
    "changed": false,
    "failed": true
}

MSG:

Could not detect which package manager to use. Try gathering facts or setting the "use" option.

        to retry, use: --limit @/Users/rubendibattista/Dotfiles/ansible/pkg.retry

PLAY RECAP *****************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1
```



Discussion:
I believe the cause to your problem is in that you are not specifying a password to use with `become`

Due to some unknown reason, it looks like ansible cannot find `ansible_pkg_mgr` and is attempting to re-run `setup`.  

You have supplied `become: true`, and this applies to the additional `setup` task as well, and ansible fails due to needing a sudo password.

Try adding `--ask-become-pass` and re-running this playbook.

needs_info
This shouldn't be happening though, at least not manifesting itself in this specific way.  It looks as though https://github.com/ansible/ansible/pull/22849 broke using pre gathered facts, which forces the module to always fall back on a second `setup` run.
cc @dharmabumstead @jcftang
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
cc @bcoca 

Not sure why https://github.com/ansible/ansible/pull/22849 was done, but seems to be breaking the templating in `package` for getting the `ansible_pkg_mgr`, it always falls back to re-running `setup`.

Additionally, when re-running `setup` fails here with `'module_stdout': 'sudo: a password is required\r\n',` we probably need to indicate that, as right now we swallow it, and get an ambiguous error.
@sivel Correct. It was the password! (I recently switched laptop and in the other one I had sudo without password). 

Sorry for the dumb problem...
Not a dumb problem really.  It uncovered 2 potential bugs, or at least 1 bug and 1 place where we can do better.

Resolving patch:
diff --git a/lib/ansible/plugins/action/package.py b/lib/ansible/plugins/action/package.py
--- a/lib/ansible/plugins/action/package.py
+++ b/lib/ansible/plugins/action/package.py
@@ -43,9 +43,9 @@ def run(self, tmp=None, task_vars=None):
         if module == 'auto':
             try:
                 if self._task.delegate_to:  # if we delegate, we should use delegated host's facts
-                    module = self._templar.template("{{hostvars['%s']['ansible_facts']['ansible_pkg_mgr']}}" % self._task.delegate_to)
+                    module = self._templar.template("{{hostvars['%s']['ansible_pkg_mgr']}}" % self._task.delegate_to)
                 else:
-                    module = self._templar.template('{{ansible_facts["ansible_pkg_mgr"]}}')
+                    module = self._templar.template('{{ansible_pkg_mgr}}')
             except:
                 pass  # could not get it from template!
 
diff --git a/lib/ansible/plugins/action/service.py b/lib/ansible/plugins/action/service.py
--- a/lib/ansible/plugins/action/service.py
+++ b/lib/ansible/plugins/action/service.py
@@ -42,9 +42,9 @@ def run(self, tmp=None, task_vars=None):
         if module == 'auto':
             try:
                 if self._task.delegate_to:  # if we delegate, we should use delegated host's facts
-                    module = self._templar.template("{{hostvars['%s']['ansible_facts']['ansible_service_mgr']}}" % self._task.delegate_to)
+                    module = self._templar.template("{{hostvars['%s']['ansible_service_mgr']}}" % self._task.delegate_to)
                 else:
-                    module = self._templar.template('{{ansible_facts["ansible_service_mgr"]}}')
+                    module = self._templar.template('{{ansible_service_mgr}}')
             except:
                 pass  # could not get it from template!
 


Test patch: