#!/usr/bin/python # Copyright (c) 2017 John Kwiatkoski (@JayKayy) # Copyright (c) 2018 Alexander Bethke (@oolongbrothers) # Copyright (c) 2017 Ansible Project # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later from __future__ import annotations DOCUMENTATION = r""" module: flatpak_remote short_description: Manage flatpak repository remotes description: - Allows users to add or remove flatpak remotes. - The flatpak remotes concept is comparable to what is called repositories in other packaging formats. - Currently, remote addition is only supported using C(flatpakrepo) file URLs. - Existing remotes are not updated. - See the M(community.general.flatpak) module for managing flatpaks. author: - John Kwiatkoski (@JayKayy) - Alexander Bethke (@oolongbrothers) requirements: - flatpak extends_documentation_fragment: - community.general.attributes attributes: check_mode: support: full diff_mode: support: none options: executable: description: - The path to the C(flatpak) executable to use. - By default, this module looks for the C(flatpak) executable on the path. type: str default: flatpak flatpakrepo_url: description: - The URL to the C(flatpakrepo) file representing the repository remote to add. - When used with O(state=present), the flatpak remote specified under the O(flatpakrepo_url) is added using the specified installation O(method). - When used with O(state=absent), this is not required. - Required when O(state=present). type: str method: description: - The installation method to use. - Defines if the C(flatpak) is supposed to be installed globally for the whole V(system) or only for the current V(user). type: str choices: [system, user] default: system name: description: - The desired name for the flatpak remote to be registered under on the managed host. - When used with O(state=present), the remote is added to the managed host under the specified O(name). - When used with O(state=absent) the remote with that name is removed. type: str required: true state: description: - Indicates the desired package state. type: str choices: [absent, present] default: present enabled: description: - Indicates whether this remote is enabled. type: bool default: true version_added: 6.4.0 """ EXAMPLES = r""" - name: Add the Gnome flatpak remote to the system installation community.general.flatpak_remote: name: gnome state: present flatpakrepo_url: https://sdk.gnome.org/gnome-apps.flatpakrepo - name: Add the flathub flatpak repository remote to the user installation community.general.flatpak_remote: name: flathub state: present flatpakrepo_url: https://dl.flathub.org/repo/flathub.flatpakrepo method: user - name: Remove the Gnome flatpak remote from the user installation community.general.flatpak_remote: name: gnome state: absent method: user - name: Remove the flathub remote from the system installation community.general.flatpak_remote: name: flathub state: absent - name: Disable the flathub remote in the system installation community.general.flatpak_remote: name: flathub state: present enabled: false """ RETURN = r""" command: description: The exact flatpak command that was executed. returned: When a flatpak command has been executed type: str sample: "/usr/bin/flatpak remote-add --system flatpak-test https://dl.flathub.org/repo/flathub.flatpakrepo" """ from ansible.module_utils.basic import AnsibleModule def add_remote(module, binary, name, flatpakrepo_url, method): """Add a new remote.""" global result # pylint: disable=global-variable-not-assigned command = [binary, "remote-add", f"--{method}", name, flatpakrepo_url] _flatpak_command(module, module.check_mode, command) result["changed"] = True def remove_remote(module, binary, name, method): """Remove an existing remote.""" global result # pylint: disable=global-variable-not-assigned command = [binary, "remote-delete", f"--{method}", "--force", name] _flatpak_command(module, module.check_mode, command) result["changed"] = True def remote_exists(module, binary, name, method): """Check if the remote exists.""" command = [binary, "remote-list", "--show-disabled", f"--{method}"] # The query operation for the remote needs to be run even in check mode output = _flatpak_command(module, False, command) for line in output.splitlines(): listed_remote = line.split() if len(listed_remote) == 0: continue if listed_remote[0] == name: return True return False def enable_remote(module, binary, name, method): """Enable a remote.""" global result # pylint: disable=global-variable-not-assigned command = [binary, "remote-modify", "--enable", f"--{method}", name] _flatpak_command(module, module.check_mode, command) result["changed"] = True def disable_remote(module, binary, name, method): """Disable a remote.""" global result # pylint: disable=global-variable-not-assigned command = [binary, "remote-modify", "--disable", f"--{method}", name] _flatpak_command(module, module.check_mode, command) result["changed"] = True def remote_enabled(module, binary, name, method): """Check if the remote is enabled.""" command = [binary, "remote-list", "--show-disabled", f"--{method}"] # The query operation for the remote needs to be run even in check mode output = _flatpak_command(module, False, command) for line in output.splitlines(): listed_remote = line.split() if len(listed_remote) == 0: continue if listed_remote[0] == name: return len(listed_remote) == 1 or "disabled" not in listed_remote[1].split(",") return False def _flatpak_command(module, noop, command): global result # pylint: disable=global-variable-not-assigned result["command"] = " ".join(command) if noop: result["rc"] = 0 return "" result["rc"], result["stdout"], result["stderr"] = module.run_command(command, check_rc=True) return result["stdout"] def main(): module = AnsibleModule( argument_spec=dict( name=dict(type="str", required=True), flatpakrepo_url=dict(type="str"), method=dict(type="str", default="system", choices=["user", "system"]), state=dict(type="str", default="present", choices=["absent", "present"]), enabled=dict(type="bool", default=True), executable=dict(type="str", default="flatpak"), ), # This module supports check mode supports_check_mode=True, ) name = module.params["name"] flatpakrepo_url = module.params["flatpakrepo_url"] method = module.params["method"] state = module.params["state"] enabled = module.params["enabled"] executable = module.params["executable"] binary = module.get_bin_path(executable, None) if flatpakrepo_url is None: flatpakrepo_url = "" global result result = dict(changed=False) # If the binary was not found, fail the operation if not binary: module.fail_json(msg=f"Executable '{executable}' was not found on the system.", **result) remote_already_exists = remote_exists(module, binary, name, method) if state == "present" and not remote_already_exists: add_remote(module, binary, name, flatpakrepo_url, method) elif state == "absent" and remote_already_exists: remove_remote(module, binary, name, method) if state == "present": remote_already_enabled = remote_enabled(module, binary, name, method) if enabled and not remote_already_enabled: enable_remote(module, binary, name, method) if not enabled and remote_already_enabled: disable_remote(module, binary, name, method) module.exit_json(**result) if __name__ == "__main__": main()