Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xml module: Error w/ valid Xpath #29078

Closed
quocvu opened this issue Sep 7, 2017 · 5 comments
Closed

xml module: Error w/ valid Xpath #29078

quocvu opened this issue Sep 7, 2017 · 5 comments
Labels
affects_2.4 This issue/PR affects Ansible v2.4 bug This issue/PR relates to a bug. m:xml This issue/PR relates to the xml module. module This issue/PR relates to a module. python3 support:community This issue/PR relates to code supported by the Ansible community.

Comments

@quocvu
Copy link

quocvu commented Sep 7, 2017

ISSUE TYPE
  • Bug Report
COMPONENT NAME

XML Module

ANSIBLE VERSION
ansible 2.4.0.0
  config file = /Users/i857085/quoc/code/ansible/test_playbook/ansible.cfg
  configured module search path = [u'/Users/i857085/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Library/Python/2.7/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.10 (default, Feb  7 2017, 00:08:15) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]
CONFIGURATION

[defaults]

inventory = ./hosts
roles_path = ~/.ansible/roles:../
ansible_python_interpreter = python2

OS / ENVIRONMENT

OSX running ansible against a ArchLinux VM

SUMMARY

Getting invalid XPath

STEPS TO REPRODUCE
- name: Configure the number of virtual desktops
  xml:
    path: /home/{{ ansible_ssh_user }}/.config/openbox/rc.xml
    xpath: /openbox_config/desktops/number
    value: 3

I want to set the value of the xml tag to 3. XML file looks like this

<?xml version="1.0" encoding="UTF-8"?>

<!-- Do not edit this file, it will be overwritten on install.
        Copy the file to $HOME/.config/openbox/ instead. -->

<openbox_config xmlns="http://openbox.org/3.4/rc"
                xmlns:xi="http://www.w3.org/2001/XInclude">

<desktops>
  <!-- this stuff is only used at startup, pagers allow you to change them
       during a session

       these are default values to use when other ones are not already set
       by other applications, or saved in your session

       use obconf if you want to change these without having to log out
       and back in -->
  <number>4</number>
  <firstdesk>1</firstdesk>
  <names>
    <!-- set names up here if you want to, like this:
    <name>desktop 1</name>
    <name>desktop 2</name>
    -->
  </names>
  <popupTime>875</popupTime>
  <!-- The number of milliseconds to show the popup for when switching
       desktops.  Set this to 0 to disable the popup. -->
</desktops>
</openbox_config>
EXPECTED RESULTS

Expected the value changed from 4 to 3

ACTUAL RESULTS

getting this error

TASK [openbox-archlinux : Configure the number of virtual desktops] *************************
task path: /xyz/code/ansible/openbox-archlinux/tasks/main.yml:71
fatal: [172.28.128.3]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Shared connection to 172.28.128.3 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 546, in set_target_inner\r\n    changed = check_or_make_target(module, tree, xpath, namespaces)\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 474, in check_or_make_target\r\n    changed = check_or_make_target(module, tree, inner_xpath, namespaces)\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 474, in check_or_make_target\r\n    changed = check_or_make_target(module, tree, inner_xpath, namespaces)\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 473, in check_or_make_target\r\n    if not is_node(tree, inner_xpath, namespaces):\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 318, in is_node\r\n    if xpath_matches(tree, xpath, namespaces):\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 342, in xpath_matches\r\n    if tree.xpath(xpath, namespaces=namespaces):\r\n  File \"src/lxml/lxml.etree.pyx\", line 2287, in lxml.etree._ElementTree.xpath (src/lxml/lxml.etree.c:68382)\r\n  File \"src/lxml/xpath.pxi\", line 359, in lxml.etree.XPathDocumentEvaluator.__call__ (src/lxml/lxml.etree.c:173282)\r\n  File \"src/lxml/xpath.pxi\", line 227, in lxml.etree._XPathEvaluatorBase._handle_result (src/lxml/lxml.etree.c:171653)\r\nlxml.etree.XPathEvalError: Invalid expression\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 853, in <module>\r\n    main()\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 839, in main\r\n    set_target(module, doc, xpath, namespaces, attribute, value)\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 573, in set_target\r\n    changed = set_target_inner(module, tree, xpath, namespaces, attribute, value)\r\n  File \"/tmp/ansible_rh0r4yaw/ansible_module_xml.py\", line 549, in set_target_inner\r\n    (xpath, e, etree.tostring(tree, pretty_print=True)), exception=traceback.format_exc(e))\r\n  File \"/usr/lib/python3.6/traceback.py\", line 163, in format_exc\r\n    return \"\".join(format_exception(*sys.exc_info(), limit=limit, chain=chain))\r\n  File \"/usr/lib/python3.6/traceback.py\", line 117, in format_exception\r\n    type(value), value, tb, limit=limit).format(chain=chain))\r\n  File \"/usr/lib/python3.6/traceback.py\", line 497, in __init__\r\n    capture_locals=capture_locals)\r\n  File \"/usr/lib/python3.6/traceback.py\", line 332, in extract\r\n    if limit >= 0:\r\nTypeError: '>=' not supported between instances of 'XPathEvalError' and 'int'\r\n", "msg": "MODULE FAILURE", "rc": 0}
	to retry, use: --limit @/xyz/code/ansible/test_playbook/playbook.retry

