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

Revise extra dependency handling #179

Closed
lukpueh opened this issue Sep 12, 2019 · 6 comments
Closed

Revise extra dependency handling #179

lukpueh opened this issue Sep 12, 2019 · 6 comments

Comments

@lukpueh
Copy link
Member

lukpueh commented Sep 12, 2019

[Updated on Jan 23, 2020]

Description of issue or feature request:

securesystemslib lists some dependencies that require C-code (cryptography requiresopenssl, pynacl requires libsodium) as optional to allow for a pure-python installation. The runtime handling of missing optional dependencies should be revised.

Current behavior:
cryptography and pynacl are listed as optional (extra) dependencies, but securesystemslib does not fare (consistently) well, if installed without them.

Expected behavior:

-Optional: colorama was made a strict dependency in #178 to quickfix #155. @SantiagoTorres, to consider making it a optional again (with respect to required adoptions as outlined above). Fixed with #200

lukpueh added a commit to in-toto/in-toto that referenced this issue Sep 12, 2019
securesystemslib does not work properly without its extra
dependencies cryptography, pynacl and colorama (see
secure-systems-lab/securesystemslib#179).

To build in-toto for debian, we need these dependency, and thus
add them explicitly to debian/control.
lukpueh added a commit to in-toto/in-toto that referenced this issue Sep 12, 2019
securesystemslib does not work properly without its extra
dependencies cryptography, pynacl and colorama (see
secure-systems-lab/securesystemslib#179).

To build in-toto for debian, we need these dependency, and thus
add them explicitly to debian/control.

Signed-off-by: Lukas Puehringer <[email protected]>
@joshuagl
Copy link
Collaborator

When looking at available options for testing for the presence of optional dependencies it seems there's an old mechanism imp, which was deprecated in Python 3.4 and a new mechanism importlib, which is available since Python 3.1.

securesystemslib's tox environment tests Python 2.7, 3.5 and 3.6 - but that doesn't necessarily mean those are the only versions we care to support. PyPI lists securesystemslib-0.11.3 as supporting Python 2.7, 3.4, 3.5 and 3.6.

It may be reasonable to take the same approach as Ansible (see Ansible commit 2732cde) and use imp for Python versions < 3 and importlib for anything else.

However with Python 2's EOL being close I wanted to get some feedback on whether it's even desirable to continue to maintain Python2 support in securesystemslib?
As we consider this It's worth noting that dateutil have pledged to drop support for Python 2.7 no later than 2020. It's not clear if the project has settled on a schedule yet but their python3statement entry indicates they won't be making releases that support Python2 beyond 2019-07-01.

@lukpueh
Copy link
Member Author

lukpueh commented Oct 11, 2019

Thanks for your assessment, @joshuagl .

What's the benefit of using imp/importlib over a more vanilla approach that just catches ImportError? I think that's what securesystemslib already does in some cases.

In my mind, we would encapsulate imports and use of optional libraries in non-public modules like so:

# in `securesystemslib/optional_foo_private_module.py`
try:
  import foo

except ImportError:
  NO_FOO = True

def foo():
  if NO_FOO:
    raise("<Helpful message about missing foo>") 
  foo.foo()

This would keep our public interface clean of import-related case handling.

# in `secureystemslib/public_interface.py`
import optional_foo_private_module

def foo():
  """Call foo or raise helpful error message if not installed. """
  optional_foo_private_module.foo()

What do you think about that pattern?

Regarding Python 2.7, we discussed this recently and decided that we'll keep it around for a little longer. But I agree, we won't be able to do this for too long. We'll run into troubles at the latest when our dependencies drop support. Still, I would prefer if we could resolve this issue without dropping 2.7.

@joshuagl
Copy link
Collaborator

I had noticed that the try: import XXX / except ImportError pattern is present in places in securesystemslib and it's what I've used in the past. I'll be happy to proceed with that pattern, especially as it postpones a decision on Python2 without additional coding effort.

@joshuagl
Copy link
Collaborator

joshuagl commented Feb 6, 2020

Looking at outstanding native dependencies that need handling:

Sphincs (#169) and CCID/PIV (#170) can be handled in a similar fashion to other key algorithm modules, that is: setting a constant to False on ImportError and raiseing UnsupportedLibraryError at call time from functions requiring the library. What's the best way to handle this in terms of this issue? Comment on the PRs suggesting that such a change be added? Propose patches to the existing PR?

I have a WIP patch for GPG, raiseing an UnsupportedLibraryError is semantically incorrect, as it's a programme that's missing not a library, but it may be better to throw a consistent Exception for application authors to catch when dependencies are missing. What do you think @lukpueh ?

I also need to figure out how to test it. The gpg command is rarely missing on modern Linux, as most distro package managers pull it in as a dependency, and testing only on Windows feels insufficient.

@lukpueh
Copy link
Member Author

lukpueh commented Feb 6, 2020

Looking at outstanding native dependencies that need handling:

💯

Sphincs (#169) and CCID/PIV (#170) can be handled in a similar fashion to other key algorithm modules, that is: setting a constant to False on ImportError and raiseing UnsupportedLibraryError at call time from functions requiring the library. What's the best way to handle this in terms of this issue? Comment on the PRs suggesting that such a change be added? Propose patches to the existing PR?

Leaving a comment on the two PRs, pointing to the discussion here, and your awesome fix in #200 should go a long way. Would you mind doing that?

I have a WIP patch for GPG, raiseing an UnsupportedLibraryError is semantically incorrect, as it's a programme that's missing not a library, but it may be better to throw a consistent Exception for application authors to catch when dependencies are missing. What do you think @lukpueh ?

Throwing the same error sounds like a good idea. And I think the semantics even work if the securesystemslib.gpg is seen as the unsupported library. ;)

I also need to figure out how to test it. The gpg command is rarely missing on modern Linux, as most distro package managers pull it in as a dependency, and testing only on Windows feels insufficient.

Might apt-get remove gnupg gnupg2 work?

@lukpueh
Copy link
Member Author

lukpueh commented Feb 10, 2020

This is fixed for existing code in #200 and #206. Authors of pending relevant PRs have been informed to follow the new strategy (#170 (comment), #169 (comment)). I have created a separate feature request for a fine-tune code coverage measurement setup in #208. Thanks for the hard work, @joshuagl! Closing here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants