diff --git a/.config/ansible-lint.yml b/.config/ansible-lint.yml new file mode 100644 index 0000000..e807dd1 --- /dev/null +++ b/.config/ansible-lint.yml @@ -0,0 +1,3 @@ +--- +skip_list: + - 'name[template]' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aa89421..bb3428d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,44 +1,5 @@ --- jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: install python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: install task - uses: arduino/setup-task@v1 - with: - repo-token: ${{ github.token }} - - name: task ver - run: task --version - - name: download task mono - uses: actions/checkout@v3 - with: - path: taskmono - ref: develop - repository: andrewrothstein/tasks - - name: 'task #ftw' - run: task -t taskmono/ansible-test-role.yml "targetuser=${{ github.actor }}" - "targetpwd=${{ github.token }}" "alltags=${{ matrix.os }}" - strategy: - fail-fast: false - matrix: - os: - - archlinux_latest - - debian_bookworm - - debian_bullseye - - fedora_37 - - fedora_38 - - rockylinux_8 - - rockylinux_9 - - ubuntu_bionic - - ubuntu_focal - - ubuntu_jammy - python-version: - - '3.11' -name: dcb -'on': -- push + bake-ansible-images-v1: + uses: andrewrothstein/.github/.github/workflows/bake-ansible-images-v1.yml@develop +'on': push diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 0000000..0c01e2b --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,3 @@ +--- +rules: + line-length: disable diff --git a/dcb-os.yml b/dcb-os.yml deleted file mode 100644 index 1c362a7..0000000 --- a/dcb-os.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- archlinux_latest -- debian_bookworm -- debian_bullseye -- fedora_37 -- fedora_38 -- rockylinux_8 -- rockylinux_9 -- ubuntu_bionic -- ubuntu_focal -- ubuntu_jammy diff --git a/subrepos/udst.ansible-conda/LICENSE.txt b/library/LICENSE.txt similarity index 100% rename from subrepos/udst.ansible-conda/LICENSE.txt rename to library/LICENSE.txt diff --git a/library/conda.py b/library/conda.py deleted file mode 120000 index 6027eb2..0000000 --- a/library/conda.py +++ /dev/null @@ -1 +0,0 @@ -../subrepos/udst.ansible-conda/conda.py \ No newline at end of file diff --git a/library/conda.py b/library/conda.py new file mode 100755 index 0000000..38d2538 --- /dev/null +++ b/library/conda.py @@ -0,0 +1,373 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +DOCUMENTATION = """ +--- +module: conda +short_description: Manage Python libraries via conda +description: + > + Manage Python libraries via conda. + Can install, update, and remove packages. +author: + - Synthicity + - Colin Nolan (@colin-nolan) +notes: + > + Requires conda to already be installed. +options: + name: + description: The name of a Python package to install. + required: true + version: + description: The specific version of a package to install. + required: false + state: + description: State in which to leave the Python package. "present" will install a package of the specified version + if it is not installed (will not upgrade to latest if version is unspecified - will only install + latest); "latest" will both install and subsequently upgrade a package to the latest version on each + run; "absent" will uninstall the package if installed. + required: false + default: present + choices: [ "present", "absent", "latest" ] + channels: + description: Extra channels to use when installing packages. + required: false + executable: + description: Full path to the conda executable. + required: false + extra_args: + description: Extra arguments passed to conda. + required: false +""" + +EXAMPLES = """ +- name: install numpy via conda + conda: + name: numpy + state: latest + +- name: install scipy 0.14 via conda + conda: + name: scipy + version: "0.14" + +- name: remove matplotlib from conda + conda: + name: matplotlib + state: absent +""" + +RETURN = """ +output: + description: JSON output from Conda + returned: `changed == True` + type: dict +stderr: + description: stderr content written by Conda + returned: `changed == True` + type: str +""" + + +from shutil import which +import os.path +import json +from ansible.module_utils.basic import AnsibleModule + + +def run_package_operation(conda, name, version, state, dry_run, command_runner, on_failure, on_success): + """ + Runs Conda package operation. + + This method is intentionally decoupled from `AnsibleModule` to allow it to be easily tested in isolation. + :param conda: location of the Conda executable + :param name: name of the package of interest + :param version: version of the package (`None` for latest) + :param state: state the package should be in + :param dry_run: will "pretend" to make changes only if `True` + :param command_runner: method that executes a given Conda command (given as list of string arguments), which returns + JSON and returns a tuple where the first argument is the outputted JSON and the second is anything written to stderr + :param on_failure: method that takes any kwargs to be called on failure + :param on_success: method that takes any kwargs to be called on success + """ + correct_version_installed = check_package_installed(command_runner, conda, name, version) + + # TODO: State should be an "enum" (or whatever the Py2.7 equivalent is) + if not correct_version_installed and state != 'absent': + try: + output, stderr = install_package(command_runner, conda, name, version, dry_run=dry_run) + on_success(changed=True, output=output, stderr=stderr) + except CondaPackageNotFoundError: + on_failure(msg='Conda package "%s" not found' % (get_install_target(name, version, ))) + + elif state == 'absent': + try: + output, stderr = uninstall_package(command_runner, conda, name, dry_run=dry_run) + on_success(changed=True, output=output, stderr=stderr) + except CondaPackageNotFoundError: + on_success(changed=False) + + else: + on_success(changed=False) + + +def check_package_installed(command_runner, conda, name, version): + """ + Check whether a package with the given name and version is installed. + :param command_runner: method that executes a given Conda command (given as list of string arguments), which returns + JSON and returns a tuple where the first argument is the outputted JSON and the second is anything written to stderr + :param name: the name of the package to check if installed + :param version: the version of the package to check if installed (`None` if check for latest) + :return: `True` if a package with the given name and version is installed + :raises CondaUnexpectedOutputError: if the JSON returned by Conda was unexpected + """ + output, stderr = run_conda_package_command( + command_runner, name, version, [conda, 'install', '--json', '--dry-run', get_install_target(name, version)]) + + if 'message' in output and output['message'] == 'All requested packages already installed.': + return True + elif 'actions' in output and len(output['actions']) > 0: + return False + else: + raise CondaUnexpectedOutputError(output, stderr) + + +def install_package(command_runner, conda, name, version=None, dry_run=False): + """ + Install a package with the given name and version. Version will default to latest if `None`. + """ + command = [conda, 'install', '--yes', '--json', get_install_target(name, version)] + if dry_run: + command.insert(-1, '--dry-run') + + return run_conda_package_command(command_runner, name, version, command) + + +def uninstall_package(command_runner, conda, name, dry_run=False): + """ + Use Conda to remove a package with the given name. + """ + command = [conda, 'remove', '--yes', '--json', name] + if dry_run: + command.insert(-1, '--dry-run') + + return run_conda_package_command(command_runner, name, None, command) + + +def find_conda(executable): + """ + If `executable` is not None, checks whether it points to a valid file + and returns it if this is the case. Otherwise tries to find the `conda` + executable in the path. Calls `fail_json` if either of these fail. + """ + if not executable: + conda = which('conda') + if conda: + return conda + else: + if os.path.isfile(executable): + return executable + + raise CondaExecutableNotFoundError() + + +def add_channels_to_command(command, channels): + """ + Add extra channels to a conda command by splitting the channels + and putting "--channel" before each one. + """ + if channels: + channels = channels.strip().split() + dashc = [] + for channel in channels: + dashc.append('--channel') + dashc.append(channel) + + return command[:2] + dashc + command[2:] + else: + return command + + +def add_extras_to_command(command, extras): + """ + Add extra arguments to a conda command by splitting the arguments + on white space and inserting them after the second item in the command. + """ + if extras: + extras = extras.strip().split() + return command[:2] + extras + command[2:] + else: + return command + + +def parse_conda_stdout(stdout): + """ + Parses the given output from Conda. + :param stdout: the output from stdout + :return: standard out as parsed JSON else `None` if non-JSON format + """ + # Conda spews loading progress reports onto stdout(!?), which need ignoring. Bug observed in Conda version 4.3.25. + split_lines = stdout.strip().split("\n") + while len(split_lines) > 0: + line = split_lines.pop(0).strip('\x00') + try: + line_content = json.loads(line) + if "progress" not in line_content and "maxval" not in line_content: + # Looks like this was the output, not a progress update + return line_content + except ValueError: + split_lines.insert(0, line) + break + + try: + return json.loads("".join(split_lines)) + except ValueError: + return None + + +def run_conda_package_command(command_runner, name, version, command): + """ + Runs a Conda command related to a particular package. + :param command_runner: runner of Conda commands + :param name: the name of the package the command refers to + :param version: the version of the package that the command is referring to + :param command: the Conda command + :raises CondaPackageNotFoundError: if the package referred to by this command is not found + """ + try: + return command_runner(command) + except CondaCommandJsonDescribedError as e: + if 'exception_name' in e.output and e.output['exception_name'] in ('PackageNotFoundError', 'PackagesNotFoundError'): + raise CondaPackageNotFoundError(name, version) + else: + raise + + +def get_install_target(name, version): + """ + Gets install target string for a package with the given name and version. + :param name: the package name + :param version: the package version (`None` if latest) + :return: the target string that Conda can refer to the given package as + """ + install_target = name + if version is not None: + install_target = '%s=%s' % (name, version) + return install_target + + +class CondaCommandError(Exception): + """ + Error raised when a Conda command fails. + """ + def __init__(self, command, stdout, stderr): + self.command = command + self.stdout = stdout + self.stderr = stderr + + stdout = ' stdout: %s.' % self.stdout if self.stdout.strip() != '' else '' + stderr = ' stderr: %s.' % self.stderr if self.stderr.strip() != '' else '' + + super(CondaCommandError, self).__init__( + 'Error running command: %s.%s%s' % (self.command, stdout, stderr)) + + +class CondaCommandJsonDescribedError(CondaCommandError): + """ + Error raised when a Conda command does not output JSON. + """ + def __init__(self, command, output, stderr): + self.output = output + super(CondaCommandJsonDescribedError, self).__init__(command, json.dumps(output), stderr) + + +class CondaPackageNotFoundError(Exception): + """ + Error raised when a Conda package has not been found in the package repositories that were searched. + """ + def __int__(self, name, version): + self.name = name + self.version = version + super(CondaPackageNotFoundError, self).__init__( + 'Conda package "%s" not found' % (get_install_target(self.name, self.version), )) + + +class CondaUnexpectedOutputError(Exception): + """ + Error raised when the running of a Conda command has resulted in an unexpected output. + """ + def __int__(self, output, stderr): + self.output = output + self.stderr = stderr + + stderr = 'stderr: %s' % self.stderr if self.stderr.strip() != '' else '' + super(CondaUnexpectedOutputError, self).__init__( + 'Unexpected output from Conda (may be due to a change in Conda\'s output format): "%output".%s' + % (self.output, stderr)) + + +class CondaExecutableNotFoundError(Exception): + """ + Error raised when the Conda executable was not found. + """ + def __init__(self): + super(CondaExecutableNotFoundError, self).__init__('Conda executable not found.') + + +def _run_conda_command(module, command): + """ + Runs the given Conda command. + :param module: Ansible module + :param command: the Conda command to run, which must return JSON + """ + command = add_channels_to_command(command, module.params['channels']) + command = add_extras_to_command(command, module.params['extra_args']) + + rc, stdout, stderr = module.run_command(command) + output = parse_conda_stdout(stdout) + + if output is None: + raise CondaCommandError(command, stdout, stderr) + if rc != 0: + raise CondaCommandJsonDescribedError(command, output, stderr) + + return output, stderr + + +def _main(): + """ + Entrypoint. + """ + module = AnsibleModule( + argument_spec={ + 'name': {'required': True, 'type': 'str'}, + 'version': {'default': None, 'required': False, 'type': 'str'}, + 'state': { + 'default': 'present', + 'required': False, + 'choices': ['present', 'absent', 'latest'] + }, + 'channels': {'default': None, 'required': False}, + 'executable': {'default': None, 'required': False}, + 'extra_args': {'default': None, 'required': False, 'type': 'str'} + }, + supports_check_mode=True) + + conda = find_conda(module.params['executable']) + name = module.params['name'] + state = module.params['state'] + version = module.params['version'] + + if state == 'latest' and version is not None: + module.fail_json(msg='`version` must not be set if `state == "latest"` (`latest` upgrades to newest version)') + + def command_runner(command): + return _run_conda_command(module, command) + + run_package_operation( + conda, name, version, state, module.check_mode, command_runner, module.fail_json, module.exit_json) + + +if __name__ == '__main__': + _main() diff --git a/meta/main.yml b/meta/main.yml index 4d6b3fc..e8fc31c 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -7,11 +7,11 @@ galaxy_info: - python - conda - anaconda - license: - - MIT - min_ansible_version: 2.0 + license: MIT + min_ansible_version: '2.0' + namespace: andrewrothstein platforms: - - name: Archlinux + - name: ArchLinux versions: - all - name: Debian @@ -20,13 +20,14 @@ galaxy_info: - bullseye - name: EL versions: - - 8 - - 9 + - '8' + - '9' - name: Fedora versions: - - 37 - - 38 + - '38' + - '39' - name: Ubuntu versions: - focal - jammy + role_name: anaconda diff --git a/meta/requirements.yml b/meta/requirements.yml index 1933916..f4a7bff 100644 --- a/meta/requirements.yml +++ b/meta/requirements.yml @@ -1,5 +1,5 @@ --- - name: andrewrothstein.bash - version: v1.1.12 + version: v1.2.2 - name: andrewrothstein.unarchivedeps - version: 2.0.1 + version: 3.0.1 diff --git a/platform-matrix-v1.json b/platform-matrix-v1.json new file mode 100644 index 0000000..ca7b93c --- /dev/null +++ b/platform-matrix-v1.json @@ -0,0 +1,38 @@ +[ + { + "OS": "archlinux", + "OS_VER": "latest" + }, + { + "OS": "debian", + "OS_VER": "bookworm" + }, + { + "OS": "debian", + "OS_VER": "bullseye" + }, + { + "OS": "fedora", + "OS_VER": "38" + }, + { + "OS": "fedora", + "OS_VER": "39" + }, + { + "OS": "rockylinux", + "OS_VER": "8" + }, + { + "OS": "rockylinux", + "OS_VER": "9" + }, + { + "OS": "ubuntu", + "OS_VER": "focal" + }, + { + "OS": "ubuntu", + "OS_VER": "jammy" + } +] \ No newline at end of file diff --git a/subrepos/udst.ansible-conda/.gitignore b/subrepos/udst.ansible-conda/.gitignore deleted file mode 100644 index 183abe2..0000000 --- a/subrepos/udst.ansible-conda/.gitignore +++ /dev/null @@ -1,104 +0,0 @@ -# Created by .ignore support plugin (hsz.mobi) -### Python template -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -### Ansible template -*.retry - diff --git a/subrepos/udst.ansible-conda/.gitrepo b/subrepos/udst.ansible-conda/.gitrepo deleted file mode 100644 index 49278d5..0000000 --- a/subrepos/udst.ansible-conda/.gitrepo +++ /dev/null @@ -1,11 +0,0 @@ -; DO NOT EDIT (unless you know what you are doing) -; -; This subdirectory is a git "subrepo", and this file is maintained by the -; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme -; -[subrepo] - remote = https://github.com/UDST/ansible-conda.git - branch = master - commit = f26ac9f82bb96035d9d96a1531d62456c959229d - parent = 6152493201e573df97d45458a141f411b20f6277 - cmdver = 0.3.1 diff --git a/subrepos/udst.ansible-conda/.travis.yml b/subrepos/udst.ansible-conda/.travis.yml deleted file mode 100644 index aa59a5a..0000000 --- a/subrepos/udst.ansible-conda/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- - -sudo: required - -services: - - docker - -install: - - docker build -t test-runner -f Dockerfile.test . - -script: - - docker run --rm -t -v $PWD:/ansible-conda test-runner diff --git a/subrepos/udst.ansible-conda/Dockerfile.test b/subrepos/udst.ansible-conda/Dockerfile.test deleted file mode 100644 index 42eec75..0000000 --- a/subrepos/udst.ansible-conda/Dockerfile.test +++ /dev/null @@ -1,27 +0,0 @@ -FROM ubuntu - -ENV DATA_DIRECTORY=/ansible-conda - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - python \ - python-pip \ - python-apt \ - python-dev \ - build-essential \ - git \ - && rm -rf /var/lib/apt/lists/* - -RUN pip install setuptools wheel -RUN pip install ansible==2.3.2.0 - -ADD tests/integration/requirements.yml /tmp/requirements.yml -RUN ansible-galaxy install -r /tmp/requirements.yml - -ADD tests/integration/requirements.txt /tmp/requirements.txt -RUN pip install -r /tmp/requirements.txt - -VOLUME "${DATA_DIRECTORY}" -WORKDIR "${DATA_DIRECTORY}" - -CMD "${DATA_DIRECTORY}/run-tests.sh" diff --git a/subrepos/udst.ansible-conda/README.md b/subrepos/udst.ansible-conda/README.md deleted file mode 100644 index 961a4ea..0000000 --- a/subrepos/udst.ansible-conda/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Conda Ansible Module - -Manage [conda][] installations of Python packages in [Ansible][] playbooks. -Put this module somewhere Ansible will find it -(like the `library/` directory next to your top level playbooks). -Usage is much like the built-in Ansible pip module. -This requires `conda` to already be installed somehow. - -Examples: - -```yaml -- name: install numpy via conda - conda: name=numpy state=latest - -- name: install scipy 0.14 via conda - conda: name=scipy version="0.14" - -- name: remove matplotlib from conda - conda: name=matplotlib state=absent -``` - -From `ansible-doc`: - -``` -> CONDA - - Manage Python libraries via conda. Can install, update, and remove - packages. - -Options (= is mandatory): - -- channels - Extra channels to use when installing packages [Default: None] - -- executable - Full path to the conda executable [Default: None] - -- extra_args - Extra arguments passed to conda [Default: None] - -- name - The name of a Python library to install [Default: None] - -- state - State in which to leave the Python package (Choices: present, - absent, latest) [Default: present] - -- version - A specific version of a library to install [Default: None] - -Notes: Requires conda to already be installed. Will look under the home - directory for a conda executable. -``` - -[conda]: http://conda.pydata.org/ -[Ansible]: http://docs.ansible.com/index.html diff --git a/subrepos/udst.ansible-conda/conda.py b/subrepos/udst.ansible-conda/conda.py deleted file mode 100755 index b9d0f19..0000000 --- a/subrepos/udst.ansible-conda/conda.py +++ /dev/null @@ -1,373 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -DOCUMENTATION = """ ---- -module: conda -short_description: Manage Python libraries via conda -description: - > - Manage Python libraries via conda. - Can install, update, and remove packages. -author: - - Synthicity - - Colin Nolan (@colin-nolan) -notes: - > - Requires conda to already be installed. -options: - name: - description: The name of a Python package to install. - required: true - version: - description: The specific version of a package to install. - required: false - state: - description: State in which to leave the Python package. "present" will install a package of the specified version - if it is not installed (will not upgrade to latest if version is unspecified - will only install - latest); "latest" will both install and subsequently upgrade a package to the latest version on each - run; "absent" will uninstall the package if installed. - required: false - default: present - choices: [ "present", "absent", "latest" ] - channels: - description: Extra channels to use when installing packages. - required: false - executable: - description: Full path to the conda executable. - required: false - extra_args: - description: Extra arguments passed to conda. - required: false -""" - -EXAMPLES = """ -- name: install numpy via conda - conda: - name: numpy - state: latest - -- name: install scipy 0.14 via conda - conda: - name: scipy - version: "0.14" - -- name: remove matplotlib from conda - conda: - name: matplotlib - state: absent -""" - -RETURN = """ -output: - description: JSON output from Conda - returned: `changed == True` - type: dict -stderr: - description: stderr content written by Conda - returned: `changed == True` - type: str -""" - - -from shutil import which -import os.path -import json -from ansible.module_utils.basic import AnsibleModule - - -def run_package_operation(conda, name, version, state, dry_run, command_runner, on_failure, on_success): - """ - Runs Conda package operation. - - This method is intentionally decoupled from `AnsibleModule` to allow it to be easily tested in isolation. - :param conda: location of the Conda executable - :param name: name of the package of interest - :param version: version of the package (`None` for latest) - :param state: state the package should be in - :param dry_run: will "pretend" to make changes only if `True` - :param command_runner: method that executes a given Conda command (given as list of string arguments), which returns - JSON and returns a tuple where the first argument is the outputted JSON and the second is anything written to stderr - :param on_failure: method that takes any kwargs to be called on failure - :param on_success: method that takes any kwargs to be called on success - """ - correct_version_installed = check_package_installed(command_runner, conda, name, version) - - # TODO: State should be an "enum" (or whatever the Py2.7 equivalent is) - if not correct_version_installed and state != 'absent': - try: - output, stderr = install_package(command_runner, conda, name, version, dry_run=dry_run) - on_success(changed=True, output=output, stderr=stderr) - except CondaPackageNotFoundError: - on_failure(msg='Conda package "%s" not found' % (get_install_target(name, version, ))) - - elif state == 'absent': - try: - output, stderr = uninstall_package(command_runner, conda, name, dry_run=dry_run) - on_success(changed=True, output=output, stderr=stderr) - except CondaPackageNotFoundError: - on_success(changed=False) - - else: - on_success(changed=False) - - -def check_package_installed(command_runner, conda, name, version): - """ - Check whether a package with the given name and version is installed. - :param command_runner: method that executes a given Conda command (given as list of string arguments), which returns - JSON and returns a tuple where the first argument is the outputted JSON and the second is anything written to stderr - :param name: the name of the package to check if installed - :param version: the version of the package to check if installed (`None` if check for latest) - :return: `True` if a package with the given name and version is installed - :raises CondaUnexpectedOutputError: if the JSON returned by Conda was unexpected - """ - output, stderr = run_conda_package_command( - command_runner, name, version, [conda, 'install', '--json', '--dry-run', get_install_target(name, version)]) - - if 'message' in output and output['message'] == 'All requested packages already installed.': - return True - elif 'actions' in output and len(output['actions']) > 0: - return False - else: - raise CondaUnexpectedOutputError(output, stderr) - - -def install_package(command_runner, conda, name, version=None, dry_run=False): - """ - Install a package with the given name and version. Version will default to latest if `None`. - """ - command = [conda, 'install', '--yes', '--json', get_install_target(name, version)] - if dry_run: - command.insert(-1, '--dry-run') - - return run_conda_package_command(command_runner, name, version, command) - - -def uninstall_package(command_runner, conda, name, dry_run=False): - """ - Use Conda to remove a package with the given name. - """ - command = [conda, 'remove', '--yes', '--json', name] - if dry_run: - command.insert(-1, '--dry-run') - - return run_conda_package_command(command_runner, name, None, command) - - -def find_conda(executable): - """ - If `executable` is not None, checks whether it points to a valid file - and returns it if this is the case. Otherwise tries to find the `conda` - executable in the path. Calls `fail_json` if either of these fail. - """ - if not executable: - conda = which('conda') - if conda: - return conda - else: - if os.path.isfile(executable): - return executable - - raise CondaExecutableNotFoundError() - - -def add_channels_to_command(command, channels): - """ - Add extra channels to a conda command by splitting the channels - and putting "--channel" before each one. - """ - if channels: - channels = channels.strip().split() - dashc = [] - for channel in channels: - dashc.append('--channel') - dashc.append(channel) - - return command[:2] + dashc + command[2:] - else: - return command - - -def add_extras_to_command(command, extras): - """ - Add extra arguments to a conda command by splitting the arguments - on white space and inserting them after the second item in the command. - """ - if extras: - extras = extras.strip().split() - return command[:2] + extras + command[2:] - else: - return command - - -def parse_conda_stdout(stdout): - """ - Parses the given output from Conda. - :param stdout: the output from stdout - :return: standard out as parsed JSON else `None` if non-JSON format - """ - # Conda spews loading progress reports onto stdout(!?), which need ignoring. Bug observed in Conda version 4.3.25. - split_lines = stdout.strip().split("\n") - while len(split_lines) > 0: - line = split_lines.pop(0).strip('\x00') - try: - line_content = json.loads(line) - if "progress" not in line_content and "maxval" not in line_content: - # Looks like this was the output, not a progress update - return line_content - except ValueError: - split_lines.insert(0, line) - break - - try: - return json.loads("".join(split_lines)) - except ValueError: - return None - - -def run_conda_package_command(command_runner, name, version, command): - """ - Runs a Conda command related to a particular package. - :param command_runner: runner of Conda commands - :param name: the name of the package the command refers to - :param version: the version of the package that the command is referring to - :param command: the Conda command - :raises CondaPackageNotFoundError: if the package referred to by this command is not found - """ - try: - return command_runner(command) - except CondaCommandJsonDescribedError as e: - if 'exception_name' in e.output and e.output['exception_name'] in ('PackageNotFoundError', 'PackagesNotFoundError'): - raise CondaPackageNotFoundError(name, version) - else: - raise - - -def get_install_target(name, version): - """ - Gets install target string for a package with the given name and version. - :param name: the package name - :param version: the package version (`None` if latest) - :return: the target string that Conda can refer to the given package as - """ - install_target = name - if version is not None: - install_target = '%s=%s' % (name, version) - return install_target - - -class CondaCommandError(Exception): - """ - Error raised when a Conda command fails. - """ - def __init__(self, command, stdout, stderr): - self.command = command - self.stdout = stdout - self.stderr = stderr - - stdout = ' stdout: %s.' % self.stdout if self.stdout.strip() != '' else '' - stderr = ' stderr: %s.' % self.stderr if self.stderr.strip() != '' else '' - - super(CondaCommandError, self).__init__( - 'Error running command: %s.%s%s' % (self.command, stdout, stderr)) - - -class CondaCommandJsonDescribedError(CondaCommandError): - """ - Error raised when a Conda command does not output JSON. - """ - def __init__(self, command, output, stderr): - self.output = output - super(CondaCommandJsonDescribedError, self).__init__(command, json.dumps(output), stderr) - - -class CondaPackageNotFoundError(Exception): - """ - Error raised when a Conda package has not been found in the package repositories that were searched. - """ - def __int__(self, name, version): - self.name = name - self.version = version - super(CondaPackageNotFoundError, self).__init__( - 'Conda package "%s" not found' % (get_install_target(self.name, self.version), )) - - -class CondaUnexpectedOutputError(Exception): - """ - Error raised when the running of a Conda command has resulted in an unexpected output. - """ - def __int__(self, output, stderr): - self.output = output - self.stderr = stderr - - stderr = 'stderr: %s' % self.stderr if self.stderr.strip() != '' else '' - super(CondaUnexpectedOutputError, self).__init__( - 'Unexpected output from Conda (may be due to a change in Conda\'s output format): "%output".%s' - % (self.output, stderr)) - - -class CondaExecutableNotFoundError(Exception): - """ - Error raised when the Conda executable was not found. - """ - def __init__(self): - super(CondaExecutableNotFoundError, self).__init__('Conda executable not found.') - - -def _run_conda_command(module, command): - """ - Runs the given Conda command. - :param module: Ansible module - :param command: the Conda command to run, which must return JSON - """ - command = add_channels_to_command(command, module.params['channels']) - command = add_extras_to_command(command, module.params['extra_args']) - - rc, stdout, stderr = module.run_command(command) - output = parse_conda_stdout(stdout) - - if output is None: - raise CondaCommandError(command, stdout, stderr) - if rc != 0: - raise CondaCommandJsonDescribedError(command, output, stderr) - - return output, stderr - - -def _main(): - """ - Entrypoint. - """ - module = AnsibleModule( - argument_spec={ - 'name': {'required': True, 'type': 'str'}, - 'version': {'default': None, 'required': False, 'type': 'str'}, - 'state': { - 'default': 'present', - 'required': False, - 'choices': ['present', 'absent', 'latest'] - }, - 'channels': {'default': None, 'required': False}, - 'executable': {'default': None, 'required': False}, - 'extra_args': {'default': None, 'required': False, 'type': 'str'} - }, - supports_check_mode=True) - - conda = find_conda(module.params['executable']) - name = module.params['name'] - state = module.params['state'] - version = module.params['version'] - - if state == 'latest' and version is not None: - module.fail_json(msg='`version` must not be set if `state == "latest"` (`latest` upgrades to newest version)') - - def command_runner(command): - return _run_conda_command(module, command) - - run_package_operation( - conda, name, version, state, module.check_mode, command_runner, module.fail_json, module.exit_json) - - -if __name__ == '__main__': - _main() diff --git a/subrepos/udst.ansible-conda/run-tests.sh b/subrepos/udst.ansible-conda/run-tests.sh deleted file mode 100755 index 1f68fe5..0000000 --- a/subrepos/udst.ansible-conda/run-tests.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -set -euf -o pipefail - -# Setup -ansible-galaxy install -r "${DATA_DIRECTORY}/tests/integration/requirements.yml" -pip install -r "${DATA_DIRECTORY}/tests/integration/requirements.txt" - -# Run unit tests -PYTHONPATH=. python -m unittest discover -v -s tests/unit - -# Run integration tests -ansible-playbook -vvv -e ansible_python_interpreter=$(which python) -c local "${DATA_DIRECTORY}/tests/integration/site.yml" diff --git a/subrepos/udst.ansible-conda/tests/integration/defaults/main.yml b/subrepos/udst.ansible-conda/tests/integration/defaults/main.yml deleted file mode 100644 index 31cbed1..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/defaults/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- - -conda_tests_python_version: 2 -conda_tests_anaconda_version: 4.4.0 -conda_tests_anaconda_installation_location: /tmp/install/anaconda -conda_tests_conda_executable: "{{ conda_tests_anaconda_installation_location }}/bin/conda" diff --git a/subrepos/udst.ansible-conda/tests/integration/library/conda.py b/subrepos/udst.ansible-conda/tests/integration/library/conda.py deleted file mode 120000 index d69432a..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/library/conda.py +++ /dev/null @@ -1 +0,0 @@ -../../../conda.py \ No newline at end of file diff --git a/subrepos/udst.ansible-conda/tests/integration/meta/main.yml b/subrepos/udst.ansible-conda/tests/integration/meta/main.yml deleted file mode 100644 index 73a1cb2..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/meta/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -dependencies: - - role: anaconda - vars: - anaconda_python_ver: "{{ conda_tests_python_version }}" - anaconda_ver: "{{ conda_tests_anaconda_version }}" - anaconda_pkg_update: no - anaconda_parent_dir: "{{ conda_tests_anaconda_installation_location | dirname }}" - anaconda_link_subdir: "{{ conda_tests_anaconda_installation_location | basename }}" diff --git a/subrepos/udst.ansible-conda/tests/integration/requirements.txt b/subrepos/udst.ansible-conda/tests/integration/requirements.txt deleted file mode 100644 index c23b05b..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -jmespath \ No newline at end of file diff --git a/subrepos/udst.ansible-conda/tests/integration/requirements.yml b/subrepos/udst.ansible-conda/tests/integration/requirements.yml deleted file mode 100644 index e827817..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/requirements.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- name: anaconda - src: https://github.com/wtsi-hgi/ansible-anaconda.git - version: 60ac57016facaf8658437ca4700f4037b60be42e diff --git a/subrepos/udst.ansible-conda/tests/integration/site.yml b/subrepos/udst.ansible-conda/tests/integration/site.yml deleted file mode 100644 index 3f31b86..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/site.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -- hosts: localhost - roles: - - ../ diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/install.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/install.yml deleted file mode 100644 index a09eaf9..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/install.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -- name: install apt prerequisites - apt: - name: python-pip - -- name: install Python prerequisites - pip: - name: jmespath diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/main.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/main.yml deleted file mode 100644 index a448baf..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/main.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- - -- include: install.yml -- include: tear-down.yml - -- block: - - include: test-uninstall.yml - always: - - include: tear-down.yml - -- block: - - include: test-install-latest.yml - always: - - include: tear-down.yml - -- block: - - include: test-install-fixed-version.yml - always: - - include: tear-down.yml - -- block: - - include: test-install-loosely-fixed-version.yml - always: - - include: tear-down.yml - -- block: - - include: test-upgrade.yml - always: - - include: tear-down.yml - -- block: - - include: test-downgrade.yml - always: - - include: tear-down.yml - -- block: - - include: test-invalid-setups.yml - always: - - include: tear-down.yml - -- block: - - include: test-failures.yml - always: - - include: tear-down.yml diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/set-install-facts.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/set-install-facts.yml deleted file mode 100644 index b55faeb..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/set-install-facts.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- - -- name: find installed matching Conda packages - shell: "{{ conda_tests_conda_executable }} search --json ^{{ conda_tests_install_example }}$" - no_log: True - register: installed_raw - -- name: filter output - set_fact: - installed: "{{ (installed_raw.stdout | from_json | json_query('%s[?installed]' % conda_tests_install_example)) }}" - -- name: ensure expected environment - assert: - that: installed | length <= 1 - -- name: set install facts - set_fact: - example_package: - installed: "{{ installed | length != 0 }}" - version: "{{ installed[0].version if installed | length > 0 else False }}" diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/tear-down.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/tear-down.yml deleted file mode 100644 index a016e6f..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/tear-down.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- - -- name: uninstall package via Conda - conda: - name: "{{ conda_tests_install_example }}" - state: absent - executable: "{{ conda_tests_conda_executable }}" - -- include: set-install-facts.yml - -- name: verify package not installed - assert: - that: not example_package.installed diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/test-downgrade.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/test-downgrade.yml deleted file mode 100644 index c9c6c33..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/test-downgrade.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- - -- name: install latest Conda package - conda: - name: "{{ conda_tests_install_example }}" - state: latest - executable: "{{ conda_tests_conda_executable }}" - -- name: install old Conda package - conda: - name: "{{ conda_tests_install_example }}" - version: "{{ conda_tests_old_version }}" - state: present - executable: "{{ conda_tests_conda_executable }}" - register: second_install - -- include: set-install-facts.yml - -- name: verify installed - assert: - that: - - second_install.changed - - example_package.installed - - example_package.version | version_compare(conda_tests_old_version, '=') diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/test-failures.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/test-failures.yml deleted file mode 100644 index 12f8ec5..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/test-failures.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- - -- name: install Conda packge that does not exist (expect failure) - conda: - name: this_packge_hopefully_does_not_exist - state: present - executable: "{{ conda_tests_conda_executable }}" - register: non_existent_install - ignore_errors: yes - -- name: verify failure - assert: - that: non_existent_install.failed - -- name: install Conda packge version that does not exist (expect failure) - conda: - name: "{{ conda_tests_install_example }}" - state: present - version: 9999 - executable: "{{ conda_tests_conda_executable }}" - register: non_existent_install - ignore_errors: yes - -- name: verify failure - assert: - that: non_existent_install.failed - -- name: install latest Conda packge, fixed at a specific version (expect failure) - conda: - name: "{{ conda_tests_install_example }}" - state: latest - version: "{{ conda_tests_minimum_latest_version }}" - executable: "{{ conda_tests_conda_executable }}" - register: invalid_setup - ignore_errors: yes - -- name: verify failure - assert: - that: invalid_setup.failed diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/test-install-fixed-version.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/test-install-fixed-version.yml deleted file mode 100644 index 71b5863..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/test-install-fixed-version.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- - -- name: install Conda package - conda: - name: "{{ conda_tests_install_example }}" - version: "{{ conda_tests_old_version }}" - state: present - executable: "{{ conda_tests_conda_executable }}" - register: first_install - -- include: set-install-facts.yml - -- name: verify installed - assert: - that: - - first_install.changed - - example_package.installed - - example_package.version | version_compare(conda_tests_old_version, '=') - -- name: install Conda package (again) - conda: - name: "{{ conda_tests_install_example }}" - version: "{{ conda_tests_old_version }}" - state: present - executable: "{{ conda_tests_conda_executable }}" - register: second_install - -- name: verify idempotence - assert: - that: not second_install.changed diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/test-install-latest.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/test-install-latest.yml deleted file mode 100644 index ed71aba..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/test-install-latest.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- - -- name: install latest version of the Conda package - conda: - name: "{{ conda_tests_install_example }}" - state: latest - executable: "{{ conda_tests_conda_executable }}" - register: first_install - -- include: set-install-facts.yml - -- name: verify installed - assert: - that: - - first_install.changed - - example_package.installed - - example_package.version | version_compare(conda_tests_minimum_latest_version, '>=') - -# TODO: Until tests are ran against local package repository, this test would be flaky in the (rare) case that the -# package is updated mid-test -- name: install latest version of the Conda package (again) - conda: - name: "{{ conda_tests_install_example }}" - state: latest - executable: "{{ conda_tests_conda_executable }}" - register: second_install - -- name: verify idempotence - assert: - that: not second_install.changed - -- block: - - name: install larger Conda package with dependencies - conda: - name: "{{ conda_tests_larger_install_example }}" - state: present - executable: "{{ conda_tests_conda_executable }}" - register: larger_install - - - include: set-install-facts.yml - vars: - conda_tests_install_example: "{{ conda_tests_larger_install_example }}" - - - name: verify installed - assert: - that: - - larger_install.changed - - example_package.installed - - always: - - include: tear-down.yml - vars: - conda_tests_install_example: "{{ conda_tests_larger_install_example }}" diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/test-install-loosely-fixed-version.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/test-install-loosely-fixed-version.yml deleted file mode 100644 index fc3bd92..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/test-install-loosely-fixed-version.yml +++ /dev/null @@ -1,59 +0,0 @@ ---- - -- name: install Conda package using major version number - conda: - name: "{{ conda_tests_install_example }}" - version: "{{ conda_tests_minimum_latest_major_version }}" - state: present - executable: "{{ conda_tests_conda_executable }}" - register: first_install - -- include: set-install-facts.yml - -- name: verify installed - assert: - that: - - first_install.changed - - example_package.installed - - example_package.version | version_compare(conda_tests_minimum_latest_version, '>=') - -- name: install Conda package using major version number (again) - conda: - name: "{{ conda_tests_install_example }}" - version: "{{ conda_tests_minimum_latest_major_version }}" - state: present - executable: "{{ conda_tests_conda_executable }}" - register: second_install - -- name: verify idempotence - assert: - that: not second_install.changed - - -- name: verify setup for testing package upgrade - assert: - that: conda_tests_old_version.split('.')[0] == conda_tests_minimum_latest_major_version - -- name: install older Conda package - conda: - name: "{{ conda_tests_install_example }}" - version: "{{ conda_tests_old_version }}" - state: present - executable: "{{ conda_tests_conda_executable }}" - -- name: upgrade Conda package - conda: - name: "{{ conda_tests_install_example }}" - version: "{{ conda_tests_minimum_latest_major_version }}" - state: present - executable: "{{ conda_tests_conda_executable }}" - register: upgrade_install - -- include: set-install-facts.yml - -- name: verify upgrade - assert: - that: - - upgrade_install.changed - - example_package.installed - - example_package.version | version_compare(conda_tests_minimum_latest_version, '>=') diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/test-invalid-setups.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/test-invalid-setups.yml deleted file mode 100644 index 4e37556..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/test-invalid-setups.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- - -- name: install Conda packge with fixed version but `latest` state - conda: - name: "{{ conda_tests_install_example }}" - version: "{{ conda_tests_old_version }}" - state: latest - executable: "{{ conda_tests_conda_executable }}" - register: versioned_and_latest_install - ignore_errors: yes - -- name: verify invalid setup - assert: - that: versioned_and_latest_install.failed diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/test-uninstall.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/test-uninstall.yml deleted file mode 100644 index fc3d89d..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/test-uninstall.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- - -- name: install Conda package - conda: - name: "{{ conda_tests_install_example }}" - state: latest - executable: "{{ conda_tests_conda_executable }}" - register: first_install - -- name: uninstall Conda package - conda: - name: "{{ conda_tests_install_example }}" - state: absent - executable: "{{ conda_tests_conda_executable }}" - register: first_uninstall - -- include: set-install-facts.yml - -- name: verify package not installed - assert: - that: - - first_uninstall.changed - - not example_package.installed - -- name: uninstall Conda package again - conda: - name: "{{ conda_tests_install_example }}" - state: absent - executable: "{{ conda_tests_conda_executable }}" - register: second_uninstall - -- include: set-install-facts.yml - -- name: verify idempotence - assert: - that: not second_uninstall.changed diff --git a/subrepos/udst.ansible-conda/tests/integration/tasks/test-upgrade.yml b/subrepos/udst.ansible-conda/tests/integration/tasks/test-upgrade.yml deleted file mode 100644 index c18ea60..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/tasks/test-upgrade.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- - -- name: install old Conda package - conda: - name: "{{ conda_tests_install_example }}" - version: "{{ conda_tests_old_version }}" - state: present - executable: "{{ conda_tests_conda_executable }}" - -- name: install latest Conda package - conda: - name: "{{ conda_tests_install_example }}" - state: latest - executable: "{{ conda_tests_conda_executable }}" - register: second_install - -- include: set-install-facts.yml - -- name: verify installed - assert: - that: - - second_install.changed - - example_package.installed - - example_package.version | version_compare(conda_tests_minimum_latest_version, '>=') diff --git a/subrepos/udst.ansible-conda/tests/integration/vars/main.yml b/subrepos/udst.ansible-conda/tests/integration/vars/main.yml deleted file mode 100644 index 3591995..0000000 --- a/subrepos/udst.ansible-conda/tests/integration/vars/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -# XXX: better to hit local package repository with dummy package -conda_tests_install_example: translationstring -conda_tests_minimum_latest_version: "1.3" -conda_tests_minimum_latest_major_version: "1" -conda_tests_old_version: "1.1" - -conda_tests_larger_install_example: curl diff --git a/subrepos/udst.ansible-conda/tests/unit/test_conda.py b/subrepos/udst.ansible-conda/tests/unit/test_conda.py deleted file mode 100644 index 8bf19f3..0000000 --- a/subrepos/udst.ansible-conda/tests/unit/test_conda.py +++ /dev/null @@ -1,33 +0,0 @@ -import json -import unittest - -from conda import parse_conda_stdout - - -class TestParseCondaStdout(unittest.TestCase): - """ - Tests for `parse_conda_stdout`. - """ - _VALID_STDOUT = """ - { - "actions": {}, - "success": true - } - """ - - def test_parses_invalid_stdout(self): - self.assertIsNone(parse_conda_stdout("fail")) - - def test_parses_valid_stdout(self): - self.assertEqual( - json.loads(TestParseCondaStdout._VALID_STDOUT), parse_conda_stdout(TestParseCondaStdout._VALID_STDOUT)) - - def test_parses_valid_stdout_with_progress_reports(self): - stdout = '{"maxval": 17685, "finished": false, "fetch": "translationstr", "progress": 0}\n\x00' \ - '{"maxval": 17685, "finished": true, "fetch": "translationstr", "progress": 17685}\n\x00%s' \ - % (TestParseCondaStdout._VALID_STDOUT,) - self.assertEqual(json.loads(TestParseCondaStdout._VALID_STDOUT), parse_conda_stdout(stdout)) - - -if __name__ == "__main__": - unittest.main() diff --git a/tasks/Windows.yml b/tasks/Windows.yml index d547cbe..bd2b393 100644 --- a/tasks/Windows.yml +++ b/tasks/Windows.yml @@ -1,38 +1,39 @@ --- -- name: check for existance of Anaconda - win_stat: +- name: Check for existance of Anaconda + ansible.windows.win_stat: path: '{{ anaconda_conda_bin }}' changed_when: false register: anaconda_conda_bin_ -- when: not anaconda_conda_bin_.stat.exists +- name: Downloading and installing anaconda + when: not anaconda_conda_bin_.stat.exists vars: anaconda_installer_dest: '{{ ansible_env.TEMP }}\{{ anaconda_installer_sh }}' block: - - name: download installer... - win_get_url: + - name: Download installer... + ansible.windows.win_get_url: url: '{{ anaconda_installer_url }}' dest: '{{ anaconda_installer_dest }}' timeout: '{{ anaconda_timeout_seconds }}' register: anaconda_installer - - name: get installer information - win_stat: + - name: Get installer information + ansible.windows.win_stat: path: '{{ anaconda_installer.dest }}' checksum_algorithm: md5 get_checksum: true register: anaconda_installer_ - - name: verify installer checksum + - name: Verify installer checksum vars: checksum: '{{ anaconda_installer_.stat.checksum }}' - assert: + ansible.builtin.assert: that: - 'checksum == anaconda_checksum' msg: 'anaconda installer checksum mismatch' - name: install... - win_package: + ansible.windows.win_package: path: '{{ anaconda_installer.dest }}' creates_path: '{{ anaconda_install_dir }}' state: present @@ -44,7 +45,7 @@ - /D={{ anaconda_install_dir }} always: - - name: delete installer... - win_file: + - name: Delete installer... + ansible.windows.win_file: path: '{{ anaconda_installer_dest }}' state: absent diff --git a/tasks/default.yml b/tasks/default.yml index d01bdd3..19edfb8 100644 --- a/tasks/default.yml +++ b/tasks/default.yml @@ -1,73 +1,74 @@ --- -- name: installing OS pkg dependencies +- name: Installing OS pkg dependencies become: true become_user: root - package: + ansible.builtin.package: state: present name: '{{ anaconda_dep_pkgs | default([]) }}' -- name: check for installation at {{ anaconda_install_exe }} +- name: Check for installation at {{ anaconda_install_exe }} become: true stat: path: '{{ anaconda_install_exe }}' changed_when: false register: anaconda_conda_binary -- when: not anaconda_conda_binary.stat.exists +- name: Downloading and installing anaconda + when: not anaconda_conda_binary.stat.exists block: - - name: ensure that {{ anaconda_tmp_dir }} directory exists - file: + - name: Ensure that {{ anaconda_tmp_dir }} directory exists + ansible.builtin.file: path: "{{ anaconda_tmp_dir }}" state: directory + mode: '755' - - name: downloading {{ anaconda_installer_url }} to {{ anaconda_installer_tmp_sh }} + - name: Downloading {{ anaconda_installer_url }} to {{ anaconda_installer_tmp_sh }} become: true become_user: root - get_url: + ansible.builtin.get_url: url: '{{ anaconda_installer_url }}' dest: '{{ anaconda_installer_tmp_sh }}' timeout: '{{ anaconda_timeout_seconds }}' checksum: '{{ anaconda_checksum }}' - mode: 0755 + mode: '755' - - name: launching installer {{ anaconda_installer_tmp_sh }} with bash + - name: Launching installer {{ anaconda_installer_tmp_sh }} with bash become: true become_user: root - shell: | - ( - [ ! -z "{{ anaconda_umask }}" ] && umask {{ anaconda_umask }} - TMPDIR={{ anaconda_tmp_dir }} bash {{ anaconda_installer_tmp_sh }} -b -p {{ anaconda_install_dir }} - ) + shell: |- + [ -n "{{ anaconda_umask }}" ] && umask {{ anaconda_umask }}; + TMPDIR={{ anaconda_tmp_dir }} \ + bash "{{ anaconda_installer_tmp_sh }}" \ + -b \ + -p "{{ anaconda_install_dir }}"; args: creates: '{{ anaconda_install_dir }}' always: - - name: rm {{ anaconda_installer_tmp_sh }} + - name: Rm {{ anaconda_installer_tmp_sh }} become: true become_user: root - file: + ansible.builtin.file: path: '{{ anaconda_installer_tmp_sh }}' state: absent -- name: linking {{ anaconda_link_dir }} to {{ anaconda_install_dir }} +- name: Linking {{ anaconda_link_dir }} to {{ anaconda_install_dir }} become: true become_user: root - file: + ansible.builtin.file: src: '{{ anaconda_install_dir }}' dest: '{{ anaconda_link_dir }}' state: link -- name: updating all conda pkgs... +- name: Updating all conda pkgs... become: true become_user: root when: anaconda_pkg_update - shell: | - ( - [ ! -z "{{ anaconda_umask }}" ] && umask {{ anaconda_umask }} - {{ anaconda_conda_bin }} update -y --all - ) + shell: |- + [ -n "{{ anaconda_umask }}" ] && umask {{ anaconda_umask }}; + {{ anaconda_conda_bin }} update -y --all; -- name: remove conda-curl since it conflicts with the system curl +- name: Remove conda-curl since it conflicts with the system curl become: true become_user: root conda: @@ -75,7 +76,7 @@ state: absent executable: '{{ anaconda_conda_bin }}' -- name: make system default python etc... +- name: Make system default python etc... become: true become_user: root when: anaconda_make_sys_default @@ -87,9 +88,9 @@ template: src: '{{ tt.f }}.j2' dest: '{{ tt.d }}/{{ tt.f }}' - mode: '{{ tt.m | default("0644") }}' + mode: '{{ tt.m | default("644") }}' -- name: installing additional conda packages +- name: Installing additional conda packages become: true become_user: root loop: '{{ anaconda_install_packages | default([]) }}' diff --git a/tasks/main.yml b/tasks/main.yml index 38aa6f0..fc62700 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,11 +1,13 @@ --- -- include_role: +- name: Installing andrewrothstein.bash + ansible.builtin.include_role: name: andrewrothstein.bash -- include_role: +- name: Installing andrewrothstein.unarchivedeps + ansible.builtin.include_role: name: andrewrothstein.unarchivedeps -- name: resolve platform specific vars - include_vars: '{{ item }}' +- name: Resolve platform specific vars + ansible.builtin.include_vars: '{{ item }}' with_first_found: - files: - '{{ ansible_os_family }}.yml' @@ -13,8 +15,8 @@ paths: - '{{ role_path }}/vars' -- name: resolve platform specific tasks - include_tasks: '{{ item }}' +- name: Resolve platform specific tasks + ansible.builtin.include_tasks: '{{ item }}' with_first_found: - files: - '{{ ansible_os_family }}.yml' diff --git a/tests/inventory b/tests/inventory deleted file mode 100644 index 2302eda..0000000 --- a/tests/inventory +++ /dev/null @@ -1 +0,0 @@ -localhost ansible_connection=local diff --git a/tests/test.yml b/tests/test.yml deleted file mode 100644 index c87660e..0000000 --- a/tests/test.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- hosts: localhost - remote_user: root - roles: - - ansible-anaconda