PLAY RECAP **********************************************************************************
172.28.128.3               : ok=7    changed=2    unreachable=0    failed=1
@ansibot
Copy link
Contributor

ansibot commented Sep 7, 2017

@ansibot ansibot added affects_2.4 This issue/PR affects Ansible v2.4 bug_report module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. python3 support:community This issue/PR relates to code supported by the Ansible community. labels Sep 7, 2017
@dagwieers dagwieers changed the title Error w/ valid Xpath xml module: Error w/ valid Xpath Sep 7, 2017
@jborean93 jborean93 removed the needs_triage Needs a first human triage before being processed. label Sep 7, 2017
@sm4rk0
Copy link
Contributor

sm4rk0 commented Sep 7, 2017

This is a common mistake. There's XML namespace set in your XML document: xmlns="http://openbox.org/3.4/rc" and you should use it in XPath. See the namespaces module argument and the last example in documentation.
Please close the issue if this comment helped.

@quocvu
Copy link
Author

quocvu commented Sep 7, 2017

worked! Thanks @sm4rk0

@quocvu quocvu closed this as completed Sep 7, 2017
@sm4rk0
Copy link
Contributor

sm4rk0 commented Sep 8, 2017

BTW, @dagwieers - this bug report reveals three things. (Should I open a new issue(s) for them?)

First is a need for specific error message in case of XPath exceptions due to the missing namespace argument (I'm adding this as an idea to the Module wiki).

Second is missing try block around a call to tree.xpath here:

def xpath_matches(tree, xpath, namespaces):
    """ Test if a node exists """
    if tree.xpath(xpath, namespaces=namespaces):
        return True
return False

Third is a bug in exception handling introduced by this commit prior to module upstreaming. This is the solution that should work (not tested).

Here's the formatted module_stdout from above (Actual results):

Traceback (most recent call last):
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 546, in set_target_inner
    changed = check_or_make_target(module, tree, xpath, namespaces)
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 474, in check_or_make_target
    changed = check_or_make_target(module, tree, inner_xpath, namespaces)
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 474, in check_or_make_target
    changed = check_or_make_target(module, tree, inner_xpath, namespaces)
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 473, in check_or_make_target
    if not is_node(tree, inner_xpath, namespaces):
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 318, in is_node
    if xpath_matches(tree, xpath, namespaces):
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 342, in xpath_matches
    if tree.xpath(xpath, namespaces=namespaces):
  File "src/lxml/lxml.etree.pyx", line 2287, in lxml.etree._ElementTree.xpath (src/lxml/lxml.etree.c:68382)
  File "src/lxml/xpath.pxi", line 359, in lxml.etree.XPathDocumentEvaluator.__call__ (src/lxml/lxml.etree.c:173282)
  File "src/lxml/xpath.pxi", line 227, in lxml.etree._XPathEvaluatorBase._handle_result (src/lxml/lxml.etree.c:171653)
lxml.etree.XPathEvalError: Invalid expression

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 853, in <module>
    main()
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 839, in main
    set_target(module, doc, xpath, namespaces, attribute, value)
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 573, in set_target
    changed = set_target_inner(module, tree, xpath, namespaces, attribute, value)
  File "/tmp/ansible_rh0r4yaw/ansible_module_xml.py", line 549, in set_target_inner
    (xpath, e, etree.tostring(tree, pretty_print=True)), exception=traceback.format_exc(e))
  File "/usr/lib/python3.6/traceback.py", line 163, in format_exc
    return "".join(format_exception(*sys.exc_info(), limit=limit, chain=chain))
  File "/usr/lib/python3.6/traceback.py", line 117, in format_exception
    type(value), value, tb, limit=limit).format(chain=chain))
  File "/usr/lib/python3.6/traceback.py", line 497, in __init__
    capture_locals=capture_locals)
  File "/usr/lib/python3.6/traceback.py", line 332, in extract
    if limit >= 0:
TypeError: '>=' not supported between instances of 'XPathEvalError' and 'int'

@dagwieers
Copy link
Member

@sm4rk0 Please open issues for everything you consider needs a discussion, and PRs for everything you'd like to see changed. And thanks again for your help.

@dagwieers dagwieers added the m:xml This issue/PR relates to the xml module. label Sep 27, 2017
@ansibot ansibot added bug This issue/PR relates to a bug. and removed bug_report labels Mar 7, 2018
@ansible ansible locked and limited conversation to collaborators Apr 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.4 This issue/PR affects Ansible v2.4 bug This issue/PR relates to a bug. m:xml This issue/PR relates to the xml module. module This issue/PR relates to a module. python3 support:community This issue/PR relates to code supported by the Ansible community.
Projects
None yet
Development

No branches or pull requests

5 participants