summaryrefslogtreecommitdiff
path: root/lib/ansible/cli
diff options
context:
space:
mode:
authorLee Garrett <lgarrett@rocketjump.eu>2022-12-13 16:16:06 +0100
committerLee Garrett <lgarrett@rocketjump.eu>2022-12-13 16:16:06 +0100
commit46bbbf9f8e527b7ab4329a0aa16e3d38bfbb0c13 (patch)
treec4925ce2c3e7691925ebd7cbc4706707cdfcd86f /lib/ansible/cli
parenta6f601d820bf261c5f160bfcadb7ca6aa14d6ec2 (diff)
downloaddebian-ansible-core-46bbbf9f8e527b7ab4329a0aa16e3d38bfbb0c13.zip
New upstream version 2.14.1
Diffstat (limited to 'lib/ansible/cli')
-rwxr-xr-xlib/ansible/cli/galaxy.py62
-rwxr-xr-xlib/ansible/cli/pull.py3
2 files changed, 42 insertions, 23 deletions
diff --git a/lib/ansible/cli/galaxy.py b/lib/ansible/cli/galaxy.py
index acc3f120..f4148d92 100755
--- a/lib/ansible/cli/galaxy.py
+++ b/lib/ansible/cli/galaxy.py
@@ -17,7 +17,9 @@ import shutil
import sys
import textwrap
import time
+import typing as t
+from dataclasses import dataclass
from yaml.error import YAMLError
import ansible.constants as C
@@ -170,6 +172,30 @@ def validate_signature_count(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):
'''command to manage Ansible roles in shared repositories, the default of which is Ansible Galaxy *https://galaxy.ansible.com*.'''
@@ -198,7 +224,7 @@ class GalaxyCLI(CLI):
self.api_servers = []
self.galaxy = None
- self._api = None
+ self.lazy_role_api = None
super(GalaxyCLI, self).__init__(args)
def init_parser(self):
@@ -678,25 +704,15 @@ class GalaxyCLI(CLI):
**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']()
@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
+ return self.lazy_role_api.api
def _get_default_collection_path(self):
return C.COLLECTIONS_PATHS[0]
@@ -757,7 +773,7 @@ class GalaxyCLI(CLI):
display.vvv("found role %s in yaml file" % to_text(role))
if "name" not in role and "src" not in 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:
b_include_path = to_bytes(requirement["include"], errors="surrogate_or_strict")
if not os.path.isfile(b_include_path):
@@ -766,7 +782,7 @@ class GalaxyCLI(CLI):
with open(b_include_path, 'rb') as f_include:
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 yaml_load(f_include))]
except Exception as e:
raise AnsibleError("Unable to load data from include requirements file: %s %s"
@@ -1182,7 +1198,7 @@ class GalaxyCLI(CLI):
for role in context.CLIARGS['args']:
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
if install_info:
@@ -1327,7 +1343,7 @@ class GalaxyCLI(CLI):
# (and their dependencies, unless the user doesn't want us to).
for rname in context.CLIARGS['args']:
role = RoleRequirement.role_yaml_parse(rname.strip())
- role_requirements.append(GalaxyRole(self.galaxy, self.api, **role))
+ role_requirements.append(GalaxyRole(self.galaxy, self.lazy_role_api, **role))
if not role_requirements and not collection_requirements:
display.display("Skipping install, no requirements found")
@@ -1438,7 +1454,7 @@ class GalaxyCLI(CLI):
display.debug('Installing dep %s' % dep)
dep_req = RoleRequirement()
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:
# we know we can skip this, as it's not going to
# be found on galaxy.ansible.com
@@ -1522,7 +1538,7 @@ class GalaxyCLI(CLI):
if role_name:
# show the requested role, if it exists
- gr = GalaxyRole(self.galaxy, self.api, role_name, path=os.path.join(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):
role_found = True
display.display('# %s' % os.path.dirname(gr.path))
@@ -1541,7 +1557,7 @@ class GalaxyCLI(CLI):
display.display('# %s' % role_path)
path_files = os.listdir(role_path)
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:
_display_role(gr)
diff --git a/lib/ansible/cli/pull.py b/lib/ansible/cli/pull.py
index 99da8c4f..dc8f055b 100755
--- a/lib/ansible/cli/pull.py
+++ b/lib/ansible/cli/pull.py
@@ -38,6 +38,9 @@ class PullCLI(CLI):
This inverts the default *push* architecture of ansible into a *pull* architecture,
which has near-limitless scaling potential.
+ None of the CLI tools are designed to run concurrently with themselves,
+ you should use an external scheduler and/or locking to ensure there are no clashing operations.
+
The setup playbook can be tuned to change the cron frequency, logging locations, and parameters to ansible-pull.
This is useful both for extreme scale-out as well as periodic remediation.
Usage of the 'fetch' module to retrieve logs from ansible-pull runs would be an