Fetch signatures from galaxy after the dependency resolver runs (#80334) (#80397)

Reduce the number of Galaxy API calls made during dependency resolution by fetching remote signatures afterwards, since these are not used in backtracking.

Reduce the verbosity to `-vvvv` (to match other Galaxy API calls) to see this activity.

Co-authored-by: Sviatoslav Sydorenko <webknjaz@redhat.com>
(cherry picked from commit 460abe0cef)
pull/80431/head
Sloane Hertel 2 years ago committed by GitHub
parent ca08c27c94
commit 4fcf731ced
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- ansible-galaxy - reduce API calls to servers by fetching signatures only for final candidates.

@ -926,8 +926,7 @@ class GalaxyAPI:
try: try:
signatures = data["signatures"] signatures = data["signatures"]
except KeyError: except KeyError:
# Noisy since this is used by the dep resolver, so require more verbosity than Galaxy calls display.vvvv(f"Server {self.api_server} has not signed {namespace}.{name}:{version}")
display.vvvvvv(f"Server {self.api_server} has not signed {namespace}.{name}:{version}")
return [] return []
else: else:
return [signature_info["signature"] for signature_info in signatures] return [signature_info["signature"] for signature_info in signatures]

@ -769,6 +769,9 @@ def install_collections(
"Skipping signature verification." "Skipping signature verification."
) )
if concrete_coll_pin.type == 'galaxy':
concrete_coll_pin = concrete_coll_pin.with_signatures_repopulated()
try: try:
install(concrete_coll_pin, output_path, artifacts_manager) install(concrete_coll_pin, output_path, artifacts_manager)
except AnsibleError as err: except AnsibleError as err:

@ -27,7 +27,7 @@ if t.TYPE_CHECKING:
) )
from ansible.errors import AnsibleError from ansible.errors import AnsibleError, AnsibleAssertionError
from ansible.galaxy.api import GalaxyAPI from ansible.galaxy.api import GalaxyAPI
from ansible.galaxy.collection import HAS_PACKAGING, PkgReq from ansible.galaxy.collection import HAS_PACKAGING, PkgReq
from ansible.module_utils._text import to_bytes, to_native, to_text from ansible.module_utils._text import to_bytes, to_native, to_text
@ -584,3 +584,13 @@ class Candidate(
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Candidate, self).__init__() super(Candidate, self).__init__()
def with_signatures_repopulated(self): # type: (Candidate) -> Candidate
"""Populate a new Candidate instance with Galaxy signatures.
:raises AnsibleAssertionError: If the supplied candidate is not sourced from a Galaxy-like index.
"""
if self.type != 'galaxy':
raise AnsibleAssertionError(f"Invalid collection type for {self!r}: unable to get signatures from a galaxy server.")
signatures = self.src.get_collection_signatures(self.namespace, self.name, self.ver)
return self.__class__(self.fqcn, self.ver, self.src, self.type, frozenset([*self.signatures, *signatures]))

@ -392,7 +392,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
if not unsatisfied: if not unsatisfied:
if self._include_signatures: if self._include_signatures:
signatures = src_server.get_collection_signatures(first_req.namespace, first_req.name, version)
for extra_source in extra_signature_sources: for extra_source in extra_signature_sources:
signatures.append(get_signature_from_source(extra_source)) signatures.append(get_signature_from_source(extra_source))
latest_matches.append( latest_matches.append(

@ -5,7 +5,7 @@
state: directory state: directory
- name: install simple collection from first accessible server - name: install simple collection from first accessible server
command: ansible-galaxy collection install namespace1.name1 {{ galaxy_verbosity }} command: ansible-galaxy collection install namespace1.name1 -vvvv
environment: environment:
ANSIBLE_COLLECTIONS_PATH: '{{ galaxy_dir }}/ansible_collections' ANSIBLE_COLLECTIONS_PATH: '{{ galaxy_dir }}/ansible_collections'
register: from_first_good_server register: from_first_good_server
@ -30,6 +30,7 @@
- install_normal_files.files[1].path | basename in ['MANIFEST.json', 'FILES.json', 'README.md'] - install_normal_files.files[1].path | basename in ['MANIFEST.json', 'FILES.json', 'README.md']
- install_normal_files.files[2].path | basename in ['MANIFEST.json', 'FILES.json', 'README.md'] - install_normal_files.files[2].path | basename in ['MANIFEST.json', 'FILES.json', 'README.md']
- (install_normal_manifest.content | b64decode | from_json).collection_info.version == '1.0.9' - (install_normal_manifest.content | b64decode | from_json).collection_info.version == '1.0.9'
- 'from_first_good_server.stdout|regex_findall("has not signed namespace1\.name1")|length == 1'
- name: Remove the collection - name: Remove the collection
file: file:

Loading…
Cancel
Save