dconf: Code refactor (#1585)
* Updated documentation * Use ``module.get_bin_path`` API to check existence of ``dbus-send``, ``dconf``, and ``dbus-run-session`` * Return ``out`` and ``err`` in ``fail_json`` which helps debugging Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>pull/1657/head
parent
e901d281cf
commit
1479544029
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- dconf - update documentation and logic code refactor (https://github.com/ansible-collections/community.general/pull/1585).
|
|
@ -1,21 +1,21 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# (c) 2017, Branko Majic <branko@majic.rs>
|
# Copyright: (c) 2017, Branko Majic <branko@majic.rs>
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = r'''
|
||||||
module: dconf
|
module: dconf
|
||||||
author:
|
author:
|
||||||
- "Branko Majic (@azaghal)"
|
- "Branko Majic (@azaghal)"
|
||||||
short_description: Modify and read dconf database
|
short_description: Modify and read dconf database
|
||||||
description:
|
description:
|
||||||
- This module allows modifications and reading of dconf database. The module
|
- This module allows modifications and reading of C(dconf) database. The module
|
||||||
is implemented as a wrapper around dconf tool. Please see the dconf(1) man
|
is implemented as a wrapper around C(dconf) tool. Please see the dconf(1) man
|
||||||
page for more details.
|
page for more details.
|
||||||
- Since C(dconf) requires a running D-Bus session to change values, the module
|
- Since C(dconf) requires a running D-Bus session to change values, the module
|
||||||
will try to detect an existing session and reuse it, or run the tool via
|
will try to detect an existing session and reuse it, or run the tool via
|
||||||
|
@ -55,21 +55,18 @@ options:
|
||||||
description:
|
description:
|
||||||
- Value to set for the specified dconf key. Value should be specified in
|
- 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
|
GVariant format. Due to complexity of this format, it is best to have a
|
||||||
look at existing values in the dconf database. Required for
|
look at existing values in the dconf database.
|
||||||
C(state=present).
|
- Required for I(state=present).
|
||||||
state:
|
state:
|
||||||
type: str
|
type: str
|
||||||
required: false
|
required: false
|
||||||
default: present
|
default: present
|
||||||
choices:
|
choices: [ 'read', 'present', 'absent' ]
|
||||||
- read
|
|
||||||
- present
|
|
||||||
- absent
|
|
||||||
description:
|
description:
|
||||||
- The action to take upon the key/value.
|
- The action to take upon the key/value.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = """
|
RETURN = r"""
|
||||||
value:
|
value:
|
||||||
description: value associated with the requested key
|
description: value associated with the requested key
|
||||||
returned: success, state was "read"
|
returned: success, state was "read"
|
||||||
|
@ -77,7 +74,7 @@ value:
|
||||||
sample: "'Default'"
|
sample: "'Default'"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
EXAMPLES = """
|
EXAMPLES = r"""
|
||||||
- name: Configure available keyboard layouts in Gnome
|
- name: Configure available keyboard layouts in Gnome
|
||||||
community.general.dconf:
|
community.general.dconf:
|
||||||
key: "/org/gnome/desktop/input-sources/sources"
|
key: "/org/gnome/desktop/input-sources/sources"
|
||||||
|
@ -126,10 +123,10 @@ import traceback
|
||||||
PSUTIL_IMP_ERR = None
|
PSUTIL_IMP_ERR = None
|
||||||
try:
|
try:
|
||||||
import psutil
|
import psutil
|
||||||
psutil_found = True
|
HAS_PSUTIL = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
PSUTIL_IMP_ERR = traceback.format_exc()
|
PSUTIL_IMP_ERR = traceback.format_exc()
|
||||||
psutil_found = False
|
HAS_PSUTIL = False
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||||
|
|
||||||
|
@ -165,7 +162,7 @@ class DBusWrapper(object):
|
||||||
# If no existing D-Bus session was detected, check if dbus-run-session
|
# If no existing D-Bus session was detected, check if dbus-run-session
|
||||||
# is available.
|
# is available.
|
||||||
if self.dbus_session_bus_address is None:
|
if self.dbus_session_bus_address is None:
|
||||||
self.module.get_bin_path('dbus-run-session', required=True)
|
self.dbus_run_session_cmd = self.module.get_bin_path('dbus-run-session', required=True)
|
||||||
|
|
||||||
def _get_existing_dbus_session(self):
|
def _get_existing_dbus_session(self):
|
||||||
"""
|
"""
|
||||||
|
@ -189,7 +186,8 @@ class DBusWrapper(object):
|
||||||
if process_real_uid == uid and 'DBUS_SESSION_BUS_ADDRESS' in process.environ():
|
if process_real_uid == uid and 'DBUS_SESSION_BUS_ADDRESS' in process.environ():
|
||||||
dbus_session_bus_address_candidate = process.environ()['DBUS_SESSION_BUS_ADDRESS']
|
dbus_session_bus_address_candidate = process.environ()['DBUS_SESSION_BUS_ADDRESS']
|
||||||
self.module.debug("Found D-Bus user session candidate at address: %s" % dbus_session_bus_address_candidate)
|
self.module.debug("Found D-Bus user session candidate at address: %s" % dbus_session_bus_address_candidate)
|
||||||
command = ['dbus-send', '--address=%s' % dbus_session_bus_address_candidate, '--type=signal', '/', 'com.example.test']
|
dbus_send_cmd = self.module.get_bin_path('dbus-send', required=True)
|
||||||
|
command = [dbus_send_cmd, '--address=%s' % dbus_session_bus_address_candidate, '--type=signal', '/', 'com.example.test']
|
||||||
rc, _, _ = self.module.run_command(command)
|
rc, _, _ = self.module.run_command(command)
|
||||||
|
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
|
@ -219,7 +217,7 @@ class DBusWrapper(object):
|
||||||
|
|
||||||
if self.dbus_session_bus_address is None:
|
if self.dbus_session_bus_address is None:
|
||||||
self.module.debug("Using dbus-run-session wrapper for running commands.")
|
self.module.debug("Using dbus-run-session wrapper for running commands.")
|
||||||
command = ['dbus-run-session'] + command
|
command = [self.dbus_run_session_cmd] + command
|
||||||
rc, out, err = self.module.run_command(command)
|
rc, out, err = self.module.run_command(command)
|
||||||
|
|
||||||
if self.dbus_session_bus_address is None and rc == 127:
|
if self.dbus_session_bus_address is None and rc == 127:
|
||||||
|
@ -246,6 +244,8 @@ class DconfPreference(object):
|
||||||
|
|
||||||
self.module = module
|
self.module = module
|
||||||
self.check_mode = check_mode
|
self.check_mode = check_mode
|
||||||
|
# Check if dconf binary exists
|
||||||
|
self.dconf_bin = self.module.get_bin_path('dconf', required=True)
|
||||||
|
|
||||||
def read(self, key):
|
def read(self, key):
|
||||||
"""
|
"""
|
||||||
|
@ -255,13 +255,14 @@ class DconfPreference(object):
|
||||||
|
|
||||||
:returns: string -- Value assigned to the provided key. If the value is not set for specified key, returns None.
|
:returns: string -- Value assigned to the provided key. If the value is not set for specified key, returns None.
|
||||||
"""
|
"""
|
||||||
|
command = [self.dconf_bin, "read", key]
|
||||||
command = ["dconf", "read", key]
|
|
||||||
|
|
||||||
rc, out, err = self.module.run_command(command)
|
rc, out, err = self.module.run_command(command)
|
||||||
|
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
self.module.fail_json(msg='dconf failed while reading the value with error: %s' % err)
|
self.module.fail_json(msg='dconf failed while reading the value with error: %s' % err,
|
||||||
|
out=out,
|
||||||
|
err=err)
|
||||||
|
|
||||||
if out == '':
|
if out == '':
|
||||||
value = None
|
value = None
|
||||||
|
@ -284,7 +285,6 @@ class DconfPreference(object):
|
||||||
|
|
||||||
:returns: bool -- True if a change was made, False if no change was required.
|
:returns: bool -- True if a change was made, False if no change was required.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# If no change is needed (or won't be done due to check_mode), notify
|
# If no change is needed (or won't be done due to check_mode), notify
|
||||||
# caller straight away.
|
# caller straight away.
|
||||||
if value == self.read(key):
|
if value == self.read(key):
|
||||||
|
@ -294,14 +294,16 @@ class DconfPreference(object):
|
||||||
|
|
||||||
# Set-up command to run. Since DBus is needed for write operation, wrap
|
# Set-up command to run. Since DBus is needed for write operation, wrap
|
||||||
# dconf command dbus-launch.
|
# dconf command dbus-launch.
|
||||||
command = ["dconf", "write", key, value]
|
command = [self.dconf_bin, "write", key, value]
|
||||||
|
|
||||||
# Run the command and fetch standard return code, stdout, and stderr.
|
# Run the command and fetch standard return code, stdout, and stderr.
|
||||||
dbus_wrapper = DBusWrapper(self.module)
|
dbus_wrapper = DBusWrapper(self.module)
|
||||||
rc, out, err = dbus_wrapper.run_command(command)
|
rc, out, err = dbus_wrapper.run_command(command)
|
||||||
|
|
||||||
if rc != 0:
|
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 write the value with error: %s' % err,
|
||||||
|
out=out,
|
||||||
|
err=err)
|
||||||
|
|
||||||
# Value was changed.
|
# Value was changed.
|
||||||
return True
|
return True
|
||||||
|
@ -330,14 +332,16 @@ class DconfPreference(object):
|
||||||
|
|
||||||
# Set-up command to run. Since DBus is needed for reset operation, wrap
|
# Set-up command to run. Since DBus is needed for reset operation, wrap
|
||||||
# dconf command dbus-launch.
|
# dconf command dbus-launch.
|
||||||
command = ["dconf", "reset", key]
|
command = [self.dconf_bin, "reset", key]
|
||||||
|
|
||||||
# Run the command and fetch standard return code, stdout, and stderr.
|
# Run the command and fetch standard return code, stdout, and stderr.
|
||||||
dbus_wrapper = DBusWrapper(self.module)
|
dbus_wrapper = DBusWrapper(self.module)
|
||||||
rc, out, err = dbus_wrapper.run_command(command)
|
rc, out, err = dbus_wrapper.run_command(command)
|
||||||
|
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
self.module.fail_json(msg='dconf failed while reseting the value with error: %s' % err)
|
self.module.fail_json(msg='dconf failed while reseting the value with error: %s' % err,
|
||||||
|
out=out,
|
||||||
|
err=err)
|
||||||
|
|
||||||
# Value was changed.
|
# Value was changed.
|
||||||
return True
|
return True
|
||||||
|
@ -354,7 +358,7 @@ def main():
|
||||||
supports_check_mode=True
|
supports_check_mode=True
|
||||||
)
|
)
|
||||||
|
|
||||||
if not psutil_found:
|
if not HAS_PSUTIL:
|
||||||
module.fail_json(msg=missing_required_lib("psutil"), exception=PSUTIL_IMP_ERR)
|
module.fail_json(msg=missing_required_lib("psutil"), exception=PSUTIL_IMP_ERR)
|
||||||
|
|
||||||
# If present state was specified, value must be provided.
|
# If present state was specified, value must be provided.
|
||||||
|
|
Loading…
Reference in New Issue