Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/ansible_builder/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@

DEFAULT_EE_BASENAME = "execution-environment"
YAML_FILENAME_EXTENSIONS = ('yml', 'yaml')

REQUIRE_ANSIBLE_CORE_PIN = False
27 changes: 27 additions & 0 deletions src/ansible_builder/user_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import Callable

import yaml
from packaging.requirements import InvalidRequirement, Requirement

from . import constants
from .exceptions import DefinitionError
Expand Down Expand Up @@ -239,6 +240,30 @@ def _validate_additional_build_files(self):
if dest.is_absolute() or '..' in dest.parts:
raise DefinitionError(f"'dest' must not be an absolute path or contain '..': {dest}")

def _validate_ansible_core_ref(self):
"""
If a downstream has patched REQUIRE_ANSIBLE_CORE_PIN validate
that the 'ansible_core' ref contains a version constraint.

:raises: DefinitionError exception if version constraint is invalid or missing
"""
if not constants.REQUIRE_ANSIBLE_CORE_PIN:
return

ref = self.ansible_core_ref
if not ref:
return

try:
req = Requirement(ref)
except InvalidRequirement as e:
raise DefinitionError("Invalid package requirement specified for 'ansible_core'") from e

if not req.specifier:
raise DefinitionError(
"Value for 'ansible_core' must contain a version constraint, such as 'ansible-core==2.16.*'"
)

def validate(self):
"""
Check that all specified keys in the definition file are valid.
Expand All @@ -247,6 +272,8 @@ def validate(self):
"""
validate_schema(self.raw)

self._validate_ansible_core_ref()

for item in constants.CONTEXT_FILES:
for exclude in (False, True):
requirement_path = self.get_dep_abs_path(item, exclude=exclude)
Expand Down
42 changes: 39 additions & 3 deletions test/unit/test_user_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,53 @@ def test_v3_ansible_install_refs(self, exec_env_definition_file):
{'version': 3,
'images': { 'base_image': {'name': 'base_image:latest'}},
'dependencies': {
'ansible_core': {'package_pip': 'ansible-core==2.13'},
'ansible_core': {'package_pip': 'ansible-core'},
'ansible_runner': { 'package_pip': 'ansible-runner==2.3.1'}
}
}
"""
)
definition = UserDefinition(path)
definition.validate()
assert definition.ansible_core_ref == "ansible-core==2.13"
assert definition.ansible_core_ref == "ansible-core"
assert definition.ansible_runner_ref == "ansible-runner==2.3.1"
assert definition.ansible_ref_install_list == "ansible-core==2.13 ansible-runner==2.3.1"
assert definition.ansible_ref_install_list == "ansible-core ansible-runner==2.3.1"

def test_v3_ansible_install_ref_pin_required(self, monkeypatch, exec_env_definition_file):
path = exec_env_definition_file(
"""
{'version': 3,
'images': { 'base_image': {'name': 'base_image:latest'}},
'dependencies': {
'ansible_core': {'package_pip': 'ansible-core'},
'ansible_runner': { 'package_pip': 'ansible-runner==2.3.1'}
}
}
"""
)
monkeypatch.setattr(constants, 'REQUIRE_ANSIBLE_CORE_PIN', True)
definition = UserDefinition(path)
with pytest.raises(DefinitionError) as error:
definition.validate()
assert "Value for 'ansible_core' must contain a version constraint" in str(error.value.args[0])

def test_v3_ansible_install_ref_bad_req(self, monkeypatch, exec_env_definition_file):
path = exec_env_definition_file(
"""
{'version': 3,
'images': { 'base_image': {'name': 'base_image:latest'}},
'dependencies': {
'ansible_core': {'package_pip': 'ansible-core=2.6.0'},
'ansible_runner': { 'package_pip': 'ansible-runner==2.3.1'}
}
}
"""
)
monkeypatch.setattr(constants, 'REQUIRE_ANSIBLE_CORE_PIN', True)
definition = UserDefinition(path)
with pytest.raises(DefinitionError) as error:
definition.validate()
assert "Invalid package requirement specified for 'ansible_core'" in str(error.value.args[0])

def test_v3_inline_python(self, exec_env_definition_file):
"""
Expand Down