Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General upgrade of dependencies #3682

Merged
merged 2 commits into from May 23, 2019

Conversation

AlanCoding
Copy link
Member

SUMMARY

This upgrades using the pip-compile dependency resolution. Only very few manually-pinned things are upgraded here, and generally done so to pick up CVE fixes.

ISSUE TYPE
  • Feature Pull Request
  • Bugfix Pull Request
COMPONENT NAME
  • API
AWX VERSION
4.0.0
ADDITIONAL INFORMATION

There will be a lot of additional information on this. The upgrade agenda items were the following:

  • kombu
  • Django<2.0
  • pyyaml
  • (in ansible venv) cryptography & paramiko

Covering what's listed in:
https://github.com/ansible/awx/network/alerts

kombu

I very specifically want this fix:

celery/kombu#880

Because I believe it'll keep awx-manage run_dispatcher --status from hanging
when rabbit becomes unresponsive, and will give a timeout error instead. Version 4.5.0 will pick that up (we could do much lower, if needed).

Django

Old: 1.11.16
New: 1.11.20

Versions .18 and .19 have CVEs the other two are single-item fixes, prevent crashing, fixed packaging. Hopefully this doesn't mess with FIPS???

pyyaml

This had a CVE, and if you upgrade it will start to issue an annoying warning if you don't pass in the loader. The fix was picked up by running the pip tool

cryptography

github suggests cryptography>=2.3
pip-compile gave cryptography==2.6.1

no problem there

paramiko

github suggests paramiko>=2.4.2
pip-compile gave paramiko==2.4.2

no problem there.

related:
#3466

@softwarefactory-project-zuul
Copy link
Contributor

Build failed.

@AlanCoding AlanCoding changed the title General upgrade of dependencies [WIP] General upgrade of dependencies Apr 11, 2019
@AlanCoding
Copy link
Member Author

python websocket-client has changed its license

websocket-client/websocket-client@e94ed9e

Ping @wenottingham this change to BSD, that okay?

@softwarefactory-project-zuul
Copy link
Contributor

Merge Failed.

This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@AlanCoding
Copy link
Member Author

This seems to have introduced some problems with openssl

awx_1        | :0: UserWarning: You do not have a working installation of the service_identity module: 'cannot import name 'verify_ip_address''.  Please install it from <https://pypi.python.org/pypi/service_identity> and make sure all of its dependencies are satisfied.  Without the service_identity module, Twisted can perform only rudimentary TLS client hostname verification.  Many valid certificate/hostname mappings may be rejected.

And trying to install pycurl

(buildit4) bash-4.2# pip install pycurl
Collecting pycurl
  Using cached https://files.pythonhosted.org/packages/e8/e4/0dbb8735407189f00b33d84122b9be52c790c7c3b25286826f4e1bdb7bde/pycurl-7.43.0.2.tar.gz
    Complete output from command python setup.py egg_info:
    Using curl-config (libcurl 7.29.0)
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-k_qxiuk1/pycurl/setup.py", line 913, in <module>
        ext = get_extension(sys.argv, split_extension_source=split_extension_source)
      File "/tmp/pip-install-k_qxiuk1/pycurl/setup.py", line 582, in get_extension
        ext_config = ExtensionConfiguration(argv)
      File "/tmp/pip-install-k_qxiuk1/pycurl/setup.py", line 99, in __init__
        self.configure()
      File "/tmp/pip-install-k_qxiuk1/pycurl/setup.py", line 316, in configure_unix
        specify the SSL backend manually.''')
    __main__.ConfigurationError: Curl is configured to use SSL, but we have not been able to determine which SSL backend it is using. Please see PycURL documentation for how to specify the SSL backend manually.
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-k_qxiuk1/pycurl/

I'll be looking into that.

@AlanCoding
Copy link
Member Author

Making progress on a few issues here.

pycurl

This will not install if you get the new version. The old version will install, and that's why the problem has not been faced before. By pinning the requirement, it seems that we can stabilize this tool again, and I will do that shortly.

@rooftopcellist as we discussed, this will restore the tool to functionality for Ansible requirements.

Ansible venv python2 vs python3

The current instructions do not consider py2 vs py3 in building the Ansible venv. It also seems that the pip compile tool does not handle the switches when making 1 file.

Now I have a bit of an answer as to how we can get this back to maintainability - right now, to remake the file as it is, you have to use py2.

I tried with py3 and got this diff:

diff --git a/requirements/requirements_ansible.txt b/requirements/requirements_ansible.txt
index 5aac69dd26..221acf0f35 100644
--- a/requirements/requirements_ansible.txt
+++ b/requirements/requirements_ansible.txt
@@ -43,18 +43,14 @@ certifi==2019.3.9         # via msrest, requests
 cffi==1.12.2              # via bcrypt, cryptography, pynacl
 chardet==3.0.4            # via requests
 colorama==0.4.1           # via azure-cli-core, knack
-configparser==3.7.4       # via entrypoints
 cryptography==2.6.1       # via adal, azure-keyvault, azure-storage, openstacksdk, paramiko, pyopenssl, requests-kerberos, requests-ntlm, secretstorage
 decorator==4.4.0          # via dogpile.cache, openstacksdk
 docutils==0.14            # via botocore
 dogpile.cache==0.7.1      # via openstacksdk
 entrypoints==0.3          # via keyring
-enum34==1.1.6; python_version < '3' # via cryptography, knack, msrest, ovirt-engine-sdk-python
-futures==3.2.0; python_version < '3' # via openstacksdk, s3transfer
 google-auth==1.6.2
 humanfriendly==4.18       # via azure-cli-core
 idna==2.8                 # via requests
-ipaddress==1.0.22         # via cryptography, openstacksdk
 iso8601==0.1.12           # via keystoneauth1, openstacksdk
 isodate==0.6.0            # via msrest
 jinja2==2.10
@@ -66,7 +62,6 @@ keystoneauth1==3.13.1     # via openstacksdk
 knack==0.3.3              # via azure-cli-core
 lxml==4.3.3               # via ncclient, pyvmomi
 markupsafe==1.1.1         # via jinja2
-monotonic==1.5            # via humanfriendly
 msrest==0.4.29
 msrestazure==0.4.31
 munch==2.3.2              # via openstacksdk

so... obviously, we should not be manually trying to decide which libraries are not needed in python3. I will sketch kind of a rough proposal for how we can encode this into the formal process moving forward.

@wenottingham I'm looking at #3550 here. I'm not against splitting these out into 2 files in the future (after all, python2 should eventually die), but to keep these changes as minimal as possible, I'd like to see about wrapping up with the single consolidated fine for this development cycle.

git dependency resolution

In jazzband/pip-tools#476, it looks like the problem referenced in this text:

As of pip-tools 1.8.1 pip-compile does not resolve packages specified using a git url. Thus, dependencies for things like dm.xmlsec.binding do not get resolved and output to requirements.txt.

Is resolved. However, again, it's clear that common practice has already been that the git requirements are no longer maintained as part of the dependency tree. Maybe it would be good to add them back in and thus allow the pip-compile tool to handle dependencies such as those. @chrismeyersfsu right now my plan is just to delete all mentions of git+ dependencies.


* Both pip and setuptools need to be added back into `requirements_ansible.txt`

* Python3 exceptions need to be re-added back to `requirements_ansible.txt`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alternatively, #3550

If any library has a change to its license with the upgrde, then the license for that library
inside of `docs/licenses` needs to be updated.

For certain libraries, a tarball of the library is kept along with the license.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For libraries that have source distribution requirements (LGPL as an example), a tarball...

@AlanCoding
Copy link
Member Author

New info @ryanpetrello, the pip & setuptools requirements were lost in this change:

https://github.com/ansible/awx/pull/3269/files#diff-444e80f30bd2f1e25b779966c9621b9bL112

Every time upgrades are done, it requires manual intervention to maintain these. I've added a blurb to the README to enshrine this in the expected practices. I'm not saying we necessarily want to keep these libraries and this practice. Since they were only just lost in this development cycle, I just have to add them back to be change-adverse.

jinja2==2.10 # required for native jinja2 types for inventory compat mode
# netconf for network modules
ncclient==0.6.3
# netaddr filter
netaddr
# oVirt/RHV
# oVirt/RHV (see README about pip-compile problem)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing

@AlanCoding
Copy link
Member Author

Here's the result of doing the 2 different files I mention in the README:

(buildit_py2) bash-4.2# diff requirements/requirements_ansible_py3.txt requirements/requirements_ansible.txt
5c5
< #    pip-compile --output-file requirements/requirements_ansible_py3.txt requirements/requirements_ansible.in
---
> #    pip-compile --output-file requirements/requirements_ansible.txt requirements/requirements_ansible.in
45a46
> configparser==3.7.4       # via entrypoints
50a52,53
> enum34==1.1.6             # via cryptography, knack, msrest, ovirt-engine-sdk-python
> futures==3.2.0            # via openstacksdk, s3transfer
53a57
> ipaddress==1.0.22         # via cryptography, openstacksdk
56d59
< jeepney==0.4              # via secretstorage
61c64
< keyring==19.0.1           # via msrestazure
---
> keyring==18.0.1           # via msrestazure
65a69
> monotonic==1.5            # via humanfriendly
105c109
< secretstorage==3.1.1      # via keyring
---
> secretstorage==2.3.1      # via keyring

You'll notice that this is different from the above diff I shared. I have found this to be (bizarrely) reproducible.

It seems that creating new requirements file, as opposed to modify the previously existing python2 file will cause the python3 pip-compile to make different decisions. That might argue in favor of using different requirements files.

I know that some of our version-specific requirements come from:

https://github.com/openstack/openstacksdk/blob/81bb77fe30e54715f836a4d27ed041125063088a/requirements.txt

The other kind of case (which may become increasingly common) is:

https://github.com/mitya57/secretstorage/blob/master/changelog#L33

A library becomes incompatible with python 2. By separating the files, we allow python3 to continue with upgrades, but python 2 declines any version that's not compatible with it. Keeping the single consolidated file, this isn't really possible.

I'm just trying to get the facts out there for this decision.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@AlanCoding
Copy link
Member Author

The known item that still needs to be resolved with this is the warning I mentioned above. Here is that warning turned into an error:

(awx) bash-4.2$ python -W error $(which awx-manage)
Traceback (most recent call last):
  File "/usr/local/bin/awx-manage", line 9, in <module>
    load_entry_point('awx', 'console_scripts', 'awx-manage')()
  File "/awx_devel/awx/__init__.py", line 124, in manage
    prepare_env()
  File "/awx_devel/awx/__init__.py", line 89, in prepare_env
    if not settings.DEBUG: # pragma: no cover
  File "/venv/awx/lib64/python3.6/site-packages/django/conf/__init__.py", line 56, in __getattr__
    self._setup(name)
  File "/venv/awx/lib64/python3.6/site-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/venv/awx/lib64/python3.6/site-packages/django/conf/__init__.py", line 110, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/awx_devel/awx/settings/development.py", line 22, in <module>
    from .defaults import *  # NOQA
  File "/awx_devel/awx/settings/defaults.py", line 8, in <module>
    from celery.schedules import crontab
  File "/venv/awx/lib64/python3.6/site-packages/celery/schedules.py", line 13, in <module>
    from . import current_app
  File "<frozen importlib._bootstrap>", line 1020, in _handle_fromlist
  File "/venv/awx/lib64/python3.6/site-packages/celery/local.py", line 509, in __getattr__
    module = __import__(self._object_origins[name], None, None, [name])
  File "/venv/awx/lib64/python3.6/site-packages/celery/_state.py", line 17, in <module>
    from celery.utils.threads import LocalStack
  File "/venv/awx/lib64/python3.6/site-packages/celery/utils/__init__.py", line 9, in <module>
    from .nodenames import worker_direct, nodename, nodesplit
  File "/venv/awx/lib64/python3.6/site-packages/celery/utils/nodenames.py", line 9, in <module>
    from kombu.entity import Exchange, Queue
  File "/venv/awx/lib64/python3.6/site-packages/kombu/entity.py", line 9, in <module>
    from .serialization import prepare_accept_content
  File "/venv/awx/lib64/python3.6/site-packages/kombu/serialization.py", line 396, in <module>
    register_msgpack()
  File "/venv/awx/lib64/python3.6/site-packages/kombu/serialization.py", line 365, in register_msgpack
    import msgpack
  File "/venv/awx/lib64/python3.6/site-packages/msgpack/__init__.py", line 25, in <module>
    from msgpack._packer import Packer
  File "msgpack/_packer.pyx", line 8, in init msgpack._packer
ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__

digging into that.

To download the PyPI tarball, you can run this command:

```
pip download <pypi library name> -d docs/licenses/ --no-binary :all: --no-deps
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Man, thanks for putting in the legwork to get this process documented better. It needed some love.

@AlanCoding
Copy link
Member Author

ansible/asgi_amqp#6

Verification within this environment:

(awx) bash-4.2# python -W error $(which awx-manage)
Traceback (most recent call last):
  File "/usr/local/bin/awx-manage", line 9, in <module>
    load_entry_point('awx', 'console_scripts', 'awx-manage')()
  File "/awx_devel/awx/__init__.py", line 124, in manage
    prepare_env()
  File "/awx_devel/awx/__init__.py", line 89, in prepare_env
    if not settings.DEBUG: # pragma: no cover
  File "/venv/awx/lib64/python3.6/site-packages/django/conf/__init__.py", line 56, in __getattr__
    self._setup(name)
  File "/venv/awx/lib64/python3.6/site-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/venv/awx/lib64/python3.6/site-packages/django/conf/__init__.py", line 110, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/awx_devel/awx/settings/development.py", line 22, in <module>
    from .defaults import *  # NOQA
  File "/awx_devel/awx/settings/defaults.py", line 8, in <module>
    from celery.schedules import crontab
  File "/venv/awx/lib64/python3.6/site-packages/celery/schedules.py", line 13, in <module>
    from . import current_app
  File "<frozen importlib._bootstrap>", line 1020, in _handle_fromlist
  File "/venv/awx/lib64/python3.6/site-packages/celery/local.py", line 509, in __getattr__
    module = __import__(self._object_origins[name], None, None, [name])
  File "/venv/awx/lib64/python3.6/site-packages/celery/_state.py", line 17, in <module>
    from celery.utils.threads import LocalStack
  File "/venv/awx/lib64/python3.6/site-packages/celery/utils/__init__.py", line 9, in <module>
    from .nodenames import worker_direct, nodename, nodesplit
  File "/venv/awx/lib64/python3.6/site-packages/celery/utils/nodenames.py", line 9, in <module>
    from kombu.entity import Exchange, Queue
  File "/venv/awx/lib64/python3.6/site-packages/kombu/entity.py", line 9, in <module>
    from .serialization import prepare_accept_content
  File "/venv/awx/lib64/python3.6/site-packages/kombu/serialization.py", line 396, in <module>
    register_msgpack()
  File "/venv/awx/lib64/python3.6/site-packages/kombu/serialization.py", line 365, in register_msgpack
    import msgpack
  File "/venv/awx/lib64/python3.6/site-packages/msgpack/__init__.py", line 25, in <module>
    from msgpack._packer import Packer
  File "msgpack/_packer.pyx", line 8, in init msgpack._packer
ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__
(awx) bash-4.2# pip uninstall msgpack-python
Uninstalling msgpack-python-0.5.6:
  Would remove:
    /venv/awx/lib/python3.6/site-packages/msgpack/*
    /venv/awx/lib/python3.6/site-packages/msgpack_python-0.5.6-py3.6.egg-info
Proceed (y/n)? y
  Successfully uninstalled msgpack-python-0.5.6
(awx) bash-4.2# pip install msgpack
Collecting msgpack
  Downloading https://files.pythonhosted.org/packages/92/7e/ae9e91c1bb8d846efafd1f353476e3fd7309778b582d2fb4cea4cc15b9a2/msgpack-0.6.1-cp36-cp36m-manylinux1_x86_64.whl (248kB)
    100% |████████████████████████████████| 256kB 3.4MB/s 
Installing collected packages: msgpack
Successfully installed msgpack-0.6.1
(awx) bash-4.2# python -W error $(which awx-manage)
Traceback (most recent call last):
  File "/usr/local/bin/awx-manage", line 9, in <module>
    load_entry_point('awx', 'console_scripts', 'awx-manage')()
  File "/awx_devel/awx/__init__.py", line 124, in manage
    prepare_env()
  File "/awx_devel/awx/__init__.py", line 89, in prepare_env
    if not settings.DEBUG: # pragma: no cover
  File "/venv/awx/lib64/python3.6/site-packages/django/conf/__init__.py", line 56, in __getattr__
    self._setup(name)
  File "/venv/awx/lib64/python3.6/site-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/venv/awx/lib64/python3.6/site-packages/django/conf/__init__.py", line 110, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/awx_devel/awx/settings/development.py", line 22, in <module>
    from .defaults import *  # NOQA
  File "/awx_devel/awx/settings/defaults.py", line 8, in <module>
    from celery.schedules import crontab
  File "/venv/awx/lib64/python3.6/site-packages/celery/schedules.py", line 13, in <module>
    from . import current_app
  File "<frozen importlib._bootstrap>", line 1020, in _handle_fromlist
  File "/venv/awx/lib64/python3.6/site-packages/celery/local.py", line 509, in __getattr__
    module = __import__(self._object_origins[name], None, None, [name])
  File "/venv/awx/lib64/python3.6/site-packages/celery/_state.py", line 17, in <module>
    from celery.utils.threads import LocalStack
  File "/venv/awx/lib64/python3.6/site-packages/celery/utils/__init__.py", line 17, in <module>
    from .imports import (          # noqa
  File "/venv/awx/lib64/python3.6/site-packages/celery/utils/imports.py", line 5, in <module>
    import imp as _imp
  File "/usr/lib64/python3.6/imp.py", line 33, in <module>
    DeprecationWarning, stacklevel=2)
DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses

@AlanCoding
Copy link
Member Author

Well it looks like I could just continue hunting those warnings forever, but only the UserWarning is not filtered when running AWX code, this this is clearly the higher priority, obtained by filtering only that warning type.

(awx) bash-4.2# awx-manage
Traceback (most recent call last):
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/_sslverify.py", line 177, in _selectVerifyImplementation
    from service_identity.pyopenssl import (
ImportError: cannot import name 'verify_ip_address'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/awx-manage", line 9, in <module>
    load_entry_point('awx', 'console_scripts', 'awx-manage')()
  File "/awx_devel/awx/__init__.py", line 144, in manage
    execute_from_command_line(sys.argv)
  File "/venv/awx/lib64/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/venv/awx/lib64/python3.6/site-packages/django/core/management/__init__.py", line 338, in execute
    django.setup()
  File "/venv/awx/lib64/python3.6/site-packages/django/__init__.py", line 27, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/venv/awx/lib64/python3.6/site-packages/django/apps/registry.py", line 116, in populate
    app_config.ready()
  File "/venv/awx/lib64/python3.6/site-packages/channels/apps.py", line 17, in ready
    monkeypatch_django()
  File "/venv/awx/lib64/python3.6/site-packages/channels/hacks.py", line 10, in monkeypatch_django
    from .management.commands.runserver import Command as RunserverCommand
  File "/venv/awx/lib64/python3.6/site-packages/channels/management/commands/runserver.py", line 5, in <module>
    from daphne.server import Server, build_endpoint_description_strings
  File "/venv/awx/lib64/python3.6/site-packages/daphne/server.py", line 8, in <module>
    from twisted.internet import reactor, defer
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/reactor.py", line 38, in <module>
    from twisted.internet import default
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/default.py", line 56, in <module>
    install = _getInstallFunction(platform)
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/default.py", line 44, in _getInstallFunction
    from twisted.internet.epollreactor import install
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/epollreactor.py", line 24, in <module>
    from twisted.internet import posixbase
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/posixbase.py", line 18, in <module>
    from twisted.internet import error, udp, tcp
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/tcp.py", line 31, in <module>
    from twisted.internet._newtls import (
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/_newtls.py", line 21, in <module>
    from twisted.protocols.tls import TLSMemoryBIOFactory, TLSMemoryBIOProtocol
  File "/venv/awx/lib64/python3.6/site-packages/twisted/protocols/tls.py", line 63, in <module>
    from twisted.internet._sslverify import _setAcceptableProtocols
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/_sslverify.py", line 197, in <module>
    _selectVerifyImplementation()
  File "/venv/awx/lib64/python3.6/site-packages/twisted/internet/_sslverify.py", line 190, in _selectVerifyImplementation
    category=UserWarning, filename="", lineno=0)
UserWarning: You do not have a working installation of the service_identity module: 'cannot import name 'verify_ip_address''.  Please install it from <https://pypi.python.org/pypi/service_identity> and make sure all of its dependencies are satisfied.  Without the service_identity module, Twisted can perform only rudimentary TLS client hostname verification.  Many valid certificate/hostname mappings may be rejected.

@AlanCoding
Copy link
Member Author

AlanCoding commented Apr 12, 2019

Well this seems quite self-explanatory here:

https://github.com/twisted/twisted/blob/twisted-19.2.0/src/twisted/python/_setup.py#L95-L97

The versions don't sync up. The dependency resolution should have required that service_identity==18.1.0 or higher was installed.

Upgrading service_identity solves the warning.

I replicated this locally, installed the old service-identity package, then I installed twisted, fresh. This left the environment in an error state. What was the problem? Well, I squinted at those twisted requirements, and saw that it was required as a tls dependency, so I tried...

pip install twisted[tls,conch]

Bingo! It picked up the dependencies it should have been picking up all along.

So, who's the culprit? Well, we didn't put twisted in our requirements. daphne did.

https://github.com/django/daphne/blob/2.3.0/setup.py#L25

Is this daphne's problem? Probably.

https://github.com/django/daphne/blob/9c574083ff04037cd728bfda351b5ca3327f1fff/daphne/server.py#L26

These imports, by themselves, are probably enough to require various twisted extras. Those are undeclared extras, and that breaks dependency resolution. This is a very bug-prone practice, and it should be fixed so that we don't face the possibility of regressions in the future with similar dependency upgrades.

EDIT: Looks like I resolved this the incorrect way in ce56a5e

@AlanCoding
Copy link
Member Author

Link django/daphne#257

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@AlanCoding
Copy link
Member Author

Link oauthlib/oauthlib#264

Due to the upgrades, the status code for an invalid token creation request has changed from 400 to 401. This was an intentional change by the maintainers.

@AlanCoding
Copy link
Member Author

Regarding my previous comment:

#3682 (comment)

I believe that diff was still overly-complicated due to some form of human error. Doing some clean runs just now, the diff returned is:

diff requirements/requirements_ansible_py3.txt requirements/requirements_ansible.txt
5c5
< #    pip-compile -U -r --allow-unsafe --output-file requirements/requirements_ansible_py3.txt requirements/requirements_ansible.in
---
> #    pip-compile -U -r --allow-unsafe --output-file requirements/requirements_ansible.txt requirements/requirements_ansible.in
57a58,59
> enum34==1.1.6             # via cryptography, knack, msrest, ovirt-engine-sdk-python
> futures==3.2.0            # via openstacksdk, s3transfer
60a63
> ipaddress==1.0.22         # via cryptography, openstacksdk
70a74
> monotonic==1.5            # via humanfriendly
113a118
> typing==3.6.6             # via msrest

This matches exactly with what's expected, and I have gone through the requirements_ansible.txt file with a fine toothed comb to assure that its contents now reflect this machine-generated diff.

The only py2 vs. py3 differences are where some libraries are exclusive to python2, and should not be installed in python3. Looking at typing for instance, it is a backport of python3 stuff.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@@ -44,79 +44,81 @@ django-taggit==0.22.2
django==1.11.20
djangorestframework-yaml==1.0.3
djangorestframework==3.7.7
docutils==0.14 # via python-daemon
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We explicitly removed docutils from this list and put a Makefile directive in here https://github.com/ansible/awx/blob/devel/Makefile#L149 to install docutils. At pip install time a dependency of ansible-runner requires docutils to exist to "build" the package .. it's weird. So we pre-install docutils before installing that ansible-runner dep.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, the logic I had for removing the git requirements was that, it turned out that no dependencies pulled it.

Since I originally did that, I've done several rebases of this, running the tool again, and here it is, shows up as a surprise.

It appears that it is listed as a setup_requires, but not a install_requires.

https://pagure.io/python-daemon/blob/master/f/setup.py

I'm still looking into what we can do about this. My current thinking is to change the instructions to say "remove all the git requirements at the end"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I removed it and added a note.

I still don't think we need to maintain the -e git+ stuff that we used to have. Maybe we need to add a note to check that no dependencies conflict with the git requirements, but that doesn't mean that we need to throw them into the pot before we cook it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I missed this from docutils

# Docutils is only required for building, but Setuptools can't distinguish
# dependencies properly.
# See <URL:https://github.com/pypa/setuptools/issues/457>.
setup_kwargs['install_requires'].append("docutils")

So yeah, either we tell pip-compile to ignore libraries like this, or we just let it run and have them deleted at the end. My preference is switching to the latter here.

kombu==4.2.1 # via asgi-amqp, celery
lxml==4.3.1 # via xmlsec
kombu==4.5.0 # via asgi-amqp, celery
lockfile==0.12.2 # via python-daemon
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, maybe I missed this dependency of a dependency. python-daemon version didn't change, but this is being pulled in now

pyparsing==2.2.0
pyrad==2.1 # via django-radius
pysocks==1.6.8 # via twilio
python-daemon==2.2.0 # via ansible-runner
python-daemon==2.2.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ansible-runner doesn't pull this in now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The automated tool will not add this comment, and I do not know why. Yes, it is listed as a dependency, so I'm not sure what's up with that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, that's because it was put into requirements/requirements.in. Since it's a top-level dependency, it is not annotated as being a dependency of another library here.

Here is a change to resolve this, and the output of the tool along with it:

diff --git a/requirements/requirements.in b/requirements/requirements.in
index 05853a486f..747d18b079 100644
--- a/requirements/requirements.in
+++ b/requirements/requirements.in
@@ -35,7 +35,6 @@ psutil==5.4.3
 psycopg2==2.7.3.2   # problems with Segmentation faults / wheels on upgrade
 pygerduty==0.37.0
 pyparsing==2.2.0
-python-daemon==2.2.0
 python-dateutil==2.7.2  # contains support for TZINFO= parsing
 python-memcached==1.59
 python-radius==1.0
diff --git a/requirements/requirements.txt b/requirements/requirements.txt
index 10254944b3..0ae05d9538 100644
--- a/requirements/requirements.txt
+++ b/requirements/requirements.txt
@@ -2,7 +2,7 @@
 # This file is autogenerated by pip-compile
 # To update, run:
 #
-#    pip-compile -U -r --allow-unsafe --output-file requirements/requirements.txt requirements/requirements.in
+#    pip-compile --allow-unsafe --output-file=requirements/requirements.txt requirements/requirements.in
 #
 adal==1.2.1               # via msrestazure
 amqp==2.4.2               # via kombu
@@ -15,7 +15,7 @@ asn1crypto==0.24.0        # via cryptography
 attrs==19.1.0             # via automat, service-identity, twisted
 autobahn==19.3.3          # via daphne
 automat==0.7.0            # via twisted
-azure-common==1.1.19      # via azure-keyvault
+azure-common==1.1.20      # via azure-keyvault
 azure-keyvault==1.1.0
 azure-nspkg==3.0.2        # via azure-keyvault
 billiard==3.6.0.0         # via celery
@@ -90,7 +90,7 @@ pyopenssl==19.0.0         # via twisted
 pyparsing==2.2.0
 pyrad==2.1                # via django-radius
 pysocks==1.6.8            # via twilio
-python-daemon==2.2.0
+python-daemon==2.2.3      # via ansible-runner
 python-dateutil==2.7.2
 python-ldap==3.2.0        # via django-auth-ldap
 python-memcached==1.59

cffi==1.11.5 # via bcrypt, cryptography, pynacl
botocore==1.9.23 # via boto3, s3transfer
cachetools==3.1.0 # via google-auth
certifi==2019.3.9 # via msrest, requests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meh, we are going to explicitly uninstall it anyway.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

Update licenses for new versions after dependency upgrades

pin pycurl to version that does not break on install

implement new workflow for py2/3 requirements management

require twisted tls extras, resolve service-identity version

Upgrade celery to resolve importlib DeprecationWarning

use flags to resolve the unsafe and cache problems
@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded.

Copy link
Member

@jbradberry jbradberry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Celery was the main thing I was concerned about here, but it looks like it should be ok. 🚀 🗿

@softwarefactory-project-zuul
Copy link
Contributor

Build succeeded (gate pipeline).

@softwarefactory-project-zuul softwarefactory-project-zuul bot merged commit 34c3aae into ansible:devel May 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants