Repository: ansible/ansible

Issue:
anisble fails to alert when modules are missing
Is there changes in yml format in ansible dev latest? I have a simplest playbook that works fine with ansible 1.9.1 but fails with dev latest.

Playbook file:

```

---
- hosts: localhost
  connection: local
  tasks:
  - name: echo test
    shell: echo test
```

Running against ansible 1.9.1

```
[xxx]$ ansible --version
ansible 1.9.1
  configured module search path = None
[xxx]$ ansible-playbook test.yml 

PLAY [localhost] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [localhost]

TASK: [echo test] ************************************************************* 
changed: [localhost]

PLAY RECAP ******************************************************************** 
localhost                  : ok=2    changed=1    unreachable=0    failed=0   
```

Running against dev latest

```
[yyy]$ ansible --version
ansible 2.0.0
  configured module search path = None

[yyy]$ ansible-playbook test.yml  -i hosts
ERROR! no action detected in task

The error appears to have been in '/tmp/test.yml': line 5, column 5, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
  - name: echo test
    ^ here

```



Discussion:
I cannot confirm this is current devel.  Copying your playbook, works without error for me.

there should be no changes in format, we have revamped the parser to better display errors, but playbooks that work should still work.

I have also been unable to reproduce the error with your test playbook

I created a new clean virtual env and it still fails. Could it be missing dependencies?

```
[13:48 wyang@us0101ado019 ecommerce]$ virtualenv -p /opt/rh/python27/root/usr/bin/python py27
Already using interpreter /opt/rh/python27/root/usr/bin/python
New python executable in py27/bin/python
Installing Setuptools..............................................................................................................................................................................................................................done.
Installing Pip.....................................................................................................................................................................................................................................................................................................................................done.
[13:48 wyang@us0101ado019 ecommerce]$ source py27/bin/activate
(py27)[13:48 wyang@us0101ado019 ecommerce]$ python --version
Python 2.7.5
(py27)[13:48 wyang@us0101ado019 ecommerce]$ pip install boto
...
Successfully installed boto
Cleaning up...
(py27)[13:49 wyang@us0101ado019 ecommerce]$ pip install awscli
...
Successfully installed awscli botocore bcdoc colorama docutils rsa jmespath python-dateutil six pyasn1
Cleaning up...

# I try to bring in the dependencies from ansible 1.9.1
(py27)[13:49 wyang@us0101ado019 ecommerce]$ pip install ansible
Downloading/unpacking ansible
  Downloading ansible-1.9.1.tar.gz (917kB): 917kB downloaded
...
Successfully installed ansible paramiko jinja2 PyYAML pycrypto ecdsa markupsafe
Cleaning up...


(py27)[13:49 wyang@us0101ado019 ecommerce]$ pip uninstall ansible
Uninstalling ansible:
...
Proceed (y/n)? y
  Successfully uninstalled ansible

# new ansible installation
(py27)[13:50 wyang@us0101ado019 ecommerce]$ git clone https://github.com/ansible/ansible.git
(py27)[13:50 wyang@us0101ado019 ecommerce]$ cd ansible
(py27)[13:50 wyang@us0101ado019 ansible]$ ls
bin  build  CHANGELOG.md  CODING_GUIDELINES.md  CONTRIBUTING.md  COPYING  dist  docs  docsite  examples  hacking  ISSUE_TEMPLATE.md  lib  Makefile  MANIFEST.in  packaging  plugins  README.md  RELEASES.txt  samples  setup.py  test  test-requirements.txt  ticket_stubs  tox.ini  v1  VERSION
(py27)[13:50 wyang@us0101ado019 ansible]$ make
...
(py27)[13:50 wyang@us0101ado019 ansible]$ make install
...
Using /local/wyang/ecommerce/py27/lib/python2.7/site-packages
Finished processing dependencies for ansible==2.0.0
(py27)[13:50 wyang@us0101ado019 ansible]$ ansible --version
ansible 2.0.0
  configured module search path = None

(py27)[13:51 wyang@us0101ado019 ecommerce]$ pip list
ansible (2.0.0)
awscli (1.7.32)
bcdoc (0.15.0)
boto (2.38.0)
botocore (1.0.0b1)
colorama (0.3.3)
docutils (0.12)
ecdsa (0.13)
Jinja2 (2.7.3)
jmespath (0.7.1)
MarkupSafe (0.23)
paramiko (1.15.2)
pip (1.4.1)
pyasn1 (0.1.7)
pycrypto (2.6.1)
python-dateutil (2.4.2)
PyYAML (3.11)
rsa (3.1.4)
setuptools (0.9.8)
six (1.9.0)
wsgiref (0.1.2)

(py27)[13:50 wyang@us0101ado019 ansible]$ ansible --version
ansible 2.0.0
  configured module search path = None
(py27)[13:50 wyang@us0101ado019 ecommerce]$ ansible-playbook -vvvv /tmp/test.yml  -i hosts 
ERROR! no action detected in task

The error appears to have been in '/tmp/test.yml': line 5, column 5, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
  - name: echo test
    ^ here

```

