From 69aea38683bd96eda1e36abdfd9a7332b76441e2 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 23:27:05 +0100 Subject: [PATCH] [PR #9236/2b2872f0 backport][stable-10] Add android sdk module (#9293) Add android sdk module (#9236) * adds simple implementation of adding and removing android sdk packages * adds package update * adds simple installed packages parsing * moves parsing logic to a separate class * adds absent state for sdkmanager packages and setup for tests * adds output for installing and removing packages * removes version from Package object since it is not possible to specify version for a package while using sdkmanager * adds 'latest' state * adds tests * fixes crash when sdkmanager is invoked from python with LC_ALL=C * fixes latest state * adds sdk_root parameter * adds channel parameter * simplifies regexps, removes unused named groups * minor refactoring of sdkmanager parsing * adds java dependency variable for different distributions * adds RETURN documentation * adds check for nonexisting package * adds check for non-accepted licenses * removes excessive methods from sdkmanager * removes unused 'update' module parameter, packages may be updated using 'latest' state * minor refactoring * adds EXAMPLES doc section * adds DOCUMENTATION section and license headers * fixes formatting issues * removes diff_params * adds maintainer * fixes sanity check issues in sdkmanager * adds java dependency for macos and moves some tests to a separate FreeBSD configuration * fixes dependencies setup for OSX * fixes dependencies setup for OSX (2) * fixes dependencies setup for OSX (3) * Apply minor suggestions from code review Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> * applies code review suggestions * changes force_lang from C.UTF-8 to auto in sdkmanager (as per discussion https://github.com/ansible-collections/community.general/pull/9236#discussion_r1881114326) * Revert "changes force_lang from C.UTF-8 to auto in sdkmanager (as per discussion https://github.com/ansible-collections/community.general/pull/9236#discussion_r1881114326)" This reverts commit 619f28dd58db005e466a19b98604221da82b7ecc. * fixes some more comments from review * minor sanity issue fix * uses the 'changed' test instead of checking the 'changed' attribute * adds 'accept_licenses' parameter. Installation is now performed independently for each package specified. * removes "Accept licenses" task from examples * fixes docs sanity issues * applies minor suggestions from code review * fixes regexps. The previous version didn't match versions like "32.1.0 rc1". Also, this allows to simplify the parsing logic as there is no need to skip table headers anymore. * renamed sdkmanager.py to android_sdkmanager.py * applies minor suggestions from code review Co-authored-by: Felix Fontein * updates BOTMETA * reordered BOTMETA --------- Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> Co-authored-by: Felix Fontein (cherry picked from commit 2b2872f0efe7f2fcf2c8c0e2b40764d940c79dff) Co-authored-by: Stanislav Shamilov --- .github/BOTMETA.yml | 4 + plugins/module_utils/android_sdkmanager.py | 148 ++++++++++++ plugins/modules/android_sdk.py | 213 ++++++++++++++++++ tests/integration/targets/android_sdk/aliases | 7 + .../targets/android_sdk/meta/main.yml | 8 + .../android_sdk/tasks/default-tests.yml | 92 ++++++++ .../android_sdk/tasks/freebsd-tests.yml | 72 ++++++ .../targets/android_sdk/tasks/main.yml | 31 +++ .../targets/android_sdk/tasks/setup.yml | 86 +++++++ .../targets/android_sdk/vars/Alpine.yml | 6 + .../targets/android_sdk/vars/Archlinux.yml | 6 + .../targets/android_sdk/vars/Darwin.yml | 6 + .../targets/android_sdk/vars/Debian.yml | 6 + .../targets/android_sdk/vars/FreeBSD.yml | 6 + .../targets/android_sdk/vars/RedHat.yml | 6 + .../targets/android_sdk/vars/Suse.yml | 6 + .../targets/android_sdk/vars/main.yml | 8 + 17 files changed, 711 insertions(+) create mode 100644 plugins/module_utils/android_sdkmanager.py create mode 100644 plugins/modules/android_sdk.py create mode 100644 tests/integration/targets/android_sdk/aliases create mode 100644 tests/integration/targets/android_sdk/meta/main.yml create mode 100644 tests/integration/targets/android_sdk/tasks/default-tests.yml create mode 100644 tests/integration/targets/android_sdk/tasks/freebsd-tests.yml create mode 100644 tests/integration/targets/android_sdk/tasks/main.yml create mode 100644 tests/integration/targets/android_sdk/tasks/setup.yml create mode 100644 tests/integration/targets/android_sdk/vars/Alpine.yml create mode 100644 tests/integration/targets/android_sdk/vars/Archlinux.yml create mode 100644 tests/integration/targets/android_sdk/vars/Darwin.yml create mode 100644 tests/integration/targets/android_sdk/vars/Debian.yml create mode 100644 tests/integration/targets/android_sdk/vars/FreeBSD.yml create mode 100644 tests/integration/targets/android_sdk/vars/RedHat.yml create mode 100644 tests/integration/targets/android_sdk/vars/Suse.yml create mode 100644 tests/integration/targets/android_sdk/vars/main.yml diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 6896106906..2be4619ecb 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -309,6 +309,8 @@ files: maintainers: delineaKrehl tylerezimmerman $module_utils/: labels: module_utils + $module_utils/android_sdkmanager.py: + maintainers: shamilovstas $module_utils/btrfs.py: maintainers: gnfzdz $module_utils/cmd_runner_fmt.py: @@ -420,6 +422,8 @@ files: ignore: DavidWittman jiuka labels: alternatives maintainers: mulby + $modules/android_sdk.py: + maintainers: shamilovstas $modules/ansible_galaxy_install.py: maintainers: russoz $modules/apache2_mod_proxy.py: diff --git a/plugins/module_utils/android_sdkmanager.py b/plugins/module_utils/android_sdkmanager.py new file mode 100644 index 0000000000..9cbb2df6b0 --- /dev/null +++ b/plugins/module_utils/android_sdkmanager.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2024, Stanislav Shamilov +# 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 absolute_import, division, print_function + +__metaclass__ = type + +import re + +from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt + +__state_map = { + "present": "--install", + "absent": "--uninstall" +} + +# sdkmanager --help 2>&1 | grep -A 2 -- --channel +__channel_map = { + "stable": 0, + "beta": 1, + "dev": 2, + "canary": 3 +} + + +def __map_channel(channel_name): + if channel_name not in __channel_map: + raise ValueError("Unknown channel name '%s'" % channel_name) + return __channel_map[channel_name] + + +def sdkmanager_runner(module, **kwargs): + return CmdRunner( + module, + command='sdkmanager', + arg_formats=dict( + state=cmd_runner_fmt.as_map(__state_map), + name=cmd_runner_fmt.as_list(), + installed=cmd_runner_fmt.as_fixed("--list_installed"), + list=cmd_runner_fmt.as_fixed('--list'), + newer=cmd_runner_fmt.as_fixed("--newer"), + sdk_root=cmd_runner_fmt.as_opt_eq_val("--sdk_root"), + channel=cmd_runner_fmt.as_func(lambda x: ["{0}={1}".format("--channel", __map_channel(x))]) + ), + force_lang="C.UTF-8", # Without this, sdkmanager binary crashes + **kwargs + ) + + +class Package: + def __init__(self, name): + self.name = name + + def __hash__(self): + return hash(self.name) + + def __ne__(self, other): + if not isinstance(other, Package): + return True + return self.name != other.name + + def __eq__(self, other): + if not isinstance(other, Package): + return False + + return self.name == other.name + + +class SdkManagerException(Exception): + pass + + +class AndroidSdkManager(object): + _RE_INSTALLED_PACKAGES_HEADER = re.compile(r'^Installed packages:$') + _RE_UPDATABLE_PACKAGES_HEADER = re.compile(r'^Available Updates:$') + + # Example: ' platform-tools | 27.0.0 | Android SDK Platform-Tools 27 | platform-tools ' + _RE_INSTALLED_PACKAGE = re.compile(r'^\s*(?P\S+)\s*\|\s*[0-9][^|]*\b\s*\|\s*.+\s*\|\s*(\S+)\s*$') + + # Example: ' platform-tools | 27.0.0 | 35.0.2' + _RE_UPDATABLE_PACKAGE = re.compile(r'^\s*(?P\S+)\s*\|\s*[0-9][^|]*\b\s*\|\s*[0-9].*\b\s*$') + + _RE_UNKNOWN_PACKAGE = re.compile(r'^Warning: Failed to find package \'(?P\S+)\'\s*$') + _RE_ACCEPT_LICENSE = re.compile(r'^The following packages can not be installed since their licenses or those of ' + r'the packages they depend on were not accepted') + + def __init__(self, module): + self.runner = sdkmanager_runner(module) + + def get_installed_packages(self): + with self.runner('installed sdk_root channel') as ctx: + rc, stdout, stderr = ctx.run() + return self._parse_packages(stdout, self._RE_INSTALLED_PACKAGES_HEADER, self._RE_INSTALLED_PACKAGE) + + def get_updatable_packages(self): + with self.runner('list newer sdk_root channel') as ctx: + rc, stdout, stderr = ctx.run() + return self._parse_packages(stdout, self._RE_UPDATABLE_PACKAGES_HEADER, self._RE_UPDATABLE_PACKAGE) + + def apply_packages_changes(self, packages, accept_licenses=False): + """ Install or delete packages, depending on the `module.vars.state` parameter """ + if len(packages) == 0: + return 0, '', '' + + if accept_licenses: + license_prompt_answer = 'y' + else: + license_prompt_answer = 'N' + for package in packages: + with self.runner('state name sdk_root channel', data=license_prompt_answer) as ctx: + rc, stdout, stderr = ctx.run(name=package.name) + + for line in stdout.splitlines(): + if self._RE_ACCEPT_LICENSE.match(line): + raise SdkManagerException("Licenses for some packages were not accepted") + + if rc != 0: + self._try_parse_stderr(stderr) + return rc, stdout, stderr + return 0, '', '' + + def _try_parse_stderr(self, stderr): + data = stderr.splitlines() + for line in data: + unknown_package_regex = self._RE_UNKNOWN_PACKAGE.match(line) + if unknown_package_regex: + package = unknown_package_regex.group('package') + raise SdkManagerException("Unknown package %s" % package) + + @staticmethod + def _parse_packages(stdout, header_regexp, row_regexp): + data = stdout.splitlines() + + section_found = False + packages = set() + + for line in data: + if not section_found: + section_found = header_regexp.match(line) + continue + else: + p = row_regexp.match(line) + if p: + packages.add(Package(p.group('name'))) + return packages diff --git a/plugins/modules/android_sdk.py b/plugins/modules/android_sdk.py new file mode 100644 index 0000000000..9851a84fc2 --- /dev/null +++ b/plugins/modules/android_sdk.py @@ -0,0 +1,213 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2024, Stanislav Shamilov +# 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 absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: android_sdk +short_description: Manages Android SDK packages +description: + - Manages Android SDK packages. + - Allows installation from different channels (stable, beta, dev, canary). + - Allows installation of packages to a non-default SDK root directory. +author: Stanislav Shamilov (@shamilovstas) +extends_documentation_fragment: + - community.general.attributes +attributes: + check_mode: + support: full + diff_mode: + support: none +version_added: 10.2.0 +options: + accept_licenses: + description: + - If this is set to B(true), the module will try to accept license prompts generated by C(sdkmanager) during + package installation. Otherwise, every license prompt will be rejected. + type: bool + default: false + name: + description: + - A name of an Android SDK package (for instance, V(build-tools;34.0.0)). + aliases: ['package', 'pkg'] + type: list + elements: str + state: + description: + - Indicates the desired package(s) state. + - V(present) ensures that package(s) is/are present. + - V(absent) ensures that package(s) is/are absent. + - V(latest) ensures that package(s) is/are installed and updated to the latest version(s). + choices: ['present', 'absent', 'latest'] + default: present + type: str + sdk_root: + description: + - Provides path for an alternative directory to install Android SDK packages to. By default, all packages + are installed to the directory where C(sdkmanager) is installed. + type: path + channel: + description: + - Indicates what channel must C(sdkmanager) use for installation of packages. + choices: ['stable', 'beta', 'dev', 'canary'] + default: stable + type: str +requirements: + - C(java) >= 17 + - C(sdkmanager) Command line tool for installing Android SDK packages. +notes: + - For some of the packages installed by C(sdkmanager) is it necessary to accept licenses. Usually it is done through + command line prompt in a form of a Y/N question when a licensed package is requested to be installed. If there are + several packages requested for installation and at least two of them belong to different licenses, the C(sdkmanager) + tool will prompt for these licenses in a loop. + In order to install packages, the module must be able to answer these license prompts. Currently, it is only + possible to answer one license prompt at a time, meaning that instead of installing multiple packages as a single + invocation of the C(sdkmanager --install) command, it will be done by executing the command independently for each + package. This makes sure that at most only one license prompt will need to be answered. + At the time of writing this module, a C(sdkmanager)'s package may belong to at most one license type that needs to + be accepted. However, if this is changes in the future, the module may hang as there might be more prompts generated + by the C(sdkmanager) tool which the module will not be able to answer. If this is the case, file an issue and in the + meantime, consider accepting all the licenses in advance, as it is described in the C(sdkmanager) + L(documentation,https://developer.android.com/tools/sdkmanager#accept-licenses), for instance, using the + M(ansible.builtin.command) module. +seealso: + - name: sdkmanager tool documentation + description: Detailed information of how to install and use sdkmanager command line tool. + link: https://developer.android.com/tools/sdkmanager +''' + +EXAMPLES = r''' +- name: Install build-tools;34.0.0 + community.general.android_sdk: + name: build-tools;34.0.0 + accept_licenses: true + state: present + +- name: Install build-tools;34.0.0 and platform-tools + community.general.android_sdk: + name: + - build-tools;34.0.0 + - platform-tools + accept_licenses: true + state: present + +- name: Delete build-tools;34.0.0 + community.general.android_sdk: + name: build-tools;34.0.0 + state: absent + +- name: Install platform-tools or update if installed + community.general.android_sdk: + name: platform-tools + accept_licenses: true + state: latest + +- name: Install build-tools;34.0.0 to a different SDK root + community.general.android_sdk: + name: build-tools;34.0.0 + accept_licenses: true + state: present + sdk_root: "/path/to/new/root" + +- name: Install a package from another channel + community.general.android_sdk: + name: some-package-present-in-canary-channel + accept_licenses: true + state: present + channel: canary +''' + +RETURN = r''' +installed: + description: a list of packages that have been installed + returned: when packages have changed + type: list + sample: ['build-tools;34.0.0', 'platform-tools'] + +removed: + description: a list of packages that have been removed + returned: when packages have changed + type: list + sample: ['build-tools;34.0.0', 'platform-tools'] +''' + +from ansible_collections.community.general.plugins.module_utils.mh.module_helper import StateModuleHelper +from ansible_collections.community.general.plugins.module_utils.android_sdkmanager import Package, AndroidSdkManager + + +class AndroidSdk(StateModuleHelper): + module = dict( + argument_spec=dict( + state=dict(type='str', default='present', choices=['present', 'absent', 'latest']), + package=dict(type='list', elements='str', aliases=['pkg', 'name']), + sdk_root=dict(type='path'), + channel=dict(type='str', default='stable', choices=['stable', 'beta', 'dev', 'canary']), + accept_licenses=dict(type='bool', default=False) + ), + supports_check_mode=True + ) + use_old_vardict = False + + def __init_module__(self): + self.sdkmanager = AndroidSdkManager(self.module) + self.vars.set('installed', [], change=True) + self.vars.set('removed', [], change=True) + + def _parse_packages(self): + arg_pkgs = set(self.vars.package) + if len(arg_pkgs) < len(self.vars.package): + self.do_raise("Packages may not repeat") + return set([Package(p) for p in arg_pkgs]) + + def state_present(self): + packages = self._parse_packages() + installed = self.sdkmanager.get_installed_packages() + pending_installation = packages.difference(installed) + + self.vars.installed = AndroidSdk._map_packages_to_names(pending_installation) + if not self.check_mode: + rc, stdout, stderr = self.sdkmanager.apply_packages_changes(pending_installation, self.vars.accept_licenses) + if rc != 0: + self.do_raise("Could not install packages: %s" % stderr) + + def state_absent(self): + packages = self._parse_packages() + installed = self.sdkmanager.get_installed_packages() + to_be_deleted = packages.intersection(installed) + self.vars.removed = AndroidSdk._map_packages_to_names(to_be_deleted) + if not self.check_mode: + rc, stdout, stderr = self.sdkmanager.apply_packages_changes(to_be_deleted) + if rc != 0: + self.do_raise("Could not uninstall packages: %s" % stderr) + + def state_latest(self): + packages = self._parse_packages() + installed = self.sdkmanager.get_installed_packages() + updatable = self.sdkmanager.get_updatable_packages() + not_installed = packages.difference(installed) + to_be_installed = not_installed.union(updatable) + self.vars.installed = AndroidSdk._map_packages_to_names(to_be_installed) + + if not self.check_mode: + rc, stdout, stderr = self.sdkmanager.apply_packages_changes(to_be_installed, self.vars.accept_licenses) + if rc != 0: + self.do_raise("Could not install packages: %s" % stderr) + + @staticmethod + def _map_packages_to_names(packages): + return [x.name for x in packages] + + +def main(): + AndroidSdk.execute() + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/android_sdk/aliases b/tests/integration/targets/android_sdk/aliases new file mode 100644 index 0000000000..bb79889366 --- /dev/null +++ b/tests/integration/targets/android_sdk/aliases @@ -0,0 +1,7 @@ +# Copyright (c) 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 + +azp/posix/3 +destructive +needs/root \ No newline at end of file diff --git a/tests/integration/targets/android_sdk/meta/main.yml b/tests/integration/targets/android_sdk/meta/main.yml new file mode 100644 index 0000000000..d7c152feeb --- /dev/null +++ b/tests/integration/targets/android_sdk/meta/main.yml @@ -0,0 +1,8 @@ +--- +# Copyright (c) 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 + +dependencies: + - setup_pkg_mgr + - setup_remote_tmp_dir \ No newline at end of file diff --git a/tests/integration/targets/android_sdk/tasks/default-tests.yml b/tests/integration/targets/android_sdk/tasks/default-tests.yml new file mode 100644 index 0000000000..b8cb6df54d --- /dev/null +++ b/tests/integration/targets/android_sdk/tasks/default-tests.yml @@ -0,0 +1,92 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +# Copyright (c) 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 + +- name: Install build-tools;34.0.0 + android_sdk: + accept_licenses: true + name: build-tools;34.0.0 + state: present + register: build_tools_installed + +- name: Install build-tools;34.0.0 second time + android_sdk: + name: build-tools;34.0.0 + state: present + register: build_tools_installed2 + +- name: Stat build-tools + stat: + path: "{{ android_sdk_location }}/build-tools/34.0.0" + register: build_tools_34_0_0 + +- name: Delete build-tools;34.0.0 + android_sdk: + name: build-tools;34.0.0 + state: absent + register: build_tools_deleted + +- name: Delete build-tools;34.0.0 second time + android_sdk: + name: build-tools;34.0.0 + state: absent + register: build_tools_deleted2 + +- name: Download old platform-tools + unarchive: + src: https://dl.google.com/android/repository/platform-tools_r27.0.0-linux.zip + remote_src: true + dest: "{{ android_sdk_location }}" + +- name: Try installing platform-tools from sdkmanager + android_sdk: + name: platform-tools + accept_licenses: true + state: present + register: platform_tools_present + +- name: Install (update) platform-tools + android_sdk: + name: platform-tools + state: latest + register: platform_tools_updated + +- name: Install a package to a new root + android_sdk: + name: build-tools;34.0.0 + accept_licenses: true + state: present + sdk_root: "{{ remote_tmp_dir }}" + register: new_root_package + +- name: Check package is installed + stat: + path: "{{ remote_tmp_dir }}/build-tools/34.0.0" + register: new_root_package_stat + +- name: Install a package from canary channel + android_sdk: + name: build-tools;33.0.0 + state: present + channel: canary + register: package_canary + +- name: Run tests + assert: + that: + - build_tools_34_0_0.stat.exists + - build_tools_installed is changed + - build_tools_installed2 is not changed + - build_tools_deleted is changed + - build_tools_deleted2 is not changed + - platform_tools_present is not changed + - platform_tools_updated is changed + - new_root_package is changed + - new_root_package_stat.stat.exists + - package_canary is changed \ No newline at end of file diff --git a/tests/integration/targets/android_sdk/tasks/freebsd-tests.yml b/tests/integration/targets/android_sdk/tasks/freebsd-tests.yml new file mode 100644 index 0000000000..f1886f245d --- /dev/null +++ b/tests/integration/targets/android_sdk/tasks/freebsd-tests.yml @@ -0,0 +1,72 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +# Copyright (c) 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 + +- name: Install sources;android-26 (FreeBSD) + android_sdk: + name: sources;android-26 + accept_licenses: true + state: present + register: sources_android_26_installed + +- name: Install sources;android-26 (FreeBSD) + android_sdk: + name: sources;android-26 + state: present + register: sources_android_26_installed2 + +- name: Stat build-tools (FreeBSD) + stat: + path: "{{ android_sdk_location }}/sources/android-26" + register: sources_android_26 + +- name: Delete sources;android-26 (FreeBSD) + android_sdk: + name: sources;android-26 + state: absent + register: sources_android_26_deleted + +- name: Delete sources;android-26 second time (FreeBSD) + android_sdk: + name: sources;android-26 + state: absent + register: sources_android_26_deleted2 + +- name: Install a package to a new root (FreeBSD) + android_sdk: + name: sources;android-26 + accept_licenses: true + state: present + sdk_root: "{{ remote_tmp_dir }}" + register: new_root_package + +- name: Check package is installed (FreeBSD) + stat: + path: "{{ remote_tmp_dir }}/sources/android-26" + register: new_root_package_stat + +- name: Install a package from canary channel (FreeBSD) + android_sdk: + name: sources;android-26 + accept_licenses: true + state: present + channel: canary + register: package_canary + +- name: Run tests (FreeBSD) + assert: + that: + - sources_android_26.stat.exists + - sources_android_26_installed is changed + - sources_android_26_installed2 is not changed + - sources_android_26_deleted is changed + - sources_android_26_deleted2 is not changed + - new_root_package is changed + - new_root_package_stat.stat.exists + - package_canary is changed diff --git a/tests/integration/targets/android_sdk/tasks/main.yml b/tests/integration/targets/android_sdk/tasks/main.yml new file mode 100644 index 0000000000..46cf3192e1 --- /dev/null +++ b/tests/integration/targets/android_sdk/tasks/main.yml @@ -0,0 +1,31 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +# Copyright (c) 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 + +# java >= 17 is not available in RHEL and CentOS7 repos, which is required for sdkmanager to run +- name: Bail out if not supported + when: + - "ansible_os_family == 'RedHat' and ansible_distribution_version is version('8.0', '<')" + ansible.builtin.meta: end_play + +- name: Run android_sdk tests + environment: + PATH: '{{ ansible_env.PATH }}:{{ android_sdk_location }}/cmdline-tools/latest/bin' + block: + - import_tasks: setup.yml + + - name: Run default tests + import_tasks: default-tests.yml + when: ansible_os_family != 'FreeBSD' + + # Most of the important Android SDK packages are not available on FreeBSD (like, build-tools, platform-tools and so on), + # but at least some of the functionality can be tested (like, downloading sources) + - name: Run FreeBSD tests + import_tasks: freebsd-tests.yml + when: ansible_os_family == 'FreeBSD' diff --git a/tests/integration/targets/android_sdk/tasks/setup.yml b/tests/integration/targets/android_sdk/tasks/setup.yml new file mode 100644 index 0000000000..ff2e3eb3cf --- /dev/null +++ b/tests/integration/targets/android_sdk/tasks/setup.yml @@ -0,0 +1,86 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +# Copyright (c) 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 + +- name: Include OS-specific variables + include_vars: '{{ ansible_os_family }}.yml' + +- name: Install dependencies + become: true + package: + name: + - "{{ openjdk_pkg }}" + - unzip + state: present + when: ansible_os_family != 'Darwin' + +- name: Install dependencies (OSX) + block: + - name: Find brew binary + command: which brew + register: brew_which + - name: Get owner of brew binary + stat: + path: "{{ brew_which.stdout }}" + register: brew_stat + - name: "Install package" + homebrew: + name: + - "{{ openjdk_pkg }}" + - unzip + state: present + update_homebrew: false + become: true + become_user: "{{ brew_stat.stat.pw_name }}" + environment: + HOMEBREW_NO_AUTO_UPDATE: "True" + - name: Symlink java + become: true + file: + src: "/usr/local/opt/openjdk@17/libexec/openjdk.jdk" + dest: "/Library/Java/JavaVirtualMachines/openjdk-17.jdk" + state: link + when: + - ansible_os_family == 'Darwin' + +- name: Create Android SDK directory + file: + path: "{{ android_sdk_location }}" + state: directory + +- name: Check that sdkmanager is installed + stat: + path: "{{ android_sdk_location }}/cmdline-tools/latest/bin/sdkmanager" + register: sdkmanager_installed + +- name: Install Android command line tools + when: not sdkmanager_installed.stat.exists + block: + - name: Create Android SDK dir structure + file: + path: "{{ item.path }}" + state: "{{ item.state }}" + with_items: + - { path: "{{ android_cmdline_temp_dir }}", state: "directory" } + - { path: "{{ android_sdk_location }}/cmdline-tools/latest", state: "directory" } + + - name: Download Android command line tools + unarchive: + src: "{{ commandline_tools_link }}" + dest: "{{ android_cmdline_temp_dir }}" + remote_src: yes + creates: "{{ android_cmdline_temp_dir }}/cmdline-tools" + when: not sdkmanager_installed.stat.exists + + + - name: Fix directory structure + copy: + src: "{{ android_cmdline_temp_dir }}/cmdline-tools/" + dest: "{{ android_sdk_location }}/cmdline-tools/latest" + remote_src: yes diff --git a/tests/integration/targets/android_sdk/vars/Alpine.yml b/tests/integration/targets/android_sdk/vars/Alpine.yml new file mode 100644 index 0000000000..593925f043 --- /dev/null +++ b/tests/integration/targets/android_sdk/vars/Alpine.yml @@ -0,0 +1,6 @@ +--- +# Copyright (c) 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 + +openjdk_pkg: openjdk17-jre-headless diff --git a/tests/integration/targets/android_sdk/vars/Archlinux.yml b/tests/integration/targets/android_sdk/vars/Archlinux.yml new file mode 100644 index 0000000000..ff46870671 --- /dev/null +++ b/tests/integration/targets/android_sdk/vars/Archlinux.yml @@ -0,0 +1,6 @@ +--- +# Copyright (c) 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 + +openjdk_pkg: jre17-openjdk-headless diff --git a/tests/integration/targets/android_sdk/vars/Darwin.yml b/tests/integration/targets/android_sdk/vars/Darwin.yml new file mode 100644 index 0000000000..696bf39a75 --- /dev/null +++ b/tests/integration/targets/android_sdk/vars/Darwin.yml @@ -0,0 +1,6 @@ +--- +# Copyright (c) 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 + +openjdk_pkg: openjdk@17 diff --git a/tests/integration/targets/android_sdk/vars/Debian.yml b/tests/integration/targets/android_sdk/vars/Debian.yml new file mode 100644 index 0000000000..ddcfaaf1e3 --- /dev/null +++ b/tests/integration/targets/android_sdk/vars/Debian.yml @@ -0,0 +1,6 @@ +--- +# Copyright (c) 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 + +openjdk_pkg: openjdk-17-jre-headless diff --git a/tests/integration/targets/android_sdk/vars/FreeBSD.yml b/tests/integration/targets/android_sdk/vars/FreeBSD.yml new file mode 100644 index 0000000000..61c1858423 --- /dev/null +++ b/tests/integration/targets/android_sdk/vars/FreeBSD.yml @@ -0,0 +1,6 @@ +--- +# Copyright (c) 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 + +openjdk_pkg: openjdk17-jre diff --git a/tests/integration/targets/android_sdk/vars/RedHat.yml b/tests/integration/targets/android_sdk/vars/RedHat.yml new file mode 100644 index 0000000000..40f44bd773 --- /dev/null +++ b/tests/integration/targets/android_sdk/vars/RedHat.yml @@ -0,0 +1,6 @@ +--- +# Copyright (c) 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 + +openjdk_pkg: java-17-openjdk-headless diff --git a/tests/integration/targets/android_sdk/vars/Suse.yml b/tests/integration/targets/android_sdk/vars/Suse.yml new file mode 100644 index 0000000000..40f44bd773 --- /dev/null +++ b/tests/integration/targets/android_sdk/vars/Suse.yml @@ -0,0 +1,6 @@ +--- +# Copyright (c) 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 + +openjdk_pkg: java-17-openjdk-headless diff --git a/tests/integration/targets/android_sdk/vars/main.yml b/tests/integration/targets/android_sdk/vars/main.yml new file mode 100644 index 0000000000..9ba619a6d5 --- /dev/null +++ b/tests/integration/targets/android_sdk/vars/main.yml @@ -0,0 +1,8 @@ +--- +# Copyright (c) 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 + +android_cmdline_temp_dir: "/tmp/cmdlinetools" +android_sdk_location: "/tmp/androidsdk" +commandline_tools_link: https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip