@ -19,12 +19,9 @@ from .io import (
from . util import (
from . util import (
ANSIBLE_TEST_DATA_ROOT ,
ANSIBLE_TEST_DATA_ROOT ,
ANSIBLE_TEST_TARGET_ROOT ,
ANSIBLE_TEST_TARGET_ROOT ,
ANSIBLE_TEST_TOOLS_ROOT ,
ApplicationError ,
ApplicationError ,
SubprocessError ,
SubprocessError ,
display ,
display ,
raw_command ,
version_to_str ,
)
)
from . util_common import (
from . util_common import (
@ -138,8 +135,6 @@ def install_requirements(
if command and isinstance ( args , ( UnitsConfig , IntegrationConfig ) ) and args . coverage :
if command and isinstance ( args , ( UnitsConfig , IntegrationConfig ) ) and args . coverage :
coverage = True
coverage = True
cryptography = False
if ansible :
if ansible :
try :
try :
ansible_cache = install_requirements . ansible_cache # type: ignore[attr-defined]
ansible_cache = install_requirements . ansible_cache # type: ignore[attr-defined]
@ -153,16 +148,10 @@ def install_requirements(
else :
else :
ansible_cache [ python . path ] = True
ansible_cache [ python . path ] = True
# Install the latest cryptography version that the current requirements can support if it is not already available.
# This avoids downgrading cryptography when OS packages provide a newer version than we are able to install using pip.
# If not installed here, later install commands may try to install a version of cryptography which cannot be installed.
cryptography = not is_cryptography_available ( python . path )
commands = collect_requirements (
commands = collect_requirements (
python = python ,
python = python ,
controller = controller ,
controller = controller ,
ansible = ansible ,
ansible = ansible ,
cryptography = cryptography ,
command = args . command if command else None ,
command = args . command if command else None ,
coverage = coverage ,
coverage = coverage ,
minimize = False ,
minimize = False ,
@ -197,7 +186,6 @@ def collect_requirements(
python : PythonConfig ,
python : PythonConfig ,
controller : bool ,
controller : bool ,
ansible : bool ,
ansible : bool ,
cryptography : bool ,
coverage : bool ,
coverage : bool ,
minimize : bool ,
minimize : bool ,
command : t . Optional [ str ] ,
command : t . Optional [ str ] ,
@ -209,9 +197,6 @@ def collect_requirements(
if coverage :
if coverage :
commands . extend ( collect_package_install ( packages = [ f ' coverage== { get_coverage_version ( python . version ) . coverage_version } ' ] , constraints = False ) )
commands . extend ( collect_package_install ( packages = [ f ' coverage== { get_coverage_version ( python . version ) . coverage_version } ' ] , constraints = False ) )
if cryptography :
commands . extend ( collect_package_install ( packages = get_cryptography_requirements ( python ) ) )
if ansible or command :
if ansible or command :
commands . extend ( collect_general_install ( command , ansible ) )
commands . extend ( collect_general_install ( command , ansible ) )
@ -486,60 +471,3 @@ def prepare_pip_script(commands: list[PipCommand]) -> str:
def usable_pip_file ( path : t . Optional [ str ] ) - > bool :
def usable_pip_file ( path : t . Optional [ str ] ) - > bool :
""" Return True if the specified pip file is usable, otherwise False. """
""" Return True if the specified pip file is usable, otherwise False. """
return bool ( path ) and os . path . exists ( path ) and bool ( os . path . getsize ( path ) )
return bool ( path ) and os . path . exists ( path ) and bool ( os . path . getsize ( path ) )
# Cryptography
def is_cryptography_available ( python : str ) - > bool :
""" Return True if cryptography is available for the given python. """
try :
raw_command ( [ python , ' -c ' , ' import cryptography ' ] , capture = True )
except SubprocessError :
return False
return True
def get_cryptography_requirements ( python : PythonConfig ) - > list [ str ] :
"""
Return the correct cryptography and pyopenssl requirements for the given python version .
The version of cryptography installed depends on the python version and openssl version .
"""
openssl_version = get_openssl_version ( python )
if openssl_version and openssl_version < ( 1 , 1 , 0 ) :
# cryptography 3.2 requires openssl 1.1.x or later
# see https://cryptography.io/en/latest/changelog.html#v3-2
cryptography = ' cryptography < 3.2 '
# pyopenssl 20.0.0 requires cryptography 3.2 or later
pyopenssl = ' pyopenssl < 20.0.0 '
else :
# cryptography 3.4+ builds require a working rust toolchain
# systems bootstrapped using ansible-core-ci can access additional wheels through the spare-tire package index
cryptography = ' cryptography '
# any future installation of pyopenssl is free to use any compatible version of cryptography
pyopenssl = ' '
requirements = [
cryptography ,
pyopenssl ,
]
requirements = [ requirement for requirement in requirements if requirement ]
return requirements
def get_openssl_version ( python : PythonConfig ) - > t . Optional [ tuple [ int , . . . ] ] :
""" Return the openssl version. """
version = json . loads ( raw_command ( [ python . path , os . path . join ( ANSIBLE_TEST_TOOLS_ROOT , ' sslcheck.py ' ) ] , capture = True ) [ 0 ] ) [ ' version ' ]
if version :
display . info ( f ' Detected OpenSSL version { version_to_str ( version ) } under Python { python . version } . ' , verbosity = 1 )
return tuple ( version )
display . info ( ' Unable to detect OpenSSL version. ' , verbosity = 1 )
return None