Getting Traceback error due to AnsibleParserError
ssbarnea opened this issue · comments
What is the output if you execute ansible-lint directly on the file? The output seems to imply that ansible-lint cannot parse the file due to some syntax error.
The linter has lots and lots of cases when it just crashes with a traceback instead of returning a proper linting error.
Still, a crash on the linter should not render the atom editor useless. With the current behaviour it is impossible to use atom due to these errors.
I raise a bug against the ansible-linter here ansible/ansible-lint#125 -- probably a better place to track this.
Please, and I say this here and on ansible-lint, provide a minimal complete verifiable example.
I really can't fix ansible-lint issues from a stacktrace without other context.
---
- hosts:localhost
roles:
- name: xxx
I just tried it in atom and actually did not get an error until I put a space in hosts: localhost
which is odd.
Executing it on the command line caused the following stack trace.
ansible-lint --version
ansible-lint 2.4.1
ansible-lint foo.yml
Traceback (most recent call last):
File "/usr/bin/ansible-lint", line 116, in <module>
sys.exit(main(sys.argv[1:]))
File "/usr/bin/ansible-lint", line 103, in main
matches = runner.run()
File "/usr/lib/python2.7/site-packages/ansiblelint/__init__.py", line 201, in run
for file in ansiblelint.utils.find_children(arg):
File "/usr/lib/python2.7/site-packages/ansiblelint/utils.py", line 119, in find_children
pb_data = parse_yaml_from_file(playbook[0])
File "/usr/lib/python2.7/site-packages/ansiblelint/utils.py", line 42, in parse_yaml_from_file
return dl.load_from_file(filepath)
File "/usr/lib/python2.7/site-packages/ansible/parsing/dataloader.py", line 114, in load_from_file
parsed_data = self.load(data=file_data, file_name=file_name, show_content=show_content)
File "/usr/lib/python2.7/site-packages/ansible/parsing/dataloader.py", line 95, in load
self._handle_error(yaml_exc, file_name, show_content)
File "/usr/lib/python2.7/site-packages/ansible/parsing/dataloader.py", line 191, in _handle_error
raise AnsibleParserError(YAML_SYNTAX_ERROR, obj=err_obj, show_content=show_content)
ansible.errors.AnsibleParserError: Syntax Error while loading YAML.
The error appears to have been in '/home/mis6541/foo.yml': line 3, column 8, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- hosts:localhost
roles:
^ here
@willthames I just executed ansible-lint on a playbook that was fine in previous versions and it also now throws errors. Did something break in 2.4.1? Is your tox.ini executing any tests where the .yml
are being loaded into ansible-lint for testing?
This is invalid yaml. ansible-lint can't parse it because ansible's underlying yaml loader won't load it either, and that's because yaml.safe_load
can't parse it
python -c 'import yaml; yaml.safe_load("---\n- hosts:localhost\n roles:\n - name: xxx\n\n")'
Blaming this on ansible-lint is ridiculous.
Put a space between hosts and localhost and ansible-lint gets a bit further, but then it fails because roles lists should contain a list of things that are either a role name or a dict containing a role
key.
I tend not to expect ansible-lint to be run on completely broken playbooks that wouldn't work under ansible-playbook either, but perhaps I'm expecting too much.
If you think ansible-lint should handle these cases better, feel free to raise PRs.
It might make sense to run ansible-playbook --syntax-check
on your playbooks as a pre-check to running ansible-lint
[ansible-lint (master)]$ ansible-playbook --syntax-check test/norole.yml -i localhost,
ERROR: Syntax Error while loading YAML script, test/norole.yml
Note: The error may actually appear before this position: line 3, column 8
- hosts:localhost
roles:
^
And with the fix to - hosts: localhost
:
[ansible-lint (master)]$ ansible-playbook --syntax-check test/norole.yml -i localhost,
playbook: test/norole.yml
ERROR: expected a role name in dictionary: {'name': 'xxx'}
@willthames Do you think there should be a try/except on the yaml.safe_load
in ansible-lint so people will be able to more easily differentiate between a style issue and a syntax error?
After your response I will go ahead and close this.
I would say that doing a syntax check should be part of the default behaviour or the linter. If it does pass this step it will continue with the next ones. Still, I do not see any reason for not doing it, especially because without this default behaviour it would be much harder to integrate it with other tools, like IDEs such atom.
If someone wants to disable this we could have an option, but by default check the syntax before running the linter.
@mschuchard I recommend using ansible-playbook --syntax-check.
This is no different to puppet-lint, for example.
I've added some extra handling for this to just exit on failure, but am not sure if it's going to be any more consumable by tools (see ansible/ansible-lint#126)
I think adding in the try/except will lead people to see a simple error message and think 'I made a syntax mistake' instead of seeing a long stack trace and think 'is there a bug in ansible-lint?' This should help you out with future situations like this one.
Also I believe you meant to reference ssbarnea in the above comment and not myself. I do not feel strongly one way or the other about syntax checking inside ansible-lint prior to style checking.
Thanks guys for running this to ground.
Ansible linter throws traceback error in this case and the author recommends running "ansible-playbook --syntax-check" before doing the linting in order to spot bad syntax bad syntax and to avoid those.
I already requested him to include this as the default behaviour but I am not sure he will implement it, which makes me think that at least for the moment we should include this into the atom linter.