From 8ba3d9474055450fce493f1b707ae707df144dbd Mon Sep 17 00:00:00 2001 From: Alexei Znamensky <103110+russoz@users.noreply.github.com> Date: Mon, 6 Jun 2022 20:38:46 +1200 Subject: [PATCH] xfconf module utils: providing a cmd_runner object (#4776) * xfconf: changed implementation to use cmd_runner * added module_utils/xfconf.py * xfconf_info: using cmd_runner * added module_utils to BOTMETA.yml * added changelog fragment * use cmd_runner_fmt instead of deprecated form --- .github/BOTMETA.yml | 3 + .../fragments/4776-xfconf-cmd-runner.yaml | 4 ++ plugins/module_utils/xfconf.py | 37 ++++++++++++ plugins/modules/system/xfconf.py | 57 +++++-------------- plugins/modules/system/xfconf_info.py | 28 ++++----- 5 files changed, 68 insertions(+), 61 deletions(-) create mode 100644 changelogs/fragments/4776-xfconf-cmd-runner.yaml create mode 100644 plugins/module_utils/xfconf.py diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 4b21be9c4c..685a1d0f53 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -307,6 +307,9 @@ files: $module_utils/xenserver.py: maintainers: bvitnik labels: xenserver + $module_utils/xfconf.py: + maintainers: russoz + labels: xfconf $modules/cloud/alicloud/: maintainers: xiaozhu36 $modules/cloud/atomic/atomic_container.py: diff --git a/changelogs/fragments/4776-xfconf-cmd-runner.yaml b/changelogs/fragments/4776-xfconf-cmd-runner.yaml new file mode 100644 index 0000000000..a45cf51c31 --- /dev/null +++ b/changelogs/fragments/4776-xfconf-cmd-runner.yaml @@ -0,0 +1,4 @@ +minor_changes: + - xfconf module utils - created new module util ``xfconf`` providing a ``cmd_runner`` specific for ``xfconf`` modules (https://github.com/ansible-collections/community.general/pull/4776). + - xfconf - changed implementation to use ``cmd_runner`` (https://github.com/ansible-collections/community.general/pull/4776). + - xfconf_info - changed implementation to use ``cmd_runner`` (https://github.com/ansible-collections/community.general/pull/4776). diff --git a/plugins/module_utils/xfconf.py b/plugins/module_utils/xfconf.py new file mode 100644 index 0000000000..4028da3bef --- /dev/null +++ b/plugins/module_utils/xfconf.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# (c) 2022, Alexei Znamensky +# 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 +__metaclass__ = type + +from ansible.module_utils.parsing.convert_bool import boolean +from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt as fmt + + +@fmt.unpack_args +def _values_fmt(values, value_types): + result = [] + for value, value_type in zip(values, value_types): + if value_type == 'bool': + value = boolean(value) + result.extend(['--type', '{0}'.format(value_type), '--set', '{0}'.format(value)]) + return result + + +def xfconf_runner(module, **kwargs): + runner = CmdRunner( + module, + command='xfconf-query', + arg_formats=dict( + channel=fmt.as_opt_val("--channel"), + property=fmt.as_opt_val("--property"), + force_array=fmt.as_bool("--force-array"), + reset=fmt.as_bool("--reset"), + create=fmt.as_bool("--create"), + list_arg=fmt.as_bool("--list"), + values_and_types=fmt.as_func(_values_fmt), + ), + **kwargs + ) + return runner diff --git a/plugins/modules/system/xfconf.py b/plugins/modules/system/xfconf.py index d5ec16df22..c2811e3ccb 100644 --- a/plugins/modules/system/xfconf.py +++ b/plugins/modules/system/xfconf.py @@ -145,31 +145,15 @@ RETURN = ''' sample: '"96" or ["red", "blue", "green"]' ''' -from ansible_collections.community.general.plugins.module_utils.module_helper import ( - CmdStateModuleHelper, ArgFormat -) - - -def fix_bool(value): - vl = value.lower() - return vl if vl in ("true", "false") else value - - -@ArgFormat.stars_deco(1) -def values_fmt(values, value_types): - result = [] - for value, value_type in zip(values, value_types): - if value_type == 'bool': - value = fix_bool(value) - result.extend(['--type', '{0}'.format(value_type), '--set', '{0}'.format(value)]) - return result +from ansible_collections.community.general.plugins.module_utils.module_helper import StateModuleHelper +from ansible_collections.community.general.plugins.module_utils.xfconf import xfconf_runner class XFConfException(Exception): pass -class XFConfProperty(CmdStateModuleHelper): +class XFConfProperty(StateModuleHelper): change_params = 'value', diff_params = 'value', output_params = ('property', 'channel', 'value') @@ -195,27 +179,19 @@ class XFConfProperty(CmdStateModuleHelper): ) default_state = 'present' - command = 'xfconf-query' - command_args_formats = dict( - channel=dict(fmt=('--channel', '{0}'),), - property=dict(fmt=('--property', '{0}'),), - is_array=dict(fmt="--force-array", style=ArgFormat.BOOLEAN), - reset=dict(fmt="--reset", style=ArgFormat.BOOLEAN), - create=dict(fmt="--create", style=ArgFormat.BOOLEAN), - values_and_types=dict(fmt=values_fmt) - ) def update_xfconf_output(self, **kwargs): self.update_vars(meta={"output": True, "fact": True}, **kwargs) def __init_module__(self): - self.does_not = 'Property "{0}" does not exist on channel "{1}".'.format(self.module.params['property'], - self.module.params['channel']) + self.runner = xfconf_runner(self.module) + self.does_not = 'Property "{0}" does not exist on channel "{1}".'.format(self.vars.property, + self.vars.channel) self.vars.set('previous_value', self._get(), fact=True) self.vars.set('type', self.vars.value_type, fact=True) self.vars.meta('value').set(initial_value=self.vars.previous_value) - if self.module.params['disable_facts'] is False: + if self.vars.disable_facts is False: self.do_raise('Returning results as facts has been removed. Stop using disable_facts=false.') def process_command_output(self, rc, out, err): @@ -233,11 +209,12 @@ class XFConfProperty(CmdStateModuleHelper): return result def _get(self): - return self.run_command(params=('channel', 'property')) + with self.runner.context('channel property', output_process=self.process_command_output) as ctx: + return ctx.run() def state_absent(self): - if not self.module.check_mode: - self.run_command(params=('channel', 'property', {'reset': True})) + with self.runner.context('channel property reset', check_mode_skip=True) as ctx: + ctx.run(reset=True) self.vars.value = None def state_present(self): @@ -256,22 +233,14 @@ class XFConfProperty(CmdStateModuleHelper): # or complain if lists' lengths are different raise XFConfException('Number of elements in "value" and "value_type" must be the same') - # fix boolean values - self.vars.value = [fix_bool(v[0]) if v[1] == 'bool' else v[0] for v in zip(self.vars.value, value_type)] - # calculates if it is an array self.vars.is_array = \ bool(self.vars.force_array) or \ isinstance(self.vars.previous_value, list) or \ values_len > 1 - params = ['channel', 'property', {'create': True}] - if self.vars.is_array: - params.append('is_array') - params.append({'values_and_types': (self.vars.value, value_type)}) - - if not self.module.check_mode: - self.run_command(params=params) + with self.runner.context('channel property create force_array values_and_types', check_mode_skip=True) as ctx: + ctx.run(create=True, force_array=self.vars.is_array, values_and_types=(self.vars.value, value_type)) if not self.vars.is_array: self.vars.value = self.vars.value[0] diff --git a/plugins/modules/system/xfconf_info.py b/plugins/modules/system/xfconf_info.py index 766267dd3d..ac9b2033e9 100644 --- a/plugins/modules/system/xfconf_info.py +++ b/plugins/modules/system/xfconf_info.py @@ -74,7 +74,7 @@ RETURN = ''' properties: description: - List of available properties for a specific channel. - - Returned by passed only the I(channel) parameter to the module. + - Returned by passing only the I(channel) parameter to the module. returned: success type: list elements: str @@ -116,14 +116,15 @@ RETURN = ''' - Tmp ''' -from ansible_collections.community.general.plugins.module_utils.module_helper import CmdModuleHelper, ArgFormat +from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper +from ansible_collections.community.general.plugins.module_utils.xfconf import xfconf_runner class XFConfException(Exception): pass -class XFConfInfo(CmdModuleHelper): +class XFConfInfo(ModuleHelper): module = dict( argument_spec=dict( channel=dict(type='str'), @@ -135,16 +136,9 @@ class XFConfInfo(CmdModuleHelper): supports_check_mode=True, ) - command = 'xfconf-query' - command_args_formats = dict( - channel=dict(fmt=['--channel', '{0}']), - property=dict(fmt=['--property', '{0}']), - _list_arg=dict(fmt="--list", style=ArgFormat.BOOLEAN), - ) - check_rc = True - def __init_module__(self): - self.vars.set("_list_arg", False, output=False) + self.runner = xfconf_runner(self.module, check_rc=True) + self.vars.set("list_arg", False, output=False) self.vars.set("is_array", False) def process_command_output(self, rc, out, err): @@ -167,7 +161,7 @@ class XFConfInfo(CmdModuleHelper): return lines def __run__(self): - self.vars._list_arg = not (bool(self.vars.channel) and bool(self.vars.property)) + self.vars.list_arg = not (bool(self.vars.channel) and bool(self.vars.property)) output = 'value' proc = self.process_command_output if self.vars.channel is None: @@ -176,15 +170,15 @@ class XFConfInfo(CmdModuleHelper): elif self.vars.property is None: output = 'properties' proc = self._process_list_properties - result = self.run_command(params=('_list_arg', 'channel', 'property'), process_output=proc) - if not self.vars._list_arg and self.vars.is_array: + with self.runner.context('list_arg channel property', output_process=proc) as ctx: + result = ctx.run(**self.vars) + if not self.vars.list_arg and self.vars.is_array: output = "value_array" self.vars.set(output, result) def main(): - xfconf = XFConfInfo() - xfconf.run() + XFConfInfo.execute() if __name__ == '__main__':