"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/ansible/cli/galaxy.py" between
ansible-2.14.0.tar.gz and ansible-2.14.1rc1.tar.gz

About: Ansible is an IT Configuration Management, Deployment & Orchestration tool.
Release candidate.

galaxy.py  (ansible-2.14.0):galaxy.py  (ansible-2.14.1rc1)
skipping to change at line 20 skipping to change at line 20
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first # ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI from ansible.cli import CLI
import json import json
import os.path import os.path
import re import re
import shutil import shutil
import sys import sys
import textwrap import textwrap
import time import time
import typing as t
from dataclasses import dataclass
from yaml.error import YAMLError from yaml.error import YAMLError
import ansible.constants as C import ansible.constants as C
from ansible import context from ansible import context
from ansible.cli.arguments import option_helpers as opt_help from ansible.cli.arguments import option_helpers as opt_help
from ansible.errors import AnsibleError, AnsibleOptionsError from ansible.errors import AnsibleError, AnsibleOptionsError
from ansible.galaxy import Galaxy, get_collections_galaxy_meta_info from ansible.galaxy import Galaxy, get_collections_galaxy_meta_info
from ansible.galaxy.api import GalaxyAPI from ansible.galaxy.api import GalaxyAPI
from ansible.galaxy.collection import ( from ansible.galaxy.collection import (
build_collection, build_collection,
skipping to change at line 166 skipping to change at line 168
return fqcn_length, version_length return fqcn_length, version_length
def validate_signature_count(value): def validate_signature_count(value):
match = re.match(SIGNATURE_COUNT_RE, value) match = re.match(SIGNATURE_COUNT_RE, value)
if match is None: if match is None:
raise ValueError(f"{value} is not a valid signature count value") raise ValueError(f"{value} is not a valid signature count value")
return value return value
@dataclass
class RoleDistributionServer:
_api: t.Union[GalaxyAPI, None]
api_servers: list[GalaxyAPI]
@property
def api(self):
if self._api:
return self._api
for server in self.api_servers:
try:
if u'v1' in server.available_api_versions:
self._api = server
break
except Exception:
continue
if not self._api:
self._api = self.api_servers[0]
return self._api
class GalaxyCLI(CLI): class GalaxyCLI(CLI):
'''command to manage Ansible roles in shared repositories, the default of wh ich is Ansible Galaxy *https://galaxy.ansible.com*.''' '''command to manage Ansible roles in shared repositories, the default of wh ich is Ansible Galaxy *https://galaxy.ansible.com*.'''
name = 'ansible-galaxy' name = 'ansible-galaxy'
SKIP_INFO_KEYS = ("name", "description", "readme_html", "related", "summary_ fields", "average_aw_composite", "average_aw_score", "url") SKIP_INFO_KEYS = ("name", "description", "readme_html", "related", "summary_ fields", "average_aw_composite", "average_aw_score", "url")
def __init__(self, args): def __init__(self, args):
self._raw_args = args self._raw_args = args
self._implicit_role = False self._implicit_role = False
skipping to change at line 194 skipping to change at line 219
if args[1:3] == ['role', 'login']: if args[1:3] == ['role', 'login']:
display.error( display.error(
"The login command was removed in late 2020. An API key is n ow required to publish roles or collections " "The login command was removed in late 2020. An API key is n ow required to publish roles or collections "
"to Galaxy. The key can be found at https://galaxy.ansible.c om/me/preferences, and passed to the " "to Galaxy. The key can be found at https://galaxy.ansible.c om/me/preferences, and passed to the "
"ansible-galaxy CLI via a file at {0} or (insecurely) via th e `--token` " "ansible-galaxy CLI via a file at {0} or (insecurely) via th e `--token` "
"command-line argument.".format(to_text(C.GALAXY_TOKEN_PATH) )) "command-line argument.".format(to_text(C.GALAXY_TOKEN_PATH) ))
sys.exit(1) sys.exit(1)
self.api_servers = [] self.api_servers = []
self.galaxy = None self.galaxy = None
self._api = None self.lazy_role_api = None
super(GalaxyCLI, self).__init__(args) super(GalaxyCLI, self).__init__(args)
def init_parser(self): def init_parser(self):
''' create an options parser for bin/ansible ''' ''' create an options parser for bin/ansible '''
super(GalaxyCLI, self).init_parser( super(GalaxyCLI, self).init_parser(
desc="Perform various Role and Collection related operations.", desc="Perform various Role and Collection related operations.",
) )
# Common arguments that apply to more than 1 action # Common arguments that apply to more than 1 action
skipping to change at line 674 skipping to change at line 699
# Default to C.GALAXY_SERVER if no servers were defined # Default to C.GALAXY_SERVER if no servers were defined
if len(self.api_servers) == 0: if len(self.api_servers) == 0:
self.api_servers.append(GalaxyAPI( self.api_servers.append(GalaxyAPI(
self.galaxy, 'default', C.GALAXY_SERVER, token=cmd_token, self.galaxy, 'default', C.GALAXY_SERVER, token=cmd_token,
priority=0, priority=0,
validate_certs=validate_certs, validate_certs=validate_certs,
**galaxy_options **galaxy_options
)) ))
# checks api versions once a GalaxyRole makes an api call
# self.api can be used to evaluate the best server immediately
self.lazy_role_api = RoleDistributionServer(None, self.api_servers)
return context.CLIARGS['func']() return context.CLIARGS['func']()
@property @property
def api(self): def api(self):
if self._api: return self.lazy_role_api.api
return self._api
for server in self.api_servers:
try:
if u'v1' in server.available_api_versions:
self._api = server
break
except Exception:
continue
if not self._api:
self._api = self.api_servers[0]
return self._api
def _get_default_collection_path(self): def _get_default_collection_path(self):
return C.COLLECTIONS_PATHS[0] return C.COLLECTIONS_PATHS[0]
def _parse_requirements_file(self, requirements_file, allow_old_format=True, artifacts_manager=None, validate_signature_options=True): def _parse_requirements_file(self, requirements_file, allow_old_format=True, artifacts_manager=None, validate_signature_options=True):
""" """
Parses an Ansible requirement.yml file and returns all the roles and/or collections defined in it. There are 2 Parses an Ansible requirement.yml file and returns all the roles and/or collections defined in it. There are 2
requirements file format: requirements file format:
# v1 (roles only) # v1 (roles only)
skipping to change at line 753 skipping to change at line 768
if file_requirements is None: if file_requirements is None:
raise AnsibleError("No requirements found in file '%s'" % to_native( requirements_file)) raise AnsibleError("No requirements found in file '%s'" % to_native( requirements_file))
def parse_role_req(requirement): def parse_role_req(requirement):
if "include" not in requirement: if "include" not in requirement:
role = RoleRequirement.role_yaml_parse(requirement) role = RoleRequirement.role_yaml_parse(requirement)
display.vvv("found role %s in yaml file" % to_text(role)) display.vvv("found role %s in yaml file" % to_text(role))
if "name" not in role and "src" not in role: if "name" not in role and "src" not in role:
raise AnsibleError("Must specify name or src for role") raise AnsibleError("Must specify name or src for role")
return [GalaxyRole(self.galaxy, self.api, **role)] return [GalaxyRole(self.galaxy, self.lazy_role_api, **role)]
else: else:
b_include_path = to_bytes(requirement["include"], errors="surrog ate_or_strict") b_include_path = to_bytes(requirement["include"], errors="surrog ate_or_strict")
if not os.path.isfile(b_include_path): if not os.path.isfile(b_include_path):
raise AnsibleError("Failed to find include requirements file '%s' in '%s'" raise AnsibleError("Failed to find include requirements file '%s' in '%s'"
% (to_native(b_include_path), to_native(r equirements_file))) % (to_native(b_include_path), to_native(r equirements_file)))
with open(b_include_path, 'rb') as f_include: with open(b_include_path, 'rb') as f_include:
try: try:
return [GalaxyRole(self.galaxy, self.api, **r) for r in return [GalaxyRole(self.galaxy, self.lazy_role_api, **r) for r in
(RoleRequirement.role_yaml_parse(i) for i in yam l_load(f_include))] (RoleRequirement.role_yaml_parse(i) for i in yam l_load(f_include))]
except Exception as e: except Exception as e:
raise AnsibleError("Unable to load data from include req uirements file: %s %s" raise AnsibleError("Unable to load data from include req uirements file: %s %s"
% (to_native(requirements_file), to_n ative(e))) % (to_native(requirements_file), to_n ative(e)))
if isinstance(file_requirements, list): if isinstance(file_requirements, list):
# Older format that contains only roles # Older format that contains only roles
if not allow_old_format: if not allow_old_format:
raise AnsibleError("Expecting requirements file to be a dict wit h the key 'collections' that contains " raise AnsibleError("Expecting requirements file to be a dict wit h the key 'collections' that contains "
"a list of collections to install") "a list of collections to install")
skipping to change at line 1178 skipping to change at line 1193
""" """
prints out detailed information about an installed role as well as info available from the galaxy API. prints out detailed information about an installed role as well as info available from the galaxy API.
""" """
roles_path = context.CLIARGS['roles_path'] roles_path = context.CLIARGS['roles_path']
data = '' data = ''
for role in context.CLIARGS['args']: for role in context.CLIARGS['args']:
role_info = {'path': roles_path} role_info = {'path': roles_path}
gr = GalaxyRole(self.galaxy, self.api, role) gr = GalaxyRole(self.galaxy, self.lazy_role_api, role)
install_info = gr.install_info install_info = gr.install_info
if install_info: if install_info:
if 'version' in install_info: if 'version' in install_info:
install_info['installed_version'] = install_info['version'] install_info['installed_version'] = install_info['version']
del install_info['version'] del install_info['version']
role_info.update(install_info) role_info.update(install_info)
if not context.CLIARGS['offline']: if not context.CLIARGS['offline']:
remote_data = None remote_data = None
skipping to change at line 1323 skipping to change at line 1338
display_func = display.warning if self._implicit_role else d isplay.vvv display_func = display.warning if self._implicit_role else d isplay.vvv
display_func(two_type_warning.format('collection')) display_func(two_type_warning.format('collection'))
else: else:
collection_path = self._get_default_collection_path() collection_path = self._get_default_collection_path()
collection_requirements = requirements['collections'] collection_requirements = requirements['collections']
else: else:
# roles were specified directly, so we'll just go out grab them # roles were specified directly, so we'll just go out grab them
# (and their dependencies, unless the user doesn't want us to). # (and their dependencies, unless the user doesn't want us to).
for rname in context.CLIARGS['args']: for rname in context.CLIARGS['args']:
role = RoleRequirement.role_yaml_parse(rname.strip()) role = RoleRequirement.role_yaml_parse(rname.strip())
role_requirements.append(GalaxyRole(self.galaxy, self.api, * *role)) role_requirements.append(GalaxyRole(self.galaxy, self.lazy_r ole_api, **role))
if not role_requirements and not collection_requirements: if not role_requirements and not collection_requirements:
display.display("Skipping install, no requirements found") display.display("Skipping install, no requirements found")
return return
if role_requirements: if role_requirements:
display.display("Starting galaxy role install process") display.display("Starting galaxy role install process")
self._execute_install_role(role_requirements) self._execute_install_role(role_requirements)
if collection_requirements: if collection_requirements:
skipping to change at line 1434 skipping to change at line 1449
if not no_deps and installed: if not no_deps and installed:
if not role.metadata: if not role.metadata:
# NOTE: the meta file is also required for installing the ro le, not just dependencies # NOTE: the meta file is also required for installing the ro le, not just dependencies
display.warning("Meta file %s is empty. Skipping dependencie s." % role.path) display.warning("Meta file %s is empty. Skipping dependencie s." % role.path)
else: else:
role_dependencies = role.metadata_dependencies + role.requir ements role_dependencies = role.metadata_dependencies + role.requir ements
for dep in role_dependencies: for dep in role_dependencies:
display.debug('Installing dep %s' % dep) display.debug('Installing dep %s' % dep)
dep_req = RoleRequirement() dep_req = RoleRequirement()
dep_info = dep_req.role_yaml_parse(dep) dep_info = dep_req.role_yaml_parse(dep)
dep_role = GalaxyRole(self.galaxy, self.api, **dep_info) dep_role = GalaxyRole(self.galaxy, self.lazy_role_api, * *dep_info)
if '.' not in dep_role.name and '.' not in dep_role.src and dep_role.scm is None: if '.' not in dep_role.name and '.' not in dep_role.src and dep_role.scm is None:
# we know we can skip this, as it's not going to # we know we can skip this, as it's not going to
# be found on galaxy.ansible.com # be found on galaxy.ansible.com
continue continue
if dep_role.install_info is None: if dep_role.install_info is None:
if dep_role not in requirements: if dep_role not in requirements:
display.display('- adding dependency: %s' % to_t ext(dep_role)) display.display('- adding dependency: %s' % to_t ext(dep_role))
requirements.append(dep_role) requirements.append(dep_role)
else: else:
display.display('- dependency %s already pending installation.' % dep_role.name) display.display('- dependency %s already pending installation.' % dep_role.name)
skipping to change at line 1518 skipping to change at line 1533
for path in roles_search_paths: for path in roles_search_paths:
role_path = GalaxyCLI._resolve_path(path) role_path = GalaxyCLI._resolve_path(path)
if os.path.isdir(path): if os.path.isdir(path):
path_found = True path_found = True
else: else:
warnings.append("- the configured path {0} does not exist.".form at(path)) warnings.append("- the configured path {0} does not exist.".form at(path))
continue continue
if role_name: if role_name:
# show the requested role, if it exists # show the requested role, if it exists
gr = GalaxyRole(self.galaxy, self.api, role_name, path=os.path.j oin(role_path, role_name)) gr = GalaxyRole(self.galaxy, self.lazy_role_api, role_name, path =os.path.join(role_path, role_name))
if os.path.isdir(gr.path): if os.path.isdir(gr.path):
role_found = True role_found = True
display.display('# %s' % os.path.dirname(gr.path)) display.display('# %s' % os.path.dirname(gr.path))
_display_role(gr) _display_role(gr)
break break
warnings.append("- the role %s was not found" % role_name) warnings.append("- the role %s was not found" % role_name)
else: else:
if not os.path.exists(role_path): if not os.path.exists(role_path):
warnings.append("- the configured path %s does not exist." % role_path) warnings.append("- the configured path %s does not exist." % role_path)
continue continue
if not os.path.isdir(role_path): if not os.path.isdir(role_path):
warnings.append("- the configured path %s, exists, but it is not a directory." % role_path) warnings.append("- the configured path %s, exists, but it is not a directory." % role_path)
continue continue
display.display('# %s' % role_path) display.display('# %s' % role_path)
path_files = os.listdir(role_path) path_files = os.listdir(role_path)
for path_file in path_files: for path_file in path_files:
gr = GalaxyRole(self.galaxy, self.api, path_file, path=path) gr = GalaxyRole(self.galaxy, self.lazy_role_api, path_file, path=path)
if gr.metadata: if gr.metadata:
_display_role(gr) _display_role(gr)
# Do not warn if the role was found in any of the search paths # Do not warn if the role was found in any of the search paths
if role_found and role_name: if role_found and role_name:
warnings = [] warnings = []
for w in warnings: for w in warnings:
display.warning(w) display.warning(w)
 End of changes. 13 change blocks. 
23 lines changed or deleted 38 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)