1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

snap - improved error handling (#3211)

* snap - improved error handling

* added changelog fragment

* removed experiments left overs

* rolled back the smaller list of params for commands other than install
This commit is contained in:
Alexei Znamensky 2021-08-29 07:54:39 +12:00 committed by GitHub
parent 69641d36e1
commit a91eb6ae4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 55 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- snap - improved module error handling, especially for the case when snap server is down (https://github.com/ansible-collections/community.general/issues/2970).

View file

@ -1,6 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright: (c) 2021, Alexei Znamensky (russoz) <russoz@gmail.com>
# Copyright: (c) 2018, Stanislas Lange (angristan) <angristan@pm.me> # Copyright: (c) 2018, Stanislas Lange (angristan) <angristan@pm.me>
# Copyright: (c) 2018, Victor Carceler <vcarceler@iespuigcastellar.xeill.net> # Copyright: (c) 2018, Victor Carceler <vcarceler@iespuigcastellar.xeill.net>
@ -12,17 +13,13 @@ __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = '''
--- ---
module: snap module: snap
short_description: Manages snaps short_description: Manages snaps
description: description:
- "Manages snaps packages." - "Manages snaps packages."
options: options:
name: name:
description: description:
- Name of the snap to install or remove. Can be a list of snaps. - Name of the snaps.
required: true required: true
type: list type: list
elements: str elements: str
@ -117,10 +114,10 @@ from ansible_collections.community.general.plugins.module_utils.module_helper im
__state_map = dict( __state_map = dict(
present='install', present='install',
absent='remove', absent='remove',
info='info', # not public
list='list', # not public
enabled='enable', enabled='enable',
disabled='disable', disabled='disable',
info='info', # not public
list='list', # not public
) )
@ -171,9 +168,6 @@ class Snap(CmdStateModuleHelper):
'\n'.join(results[3]), '\n'.join(results[3]),
] ]
def snap_exists(self, snap_name):
return 0 == self.run_command(params=[{'state': 'info'}, {'name': snap_name}])[0]
def is_snap_installed(self, snap_name): def is_snap_installed(self, snap_name):
return 0 == self.run_command(params=[{'state': 'list'}, {'name': snap_name}])[0] return 0 == self.run_command(params=[{'state': 'list'}, {'name': snap_name}])[0]
@ -188,14 +182,7 @@ class Snap(CmdStateModuleHelper):
notes = match.group('notes') notes = match.group('notes')
return "disabled" not in notes.split(',') return "disabled" not in notes.split(',')
def validate_input_snaps(self):
"""Ensure that all exist."""
for snap_name in self.vars.name:
if not self.snap_exists(snap_name):
raise ModuleHelperException(msg="No snap matching '%s' available." % snap_name)
def state_present(self): def state_present(self):
self.validate_input_snaps() # if snap doesnt exist, it will explode when trying to install
self.vars.meta('classic').set(output=True) self.vars.meta('classic').set(output=True)
self.vars.meta('channel').set(output=True) self.vars.meta('channel').set(output=True)
actionable_snaps = [s for s in self.vars.name if not self.is_snap_installed(s)] actionable_snaps = [s for s in self.vars.name if not self.is_snap_installed(s)]
@ -227,59 +214,32 @@ class Snap(CmdStateModuleHelper):
"error output for more details.".format(cmd=self.vars.cmd) "error output for more details.".format(cmd=self.vars.cmd)
raise ModuleHelperException(msg=msg) raise ModuleHelperException(msg=msg)
def state_absent(self): def _generic_state_action(self, actionable_func, actionable_var, params=None):
self.validate_input_snaps() # if snap doesnt exist, it will be absent by definition actionable_snaps = [s for s in self.vars.name if actionable_func(s)]
actionable_snaps = [s for s in self.vars.name if self.is_snap_installed(s)]
if not actionable_snaps: if not actionable_snaps:
return return
self.changed = True self.changed = True
self.vars.snaps_removed = actionable_snaps self.vars[actionable_var] = actionable_snaps
if self.module.check_mode: if self.module.check_mode:
return return
params = ['classic', 'channel', 'state'] # get base cmd parts if params is None:
params = ['state']
commands = [params + [{'actionable_snaps': actionable_snaps}]] commands = [params + [{'actionable_snaps': actionable_snaps}]]
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands) self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
if rc == 0: if rc == 0:
return return
msg = "Ooops! Snap removal failed while executing '{cmd}', please examine logs and " \ msg = "Ooops! Snap operation failed while executing '{cmd}', please examine logs and " \
"error output for more details.".format(cmd=self.vars.cmd) "error output for more details.".format(cmd=self.vars.cmd)
raise ModuleHelperException(msg=msg) raise ModuleHelperException(msg=msg)
def state_absent(self):
self._generic_state_action(self.is_snap_installed, "snaps_removed", ['classic', 'channel', 'state'])
def state_enabled(self): def state_enabled(self):
self.validate_input_snaps() self._generic_state_action(lambda s: not self.is_snap_enabled(s), "snaps_enabled", ['classic', 'channel', 'state'])
actionable_snaps = [s for s in self.vars.name if self.is_snap_enabled(s) is False]
if not actionable_snaps:
return
self.changed = True
self.vars.snaps_enabled = actionable_snaps
if self.module.check_mode:
return
params = ['classic', 'channel', 'state'] # get base cmd parts
commands = [params + [{'actionable_snaps': actionable_snaps}]]
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
if rc == 0:
return
msg = "Ooops! Snap enabling failed while executing '{cmd}', please examine logs and " \
"error output for more details.".format(cmd=self.vars.cmd)
raise ModuleHelperException(msg=msg)
def state_disabled(self): def state_disabled(self):
self.validate_input_snaps() self._generic_state_action(self.is_snap_enabled, "snaps_disabled", ['classic', 'channel', 'state'])
actionable_snaps = [s for s in self.vars.name if self.is_snap_enabled(s) is True]
if not actionable_snaps:
return
self.changed = True
self.vars.snaps_enabled = actionable_snaps
if self.module.check_mode:
return
params = ['classic', 'channel', 'state'] # get base cmd parts
commands = [params + [{'actionable_snaps': actionable_snaps}]]
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
if rc == 0:
return
msg = "Ooops! Snap disabling failed while executing '{cmd}', please examine logs and " \
"error output for more details.".format(cmd=self.vars.cmd)
raise ModuleHelperException(msg=msg)
def main(): def main():