Additional ansible-test path fixes. (#60300)

* Add missing ansible-test injector symlink.
* More ansible-test path fixes.
* Expand bin-symlinks docs.
This commit is contained in:
Matt Clay 2019-08-08 23:51:03 -07:00 committed by GitHub
parent 3777c2e93d
commit df59f06d6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 35 additions and 18 deletions

View file

@ -5,3 +5,7 @@ The ``bin/`` directory in Ansible must contain only symbolic links to executable
These files must reside in the ``lib/ansible/`` or ``test/lib/ansible_test/`` directories.
This is required to allow ``ansible-test`` to work with containers and remote hosts when running from an installed version of Ansible.
Symlinks for each entry point in ``bin/`` must also be present in ``test/lib/ansible_test/_data/injector/``.
Each symlink should point to the ``python.py`` script in the same directory.
This facilitates running with the correct Python interpreter and enabling code coverage.

View file

@ -0,0 +1 @@
python.py

View file

@ -9,11 +9,10 @@ from . import types as t
from .util import (
ApplicationError,
import_plugins,
ANSIBLE_ROOT,
is_subdir,
ANSIBLE_IS_INSTALLED,
ANSIBLE_LIB_ROOT,
ANSIBLE_TEST_ROOT,
ANSIBLE_SOURCE_ROOT,
)
from .provider import (
@ -65,8 +64,8 @@ class DataContext:
if content_path:
content = self.__create_content_layout(layout_providers, source_providers, content_path, False)
elif is_subdir(current_path, ANSIBLE_ROOT):
content = self.__create_content_layout(layout_providers, source_providers, ANSIBLE_ROOT, False)
elif ANSIBLE_SOURCE_ROOT and is_subdir(current_path, ANSIBLE_SOURCE_ROOT):
content = self.__create_content_layout(layout_providers, source_providers, ANSIBLE_SOURCE_ROOT, False)
else:
content = self.__create_content_layout(layout_providers, source_providers, current_path, True)
@ -95,7 +94,7 @@ class DataContext:
def __create_ansible_source(self):
"""Return a tuple of Ansible source files with both absolute and relative paths."""
if ANSIBLE_IS_INSTALLED:
if not ANSIBLE_SOURCE_ROOT:
sources = []
source_provider = InstalledSource(ANSIBLE_LIB_ROOT)
@ -112,9 +111,9 @@ class DataContext:
return tuple((os.path.join(self.content.root, path), path) for path in self.content.all_files())
try:
source_provider = find_path_provider(SourceProvider, self.__source_providers, ANSIBLE_ROOT, False)
source_provider = find_path_provider(SourceProvider, self.__source_providers, ANSIBLE_SOURCE_ROOT, False)
except ProviderNotFoundForPath:
source_provider = UnversionedSource(ANSIBLE_ROOT)
source_provider = UnversionedSource(ANSIBLE_SOURCE_ROOT)
return tuple((os.path.join(source_provider.root, path), path) for path in source_provider.get_paths(source_provider.root))
@ -148,8 +147,8 @@ def data_init(): # type: () -> DataContext
' - an Ansible collection: {...}/ansible_collections/{namespace}/{collection}/',
]
if not ANSIBLE_IS_INSTALLED:
options.insert(0, ' - the Ansible source: %s/' % ANSIBLE_ROOT)
if ANSIBLE_SOURCE_ROOT:
options.insert(0, ' - the Ansible source: %s/' % ANSIBLE_SOURCE_ROOT)
raise ApplicationError('''The current working directory must be at or below:

View file

@ -18,7 +18,7 @@ from .config import (
from .util import (
display,
ANSIBLE_ROOT,
ANSIBLE_IS_INSTALLED,
ANSIBLE_SOURCE_ROOT,
remove_tree,
is_subdir,
)
@ -59,7 +59,7 @@ def create_payload(args, dst_path): # type: (CommonConfig, str) -> None
files = list(data_context().ansible_source)
if ANSIBLE_IS_INSTALLED:
if not ANSIBLE_SOURCE_ROOT:
# reconstruct the bin directory which is not available when running from an ansible install
files.extend(create_temporary_bin_files(args))

View file

@ -9,7 +9,7 @@ import os
from ... import types as t
from ...util import (
ANSIBLE_ROOT,
ANSIBLE_SOURCE_ROOT,
)
from .. import (
@ -82,7 +82,7 @@ class ContentLayout(Layout):
self.unit_path = unit_path
self.unit_module_path = unit_module_path
self.unit_module_utils_path = unit_module_utils_path
self.is_ansible = root == ANSIBLE_ROOT
self.is_ansible = root == ANSIBLE_SOURCE_ROOT
@property
def prefix(self): # type: () -> str

View file

@ -26,6 +26,11 @@ from ..payload import (
__file__ as symlink_map_full_path,
)
from ..util import (
ANSIBLE_BIN_PATH,
ANSIBLE_TEST_DATA_ROOT,
)
class BinSymlinksTest(SanityVersionNeutral):
"""Sanity test for symlinks in the bin directory."""
@ -48,10 +53,13 @@ class BinSymlinksTest(SanityVersionNeutral):
:type targets: SanityTargets
:rtype: TestResult
"""
bin_root = os.path.join(data_context().content.root, 'bin')
bin_root = ANSIBLE_BIN_PATH
bin_names = os.listdir(bin_root)
bin_paths = sorted(os.path.join(bin_root, path) for path in bin_names)
injector_root = os.path.join(ANSIBLE_TEST_DATA_ROOT, 'injector')
injector_names = os.listdir(injector_root)
errors = [] # type: t.List[t.Tuple[str, str]]
symlink_map_path = os.path.relpath(symlink_map_full_path, data_context().content.root)
@ -85,10 +93,15 @@ class BinSymlinksTest(SanityVersionNeutral):
errors.append((bin_path, 'points to non-executable file "%s"' % dest))
continue
for bin_path, dest in ANSIBLE_BIN_SYMLINK_MAP.items():
if bin_path not in bin_names:
for bin_name, dest in ANSIBLE_BIN_SYMLINK_MAP.items():
if bin_name not in bin_names:
bin_path = os.path.join(bin_root, bin_name)
errors.append((bin_path, 'missing symlink to "%s" defined in ANSIBLE_BIN_SYMLINK_MAP in file "%s"' % (dest, symlink_map_path)))
if bin_name not in injector_names:
injector_path = os.path.join(injector_root, bin_name)
errors.append((injector_path, 'missing symlink to "python.py"'))
messages = [SanityMessage(message=message, path=os.path.relpath(path, data_context().content.root), confidence=100) for path, message in errors]
if errors:

View file

@ -68,14 +68,14 @@ ANSIBLE_TEST_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ANSIBLE_ROOT = os.path.dirname(ANSIBLE_TEST_ROOT)
ANSIBLE_BIN_PATH = os.path.dirname(os.path.abspath(sys.argv[0]))
ANSIBLE_LIB_ROOT = os.path.join(ANSIBLE_ROOT, 'ansible')
ANSIBLE_IS_INSTALLED = True
ANSIBLE_SOURCE_ROOT = None
if not os.path.exists(ANSIBLE_LIB_ROOT):
# running from source
ANSIBLE_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(ANSIBLE_TEST_ROOT)))
ANSIBLE_BIN_PATH = os.path.join(ANSIBLE_ROOT, 'bin')
ANSIBLE_LIB_ROOT = os.path.join(ANSIBLE_ROOT, 'lib', 'ansible')
ANSIBLE_IS_INSTALLED = False
ANSIBLE_SOURCE_ROOT = ANSIBLE_ROOT
ANSIBLE_TEST_DATA_ROOT = os.path.join(ANSIBLE_TEST_ROOT, '_data')
ANSIBLE_TEST_CONFIG_ROOT = os.path.join(ANSIBLE_TEST_ROOT, 'config')