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

flatpak - allow to add/remove multiple flatpaks at once (#2521) (#2822)

* reviving flatpack PR

* added changelog fragment

* adjusted integration tests per PR

* adjusted examples to use the full name of the module

* Use new local artifacts.

* Re-add StrictVersion import.

* Try to clean up PR.

* ...

* Use original name in installed/not installed list.

* More fixes.

* Work around flatpak bug.

* Fix bug I introduced.

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 3997d5fcc8)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
This commit is contained in:
patchback[bot] 2021-06-17 19:05:05 +02:00 committed by GitHub
parent b653a9a84a
commit a6bffa274c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 220 additions and 38 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- flatpak - allows installing or uninstalling a list of packages (https://github.com/ansible-collections/community.general/pull/2521).

View file

@ -38,7 +38,8 @@ options:
default: system default: system
name: name:
description: description:
- The name of the flatpak to manage. - The name of the flatpak to manage. To operate on several packages this
can accept a list of packages.
- When used with I(state=present), I(name) can be specified as a URL to a - When used with I(state=present), I(name) can be specified as a URL to a
C(flatpakref) file or the unique reverse DNS name that identifies a flatpak. C(flatpakref) file or the unique reverse DNS name that identifies a flatpak.
- Both C(https://) and C(http://) URLs are supported. - Both C(https://) and C(http://) URLs are supported.
@ -50,7 +51,8 @@ options:
installed flatpak based on the name of the flatpakref to remove it. However, there is no installed flatpak based on the name of the flatpakref to remove it. However, there is no
guarantee that the names of the flatpakref file and the reverse DNS name of the installed guarantee that the names of the flatpakref file and the reverse DNS name of the installed
flatpak do match. flatpak do match.
type: str type: list
elements: str
required: true required: true
no_dependencies: no_dependencies:
description: description:
@ -101,10 +103,25 @@ EXAMPLES = r'''
state: present state: present
remote: gnome remote: gnome
- name: Install multiple packages
community.general.flatpak:
name:
- org.gimp.GIMP
- org.inkscape.Inkscape
- org.mozilla.firefox
- name: Remove the gedit flatpak - name: Remove the gedit flatpak
community.general.flatpak: community.general.flatpak:
name: org.gnome.gedit name: org.gnome.gedit
state: absent state: absent
- name: Remove multiple packages
community.general.flatpak:
name:
- org.gimp.GIMP
- org.inkscape.Inkscape
- org.mozilla.firefox
state: absent
''' '''
RETURN = r''' RETURN = r'''
@ -143,47 +160,64 @@ from ansible.module_utils.basic import AnsibleModule
OUTDATED_FLATPAK_VERSION_ERROR_MESSAGE = "Unknown option --columns=application" OUTDATED_FLATPAK_VERSION_ERROR_MESSAGE = "Unknown option --columns=application"
def install_flat(module, binary, remote, name, method, no_dependencies): def install_flat(module, binary, remote, names, method, no_dependencies):
"""Add a new flatpak.""" """Add new flatpaks."""
global result global result
uri_names = []
id_names = []
for name in names:
if name.startswith('http://') or name.startswith('https://'):
uri_names.append(name)
else:
id_names.append(name)
base_command = [binary, "install", "--{0}".format(method)]
flatpak_version = _flatpak_version(module, binary)
if StrictVersion(flatpak_version) < StrictVersion('1.1.3'):
base_command += ["-y"]
else:
base_command += ["--noninteractive"]
if no_dependencies:
base_command += ["--no-deps"]
if uri_names:
command = base_command + uri_names
_flatpak_command(module, module.check_mode, command)
if id_names:
command = base_command + [remote] + id_names
_flatpak_command(module, module.check_mode, command)
result['changed'] = True
def uninstall_flat(module, binary, names, method):
"""Remove existing flatpaks."""
global result
installed_flat_names = [
_match_installed_flat_name(module, binary, name, method)
for name in names
]
command = [binary, "uninstall"]
flatpak_version = _flatpak_version(module, binary) flatpak_version = _flatpak_version(module, binary)
command = [binary, "install", "--{0}".format(method)]
if StrictVersion(flatpak_version) < StrictVersion('1.1.3'): if StrictVersion(flatpak_version) < StrictVersion('1.1.3'):
command += ["-y"] command += ["-y"]
else: else:
command += ["--noninteractive"] command += ["--noninteractive"]
if no_dependencies: command += ["--{0}".format(method)] + installed_flat_names
command += ["--no-deps"]
if name.startswith('http://') or name.startswith('https://'):
command += [name]
else:
command += [remote, name]
_flatpak_command(module, module.check_mode, command) _flatpak_command(module, module.check_mode, command)
result['changed'] = True result['changed'] = True
def uninstall_flat(module, binary, name, method): def flatpak_exists(module, binary, names, method):
"""Remove an existing flatpak.""" """Check if the flatpaks are installed."""
global result
flatpak_version = _flatpak_version(module, binary)
if StrictVersion(flatpak_version) < StrictVersion('1.1.3'):
noninteractive_arg = "-y"
else:
noninteractive_arg = "--noninteractive"
installed_flat_name = _match_installed_flat_name(module, binary, name, method)
command = [binary, "uninstall", "--{0}".format(method), noninteractive_arg, name]
_flatpak_command(module, module.check_mode, command)
result['changed'] = True
def flatpak_exists(module, binary, name, method):
"""Check if the flatpak is installed."""
command = [binary, "list", "--{0}".format(method), "--app"] command = [binary, "list", "--{0}".format(method), "--app"]
output = _flatpak_command(module, False, command) output = _flatpak_command(module, False, command)
name = _parse_flatpak_name(name).lower() installed = []
if name in output.lower(): not_installed = []
return True for name in names:
return False parsed_name = _parse_flatpak_name(name).lower()
if parsed_name in output.lower():
installed.append(name)
else:
not_installed.append(name)
return installed, not_installed
def _match_installed_flat_name(module, binary, name, method): def _match_installed_flat_name(module, binary, name, method):
@ -266,7 +300,7 @@ def main():
# This module supports check mode # This module supports check mode
module = AnsibleModule( module = AnsibleModule(
argument_spec=dict( argument_spec=dict(
name=dict(type='str', required=True), name=dict(type='list', elements='str', required=True),
remote=dict(type='str', default='flathub'), remote=dict(type='str', default='flathub'),
method=dict(type='str', default='system', method=dict(type='str', default='system',
choices=['user', 'system']), choices=['user', 'system']),
@ -295,10 +329,11 @@ def main():
if not binary: if not binary:
module.fail_json(msg="Executable '%s' was not found on the system." % executable, **result) module.fail_json(msg="Executable '%s' was not found on the system." % executable, **result)
if state == 'present' and not flatpak_exists(module, binary, name, method): installed, not_installed = flatpak_exists(module, binary, name, method)
install_flat(module, binary, remote, name, method, no_dependencies) if state == 'present' and not_installed:
elif state == 'absent' and flatpak_exists(module, binary, name, method): install_flat(module, binary, remote, not_installed, method, no_dependencies)
uninstall_flat(module, binary, name, method) elif state == 'absent' and installed:
uninstall_flat(module, binary, installed, method)
module.exit_json(**result) module.exit_json(**result)

View file

@ -36,7 +36,9 @@
- name: Remove (if necessary) flatpak for testing check mode on absent flatpak - name: Remove (if necessary) flatpak for testing check mode on absent flatpak
flatpak: flatpak:
name: com.dummy.App1 name:
- com.dummy.App1
- com.dummy.App3
remote: dummy-remote remote: dummy-remote
state: absent state: absent
no_dependencies: true no_dependencies: true

View file

@ -139,3 +139,146 @@
that: that:
- double_url_removal_result is not changed - double_url_removal_result is not changed
msg: "state=absent with url as name shall not do anything when flatpak is not present" msg: "state=absent with url as name shall not do anything when flatpak is not present"
- name: Make sure flatpak is really gone - {{ method }}
flatpak:
name: com.dummy.App1
state: absent
method: "{{ method }}"
no_dependencies: true
# state=present with list of packages
- name: Test addition with list - {{ method }}
flatpak:
name:
- com.dummy.App1
- http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
remote: dummy-remote
state: present
method: "{{ method }}"
no_dependencies: true
register: addition_result
- name: Verify addition with list test result - {{ method }}
assert:
that:
- addition_result is changed
msg: "state=present shall add flatpak when absent"
- name: Test idempotency of addition with list - {{ method }}
flatpak:
name:
- com.dummy.App1
- http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
remote: dummy-remote
state: present
method: "{{ method }}"
no_dependencies: true
register: double_addition_result
- name: Verify idempotency of addition with list test result - {{ method }}
assert:
that:
- double_addition_result is not changed
msg: "state=present shall not do anything when flatpak is already present"
- name: Test addition with list partially installed - {{ method }}
flatpak:
name:
- com.dummy.App1
- http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
- com.dummy.App3
remote: dummy-remote
state: present
method: "{{ method }}"
no_dependencies: true
register: addition_result
- name: Verify addition with list partially installed test result - {{ method }}
assert:
that:
- addition_result is changed
msg: "state=present shall add flatpak when absent"
- name: Test idempotency of addition with list partially installed - {{ method }}
flatpak:
name:
- com.dummy.App1
- http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
- com.dummy.App3
remote: dummy-remote
state: present
method: "{{ method }}"
no_dependencies: true
register: double_addition_result
- name: Verify idempotency of addition with list partially installed test result - {{ method }}
assert:
that:
- double_addition_result is not changed
msg: "state=present shall not do anything when flatpak is already present"
# state=absent with list of packages
- name: Test removal with list - {{ method }}
flatpak:
name:
- com.dummy.App1
- com.dummy.App2
state: absent
method: "{{ method }}"
register: removal_result
- name: Verify removal with list test result - {{ method }}
assert:
that:
- removal_result is changed
msg: "state=absent shall remove flatpak when present"
- name: Test idempotency of removal with list - {{ method }}
flatpak:
name:
- com.dummy.App1
- com.dummy.App2
state: absent
method: "{{ method }}"
register: double_removal_result
- name: Verify idempotency of removal with list test result - {{ method }}
assert:
that:
- double_removal_result is not changed
msg: "state=absent shall not do anything when flatpak is not present"
- name: Test removal with list partially removed - {{ method }}
flatpak:
name:
- com.dummy.App1
- com.dummy.App2
- com.dummy.App3
state: absent
method: "{{ method }}"
register: removal_result
- name: Verify removal with list partially removed test result - {{ method }}
assert:
that:
- removal_result is changed
msg: "state=absent shall remove flatpak when present"
- name: Test idempotency of removal with list partially removed - {{ method }}
flatpak:
name:
- com.dummy.App1
- com.dummy.App2
- com.dummy.App3
state: absent
method: "{{ method }}"
register: double_removal_result
- name: Verify idempotency of removal with list partially removed test result - {{ method }}
assert:
that:
- double_removal_result is not changed
msg: "state=absent shall not do anything when flatpak is not present"

View file

@ -18,7 +18,7 @@ flatpak install -y --system flathub org.freedesktop.Platform//1.6 org.freedeskto
# Add individual flatpaks # Add individual flatpaks
echo $'#!/bin/sh\necho hello world' > hello.sh echo $'#!/bin/sh\necho hello world' > hello.sh
for NUM in 1 2; do for NUM in 1 2 3; do
flatpak build-init appdir${NUM} com.dummy.App${NUM} org.freedesktop.Sdk org.freedesktop.Platform 1.6; flatpak build-init appdir${NUM} com.dummy.App${NUM} org.freedesktop.Sdk org.freedesktop.Platform 1.6;
flatpak build appdir${NUM} mkdir /app/bin; flatpak build appdir${NUM} mkdir /app/bin;
flatpak build appdir${NUM} install --mode=750 hello.sh /app/bin; flatpak build appdir${NUM} install --mode=750 hello.sh /app/bin;