-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Closed
Copy link
Labels
bugThis issue/PR relates to a bugThis issue/PR relates to a bugmodulemodulemodulepluginsplugin (any type)plugin (any type)traceback
Description
Summary
When the community.general.apk
module is invoked with a package name containing an unmatched quotation mark, the module passes the name
parameter directly to Python’s shlex.split()
without validation.
This call raises a ValueError: No closing quotation
, which is not caught by the module. Because the error is uncaptured, it propagates to Ansible and produces a raw Python traceback in the output.
Instead, we would expect the module to either:
- Validate the
name
parameter before callingshlex.split()
and fail early with a clear error message, or - Catch the
ValueError
and report it viafail_json()
to provide a user-friendly failure.
Issue Type
Bug Report
Component Name
apk
Ansible Version
$ ansible --version
ansible [core 2.18.6]
python version = 3.12.3
jinja version = 3.1.6
libyaml = True
Community.general Version
$ ansible-galaxy collection list community.general
Collection Version
----------------- -------
community.general 11.1.0
Configuration
$ ansible-config dump --only-changed
OS / Environment
Alpine 3.20.6
Steps to Reproduce
- name: Reproduce unmatched quote bug in apk module
hosts: localhost
gather_facts: false
tasks:
- name: Install package with unmatched quote
community.general.apk:
name: 'invalid"name'
state: present
Expected Results
We would expect the module to either:
- Validate the
name
parameter before callingshlex.split()
and fail early with a clear error message, or - Catch the
ValueError
and report it viafail_json()
to provide a user-friendly failure.
Actual Results
PLAY [Reproduce unmatched quote bug in apk module] ************************************************************************************
TASK [Install package with unmatched quote] *******************************************************************************************
task path: /foo.yml:5
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692 `" && echo ansible-tmp-1755282926.8335867-52-96736124164692="` echo /root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692 `" ) && sleep 0'
Using module file /usr/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/apk.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-49vqigmv9t/tmpni2l3hog TO /root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/AnsiballZ_apk.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+rwx /root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/ /root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/AnsiballZ_apk.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/AnsiballZ_apk.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/AnsiballZ_apk.py", line 107, in <module>
_ansiballz_main()
File "/root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/AnsiballZ_apk.py", line 99, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/AnsiballZ_apk.py", line 47, in invoke_module
runpy.run_module(mod_name='ansible_collections.community.general.plugins.modules.apk', init_globals=dict(_module_fqn='ansible_collections.community.general.plugins.modules.apk', _modlib_path=modlib_path),
File "<frozen runpy>", line 226, in run_module
File "<frozen runpy>", line 98, in _run_module_code
File "<frozen runpy>", line 88, in _run_code
File "/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible_collections/community/general/plugins/modules/apk.py", line 384, in <module>
File "/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible_collections/community/general/plugins/modules/apk.py", line 378, in main
File "/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible_collections/community/general/plugins/modules/apk.py", line 269, in install_packages
File "/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible_collections/community/general/plugins/modules/apk.py", line 230, in query_virtual
File "/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible/module_utils/basic.py", line 1856, in run_command
File "/usr/lib/python3.12/shlex.py", line 313, in split
return list(lex)
^^^^^^^^^
File "/usr/lib/python3.12/shlex.py", line 300, in __next__
token = self.get_token()
^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/shlex.py", line 109, in get_token
raw = self.read_token()
^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/shlex.py", line 191, in read_token
raise ValueError("No closing quotation")
ValueError: No closing quotation
fatal: [localhost]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n File \"/root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/AnsiballZ_apk.py\", line 107, in <module>\n _ansiballz_main()\n File \"/root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/AnsiballZ_apk.py\", line 99, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \"/root/.ansible/tmp/ansible-tmp-1755282926.8335867-52-96736124164692/AnsiballZ_apk.py\", line 47, in invoke_module\n runpy.run_module(mod_name='ansible_collections.community.general.plugins.modules.apk', init_globals=dict(_module_fqn='ansible_collections.community.general.plugins.modules.apk', _modlib_path=modlib_path),\n File \"<frozen runpy>\", line 226, in run_module\n File \"<frozen runpy>\", line 98, in _run_module_code\n File \"<frozen runpy>\", line 88, in _run_code\n File \"/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible_collections/community/general/plugins/modules/apk.py\", line 384, in <module>\n File \"/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible_collections/community/general/plugins/modules/apk.py\", line 378, in main\n File \"/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible_collections/community/general/plugins/modules/apk.py\", line 269, in install_packages\n File \"/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible_collections/community/general/plugins/modules/apk.py\", line 230, in query_virtual\n File \"/tmp/ansible_community.general.apk_payload_yf5tz74p/ansible_community.general.apk_payload.zip/ansible/module_utils/basic.py\", line 1856, in run_command\n File \"/usr/lib/python3.12/shlex.py\", line 313, in split\n return list(lex)\n ^^^^^^^^^\n File \"/usr/lib/python3.12/shlex.py\", line 300, in __next__\n token = self.get_token()\n ^^^^^^^^^^^^^^^^\n File \"/usr/lib/python3.12/shlex.py\", line 109, in get_token\n raw = self.read_token()\n ^^^^^^^^^^^^^^^^^\n File \"/usr/lib/python3.12/shlex.py\", line 191, in read_token\n raise ValueError(\"No closing quotation\")\nValueError: No closing quotation\n",
"module_stdout": "",
"msg": "MODULE FAILURE: No start of json char found\nSee stdout/stderr for the exact error",
"rc": 1
}
PLAY RECAP ****************************************************************************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Code of Conduct
- I agree to follow the Ansible Code of Conduct
Metadata
Metadata
Assignees
Labels
bugThis issue/PR relates to a bugThis issue/PR relates to a bugmodulemodulemodulepluginsplugin (any type)plugin (any type)traceback