I don't think so.  Maybe you have mixed tabs and spaces in your yml file or other odd characters?  Could you perhaps upload that yml file some place that could be downloaded directly, as opposed to copying and pasting the contents?

I saw this when I didn't have any modules checked out into my git checkout. "ansible --version" should show you the module library paths, as well as the instructions on how to check them out.

@tgerla ah, good catch, I notice that now in the output from above that the submodules don't appear to have been initialized.

FYI, I noticed this behaviour with custom modiules and when some play was included from another dir: either when calling the play directly or he one that included it, (don't recall which for now) had the same effect (`library/` being adjacent to the included play). I brought this up on IRC#ansible-devel, just pointing out here to be sure.

I'm thinking we probably need to move the functionality of `ActionBase._configure_module` to an earlier place.  Maybe even into `PluginLoader`.

@wyyang to be more explicit, it appears as though you need to do `git submodule update --init --recursive` after the `git clone`, and before the `make`/`make install`.

This issue needs to stay open though, to resolve the problem where we would never get to a point where the logic in `ActionBase._configure_module` would run, telling you to init and update the submodules.

Got. Good catch. Works now. 

User error. Issue closed.

As mentioned, we should keep this open, since we have code that should detect this, it should be made to work again.

Yes. Now I have the modules installed, running ansible --version still does not show anything different then when the modules were missing.

```
(py27)[15:26 wyang@us0101ado019 ecommerce]$ ansible --version
ansible 2.0.0
  configured module search path = None
```

well, this last one should be 'normal', its the previous 'non event' that was supposed to be caught.

I don't know. If none of the core and extra modules are installed, will it be beneficial for ansible --version to show they are missing? And when the modules are installed, show the versions of them?

The message in --version appears to be working now:

```
$ ansible --version                        *[devel]  (12:05:01)
ansible 2.0.0 (devel cc646c0a82) last updated 2015/09/21 11:57:55 (GMT -700)
  lib/ansible/modules/core:  not found - use git submodule update --init lib/ansible/modules/core
  lib/ansible/modules/extras:  not found - use git submodule update --init lib/ansible/modules/extras
  config file = /etc/ansible/ansible.cfg
  configured module search path = None
```

There's still not a good message from a playbook run, though.  Working on that.


Resolving patch:
diff --git a/lib/ansible/parsing/mod_args.py b/lib/ansible/parsing/mod_args.py
--- a/lib/ansible/parsing/mod_args.py
+++ b/lib/ansible/parsing/mod_args.py
@@ -275,7 +275,14 @@ def parse(self):
 
         # if we didn't see any module in the task at all, it's not a task really
         if action is None:
-            raise AnsibleParserError("no action detected in task", obj=self._task_ds)
+            if 'ping' not in module_loader:
+                raise AnsibleParserError("The requested action was not found in configured module paths. "
+                        "Additionally, core modules are missing. If this is a checkout, "
+                        "run 'git submodule update --init --recursive' to correct this problem.",
+                        obj=self._task_ds)
+
+            else:
+                raise AnsibleParserError("no action detected in task", obj=self._task_ds)
         elif args.get('_raw_params', '') != '' and action not in RAW_PARAM_MODULES:
             templar = Templar(loader=None)
             raw_params = args.pop('_raw_params')


Test patch: