From 41783a7e1d8fefb3cec25d7cd840fdf349456b58 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Wed, 19 May 2021 18:56:45 -0400 Subject: [PATCH 1/5] optimize config for making it on demand --- lib/ansible/constants.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index c2ce7e5ec9d..d04464e9b58 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -5,6 +5,8 @@ from __future__ import annotations import re +import sys +import types from string import ascii_letters, digits @@ -13,18 +15,12 @@ from ansible.module_utils.common.text.converters import to_text from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE from ansible.utils.fqcn import add_internal_fqcns + # initialize config manager/config data to read/store global settings # and generate 'pseudo constants' for app consumption. config = ConfigManager() - -def set_constant(name, value, export=vars()): - """ sets constants and returns resolved options dict """ - export[name] = value - - # CONSTANTS ### yes, actual ones - # The following are hard-coded action names _ACTION_DEBUG = add_internal_fqcns(('debug', )) _ACTION_IMPORT_PLAYBOOK = add_internal_fqcns(('import_playbook', )) @@ -131,13 +127,11 @@ VAULT_VERSION_MAX = 1.0 # This matches a string that cannot be used as a valid python variable name i.e 'not-valid', 'not!valid@either' '1_nor_This' INVALID_VARIABLE_NAMES = re.compile(r'^[\d\W]|[^\w]') - # FIXME: remove once play_context mangling is removed # the magic variable mapping dictionary below is used to translate # host/inventory variables to fields in the PlayContext # object. The dictionary values are tuples, to account for aliases # in variable names. - COMMON_CONNECTION_VARS = frozenset(('ansible_connection', 'ansible_host', 'ansible_user', 'ansible_shell_executable', 'ansible_port', 'ansible_pipelining', 'ansible_password', 'ansible_timeout', 'ansible_shell_type', 'ansible_module_compression', 'ansible_private_key_file')) @@ -183,6 +177,21 @@ MAGIC_VARIABLE_MAPPING = dict( become_flags=('ansible_become_flags', ), ) -# POPULATE SETTINGS FROM CONFIG ### -for setting in config.get_configuration_definitions(): - set_constant(setting, config.get_config_value(setting, variables=vars())) +### Generate C. ### +_me = sys.modules[__name__] + + +def __getattr__(name): + """ + Dynamically load constants from settings + """ + try: + value = _me.__dict__[name] + except KeyError as e: + try: + value = config.get_config_value(name) + setattr(_me, name, value) + except: + raise AttributeError from e + + return value From 8569adf3f7c91bb04d6e3ad0d836920d906c8a35 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 10 Jun 2025 16:22:05 -0400 Subject: [PATCH 2/5] remove unused --- lib/ansible/constants.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index d04464e9b58..4a50441b6ae 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -6,7 +6,6 @@ from __future__ import annotations import re import sys -import types from string import ascii_letters, digits From d73f4c0194187e5b7569e332a69668f7b84a75f7 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 10 Jun 2025 16:23:13 -0400 Subject: [PATCH 3/5] no need anymore --- lib/ansible/constants.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index 4a50441b6ae..da31f82f439 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -20,6 +20,7 @@ from ansible.utils.fqcn import add_internal_fqcns config = ConfigManager() # CONSTANTS ### yes, actual ones + # The following are hard-coded action names _ACTION_DEBUG = add_internal_fqcns(('debug', )) _ACTION_IMPORT_PLAYBOOK = add_internal_fqcns(('import_playbook', )) @@ -67,9 +68,8 @@ DEFAULT_BECOME_PASS = None DEFAULT_PASSWORD_CHARS = to_text(ascii_letters + digits + ".,:-_", errors='strict') # characters included in auto-generated passwords DEFAULT_REMOTE_PASS = None DEFAULT_SUBSET = None -# FIXME: expand to other plugins, but never doc fragments + CONFIGURABLE_PLUGINS = ('become', 'cache', 'callback', 'cliconf', 'connection', 'httpapi', 'inventory', 'lookup', 'netconf', 'shell', 'vars') -# NOTE: always update the docs/docsite/Makefile to match DOCUMENTABLE_PLUGINS = CONFIGURABLE_PLUGINS + ('module', 'strategy', 'test', 'filter') IGNORE_FILES = ("COPYING", "CONTRIBUTING", "LICENSE", "README", "VERSION", "GUIDELINES", "MANIFEST", "Makefile") # ignore during module search INTERNAL_RESULT_KEYS = ('add_host', 'add_group') From de65172db0e39dce1b9293e474021706ee99cdfa Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 10 Jun 2025 16:23:46 -0400 Subject: [PATCH 4/5] wsp --- lib/ansible/constants.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index da31f82f439..4d3480e8134 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -14,7 +14,6 @@ from ansible.module_utils.common.text.converters import to_text from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE from ansible.utils.fqcn import add_internal_fqcns - # initialize config manager/config data to read/store global settings # and generate 'pseudo constants' for app consumption. config = ConfigManager() From 1b4debec7014302276e3b3175b701f73b96fd0e2 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 10 Jun 2025 16:31:13 -0400 Subject: [PATCH 5/5] clog and ci_complete --- .../fragments/dynamic_config_loading.yml | 2 ++ lib/ansible/constants.py | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/dynamic_config_loading.yml diff --git a/changelogs/fragments/dynamic_config_loading.yml b/changelogs/fragments/dynamic_config_loading.yml new file mode 100644 index 00000000000..b549d06cdc0 --- /dev/null +++ b/changelogs/fragments/dynamic_config_loading.yml @@ -0,0 +1,2 @@ +minor_changes: + - configuration constants are now loaded on demand. There should be a very slight delay in access of ``C.`` on first access but this also should very slightly enhance Ansible performance diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index 4d3480e8134..2f9ba317312 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -177,19 +177,20 @@ MAGIC_VARIABLE_MAPPING = dict( ### Generate C. ### _me = sys.modules[__name__] +_C = {} def __getattr__(name): """ Dynamically load constants from settings """ - try: - value = _me.__dict__[name] - except KeyError as e: + if name not in _C: try: - value = config.get_config_value(name) - setattr(_me, name, value) - except: - raise AttributeError from e - - return value + return _me.__dict__[name] + except KeyError as e: + try: + value = config.get_config_value(name) + _C[name] = value + except: + raise AttributeError from e + return _C[name]