mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
dconf: three minor but useful fixes (#6206)
* dconf: Correctly handle setting a key that has no value in DB We need to check if the value in the database is None before we try to parse it, because the GVariant parser won't accept None as an input value. By definition if the value is None, i.e., there's no value in the database, than any value the user is trying to set is a change, so just indicate that it's a change without trying to compare the None to whatever the user specified as the value.x * dconf: Give a more useful error when writing a key fails if writing a key fails, then include in the error that is returned the exact key and value aguments that were given to the dconf command, to assist in diagnosing failures caused by providing the key or value in the wrong format.x * dconf: Convert boolean values into the format that dconf expects Even though we warn users to be careful to specify GVariant strings for values, a common error is to be trying to specify a boolean string which ends up getting converted into a boolean by the YAML parser or Ansible. Then it gets converted to "True" or "False", the string representations of Python booleans, which are not valid GVariants. Rather than just failing with an obscure error when this happens, let's be more user-friendly and detect when the user has specified a boolean and convert it into the correct GVariant forms, "true" or "false", so it just works. There's no good reason to be more pedantic than that.
This commit is contained in:
parent
86f9a657e7
commit
a5765143f1
2 changed files with 28 additions and 3 deletions
2
changelogs/fragments/6206-dconf-booleans.yml
Normal file
2
changelogs/fragments/6206-dconf-booleans.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- "dconf - be forgiving about boolean values: convert them to GVariant booleans automatically (https://github.com/ansible-collections/community.general/pull/6206)."
|
|
@ -70,13 +70,18 @@ options:
|
|||
description:
|
||||
- A dconf key to modify or read from the dconf database.
|
||||
value:
|
||||
type: str
|
||||
type: raw
|
||||
required: false
|
||||
description:
|
||||
- Value to set for the specified dconf key. Value should be specified in
|
||||
GVariant format. Due to complexity of this format, it is best to have a
|
||||
look at existing values in the dconf database.
|
||||
- Required for I(state=present).
|
||||
- Although the type is specified as "raw", it should typically be
|
||||
specified as a string. However, boolean values in particular are
|
||||
handled properly even when specified as booleans rather than strings
|
||||
(in fact, handling booleans properly is why the type of this parameter
|
||||
is "raw").
|
||||
state:
|
||||
type: str
|
||||
required: false
|
||||
|
@ -155,6 +160,7 @@ except ImportError:
|
|||
HAS_PSUTIL = False
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
|
||||
class DBusWrapper(object):
|
||||
|
@ -288,6 +294,10 @@ class DconfPreference(object):
|
|||
|
||||
Returns True if the two values are equal.
|
||||
"""
|
||||
if canonical_value is None:
|
||||
# It's unset in dconf database, so anything the user is trying to
|
||||
# set is a change.
|
||||
return False
|
||||
try:
|
||||
variant1 = Variant.parse(None, canonical_value)
|
||||
variant2 = Variant.parse(variant1.get_type(), user_value)
|
||||
|
@ -349,7 +359,7 @@ class DconfPreference(object):
|
|||
rc, out, err = dbus_wrapper.run_command(command)
|
||||
|
||||
if rc != 0:
|
||||
self.module.fail_json(msg='dconf failed while write the value with error: %s' % err,
|
||||
self.module.fail_json(msg='dconf failed while writing key %s, value %s with error: %s' % (key, value, err),
|
||||
out=out,
|
||||
err=err)
|
||||
|
||||
|
@ -401,11 +411,24 @@ def main():
|
|||
argument_spec=dict(
|
||||
state=dict(default='present', choices=['present', 'absent', 'read']),
|
||||
key=dict(required=True, type='str', no_log=False),
|
||||
value=dict(required=False, default=None, type='str'),
|
||||
# Converted to str below after special handling of bool.
|
||||
value=dict(required=False, default=None, type='raw'),
|
||||
),
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
# Try to be forgiving about the user specifying a boolean as the value, or
|
||||
# more accurately about the fact that YAML and Ansible are quite insistent
|
||||
# about converting strings that look like booleans into booleans. Convert
|
||||
# the boolean into a string of the type dconf will understand. Any type for
|
||||
# the value other than boolean is just converted into a string directly.
|
||||
if module.params['value'] is not None:
|
||||
if isinstance(module.params['value'], bool):
|
||||
module.params['value'] = 'true' if module.params['value'] else 'false'
|
||||
else:
|
||||
module.params['value'] = to_native(
|
||||
module.params['value'], errors='surrogate_or_strict')
|
||||
|
||||
if Variant is None:
|
||||
module.warn(
|
||||
'WARNING: The gi.repository Python library is not available; '
|
||||
|
|
Loading…
Reference in a new issue