jistr / ansible-gsetting

Ansible module for setting GSettings entries
Apache License 2.0
47 stars 18 forks source link

Setting values are being interpreted by Python under recent ansible/python #18

Open Ian2020 opened 1 year ago

Ian2020 commented 1 year ago

Under Fedora 37 (ansible 7.1, python 3.11.1) if your setting value resembles a Python type, e.g. a list like "[ 'some value' ]" then it gets interpreted as one, leading to an error inside gsetting. This seems quite likely given how many gsettings have the same syntax as Python lists.

This is NOT a problem under Fedora 36 (ansible 5.9, python 3.10.9).

Example task:

- name: set tracker directories
  become: yes
  gsetting:
    user: "me"
    settings:
      "org.freedesktop.Tracker3.Miner.Files.index-recursive-directories": "['&DOCUMENTS', '&DOWNLOAD', '&MUSIC', '&PICTURES']"

Gives:

Traceback (most recent call last):
  File \"/home/me/.ansible/tmp/ansible-tmp-1675943488.5975382-83483-120901875465516/AnsiballZ_gsetting\", line 107, in <module>
    _ansiballz_main()
  File \"/home/me/.ansible/tmp/ansible-tmp-1675943488.5975382-83483-120901875465516/AnsiballZ_gsetting\", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File \"/home/me/.ansible/tmp/ansible-tmp-1675943488.5975382-83483-120901875465516/AnsiballZ_gsetting\", line 47, in invoke_module
    runpy.run_module(mod_name='ansible.modules.gsetting', init_globals=dict(_module_fqn='ansible.modules.gsetting', _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_gsetting_payload_z_wkixsm/ansible_gsetting_payload.zip/ansible/modules/gsetting.py\", line 136, in <module>
  File \"/tmp/ansible_gsetting_payload_z_wkixsm/ansible_gsetting_payload.zip/ansible/modules/gsetting.py\", line 123, in main
  File \"/tmp/ansible_gsetting_payload_z_wkixsm/ansible_gsetting_payload.zip/ansible/modules/gsetting.py\", line 68, in _set_value
  File \"/tmp/ansible_gsetting_payload_z_wkixsm/ansible_gsetting_payload.zip/ansible/modules/gsetting.py\", line 13, in _escape_single_quotes
  File \"/usr/lib64/python3.11/re/__init__.py\", line 185, in sub
    return _compile(pattern, flags).sub(repl, string, count)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: expected string or bytes-like object, got 'list'

I believe this is due to the value: "['&DOCUMENTS', '&DOWNLOAD', '&MUSIC', '&PICTURES']" becoming a Python list by the time it's fed to the gsetting module.

I don't know why this has changed - must be something inside ansible or python.

Looking at the history of the ansible code that launches modules lib/ansible/executor/module_common.py there has been some changes around dropping python2 support that may have altered the behaviour of how arguments are interpreted/passed but I would be surprised if this hadn't affected loads of other modules too.

This can be 'fixed' in gsetting by forcing the value back to a string:

if type(value) is not str:
    value=str(value)

...but this seems a total hack. A better approach might be to use argument_spec in the module to force values to be strings but this is not supported for the dict type.

Mitlik commented 5 months ago

I also hit something like this issue on Ubuntu16.04 and Ansible 2.0.0.2 (python 2.7), I was trying to set a value to 0 and it would return the same TypeError from _escape_single_quotes() re.sub call. I landed on the same hack fix outlined here and had included it in PR #22 without realizing it might be a separate issue.