Improve ansible-galaxy error for InconsistentCandidate exception (#75235)

* Improve error for InconsistentCandidate exceptions

* Add test case for installing a collection with an inconsistent version

* Add test case for installing a collection that has a dependency with an inconsistent version

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
Co-authored-by: Sviatoslav Sydorenko <webknjaz@redhat.com>
pull/75465/head
Sloane Hertel 3 years ago committed by GitHub
parent 0055a328b3
commit e24eb59de5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- ansible-galaxy - Improve error message from dependency resolution when a candidate has inconsistent requirements (https://github.com/ansible/ansible/issues/75139).

@ -113,6 +113,7 @@ from ansible.galaxy.dependency_resolution.dataclasses import (
) )
from ansible.galaxy.dependency_resolution.errors import ( from ansible.galaxy.dependency_resolution.errors import (
CollectionDependencyResolutionImpossible, CollectionDependencyResolutionImpossible,
CollectionDependencyInconsistentCandidate,
) )
from ansible.galaxy.dependency_resolution.versioning import meets_requirements from ansible.galaxy.dependency_resolution.versioning import meets_requirements
from ansible.module_utils.six import raise_from from ansible.module_utils.six import raise_from
@ -1353,3 +1354,33 @@ def _resolve_depenency_map(
AnsibleError('\n'.join(error_msg_lines)), AnsibleError('\n'.join(error_msg_lines)),
dep_exc, dep_exc,
) )
except CollectionDependencyInconsistentCandidate as dep_exc:
parents = [
"%s.%s:%s" % (p.namespace, p.name, p.ver)
for p in dep_exc.criterion.iter_parent()
if p is not None
]
error_msg_lines = [
(
'Failed to resolve the requested dependencies map. '
'Got the candidate {req.fqcn!s}:{req.ver!s} ({dep_origin!s}) '
'which didn\'t satisfy all of the following requirements:'.
format(
req=dep_exc.candidate,
dep_origin='direct request'
if not parents else 'dependency of {parent!s}'.
format(parent=', '.join(parents))
)
)
]
for req in dep_exc.criterion.iter_requirement():
error_msg_lines.append(
'* {req.fqcn!s}:{req.ver!s}'.format(req=req)
)
raise raise_from( # NOTE: Leading "raise" is a hack for mypy bug #9717
AnsibleError('\n'.join(error_msg_lines)),
dep_exc,
)

@ -8,4 +8,5 @@ __metaclass__ = type
from resolvelib.resolvers import ( from resolvelib.resolvers import (
ResolutionImpossible as CollectionDependencyResolutionImpossible, ResolutionImpossible as CollectionDependencyResolutionImpossible,
InconsistentCandidate as CollectionDependencyInconsistentCandidate,
) )

@ -163,6 +163,81 @@
- '"Installing ''namespace3.name:1.0.0'' to" in install_tarball.stdout' - '"Installing ''namespace3.name:1.0.0'' to" in install_tarball.stdout'
- (install_tarball_actual.content | b64decode | from_json).collection_info.version == '1.0.0' - (install_tarball_actual.content | b64decode | from_json).collection_info.version == '1.0.0'
- name: write a requirements file using the artifact and a conflicting version
copy:
content: |
collections:
- name: {{ galaxy_dir }}/namespace3.tar.gz
version: 1.2.0
dest: '{{ galaxy_dir }}/test_req.yml'
- name: install the requirements file with mismatched versions
command: ansible-galaxy collection install -r '{{ galaxy_dir }}/test_req.yml' {{ galaxy_verbosity }}
ignore_errors: True
register: result
- name: remove the requirements file
file:
path: '{{ galaxy_dir }}/test_req.yml'
state: absent
- assert:
that: error == expected_error
vars:
reset_color: '\x1b\[0m'
color: '\x1b\[[0-9];[0-9]{2}m'
error: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
expected_error: >-
ERROR! Failed to resolve the requested dependencies map.
Got the candidate namespace3.name:1.0.0 (direct request)
which didn't satisfy all of the following requirements:
* namespace3.name:1.2.0
- name: test error for mismatched dependency versions
vars:
reset_color: '\x1b\[0m'
color: '\x1b\[[0-9];[0-9]{2}m'
error: "{{ result.stderr | regex_replace(reset_color) | regex_replace(color) | regex_replace('\\n', ' ') }}"
expected_error: >-
ERROR! Failed to resolve the requested dependencies map.
Got the candidate namespace3.name:1.0.0 (dependency of tmp_parent.name:1.0.0)
which didn't satisfy all of the following requirements:
* namespace3.name:1.2.0
block:
- name: init a new parent collection
command: ansible-galaxy collection init tmp_parent.name --init-path '{{ galaxy_dir }}/scratch'
- name: replace the dependencies
lineinfile:
path: "{{ galaxy_dir }}/scratch/tmp_parent/name/galaxy.yml"
regexp: "^dependencies:*"
line: "dependencies: { '{{ galaxy_dir }}/namespace3.tar.gz': '1.2.0' }"
- name: build the new artifact
command: ansible-galaxy collection build {{ galaxy_dir }}/scratch/tmp_parent/name
args:
chdir: "{{ galaxy_dir }}"
- name: install the artifact to verify the error is handled
command: ansible-galaxy collection install '{{ galaxy_dir }}/tmp_parent-name-1.0.0.tar.gz'
ignore_errors: yes
register: result
- debug: msg="Actual - {{ error }}"
- debug: msg="Expected - {{ expected_error }}"
- assert:
that: error == expected_error
always:
- name: clean up collection skeleton and artifact
file:
state: absent
path: "{{ item }}"
loop:
- "{{ galaxy_dir }}/scratch/tmp_parent/"
- "{{ galaxy_dir }}/tmp_parent-name-1.0.0.tar.gz"
- name: setup bad tarball - {{ test_name }} - name: setup bad tarball - {{ test_name }}
script: build_bad_tar.py {{ galaxy_dir | quote }} script: build_bad_tar.py {{ galaxy_dir | quote }}

Loading…
Cancel
Save