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

Vendoring-compatible imports #1261

Merged
merged 25 commits into from
Mar 19, 2021

Conversation

jku
Copy link
Member

@jku jku commented Jan 12, 2021

The goal here is to make TUF compatible with the vendoring tool so that tuf sources can be vendored into pip. As a reminder vendoring will modify all import-lines in a vendored project like this patch:

- import package 
- from package import module 
- from package.module import func
+ from _vendoring import package 
+ from _vendoring.package import module 
+ from _vendoring.package.module import func

This does not work in the case of import package.module that is so common in tuf.

Notes

  • tuf modules are now imported with this style from tuf import download. This works with just a few localised issues: I'm generally happy with how code calling internal modules looks
  • securesystemslib modules can't be handled this way:
    • module names clash with tuf modules names
    • module names are quite generic and likely to lead to conflicts later on
  • as result securesystemslib imports are now like from securesystemslib import formats as sslib_formats in most cases. I don't particularly like it but it is readable and I can't think of a better solution
  • Very minor changes to how other dependencies are used
  • linter now understands our imports so some fixes and workarounds have been added.
  • The import lists that we're changed have been sorted so tuf imports are last
  • The patch is surprisingly large, ~900 lines. Roughly 350 are needed for the client vendoring but I modified the whole code base to at least be consistent. The tests have not been touched.

Copy link
Member

@joshuagl joshuagl left a comment

Choose a reason for hiding this comment

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

Thank you for tackling this @jku!

FYI the series has multiple "imports: Fix securesystemslib.exceptions imports" patches. They aren't all modifying exceptions. Similarly with "imports: Fix securesystemslib.interface imports".

This is a draft since I'll have to do something similar in securesystemslib before I can test that it all actually works with vendoring... I am also going to go through this PR again to make sure there are no typos and to improve commit messages.

Should have paid more attention to this before reviewing commit by commit, I hope the numerous comments I've left are useful.

  • as result securesystemslib inports are now like from securesystemslib import formats as sslib_formats in most cases. I don't particularly like it and am willing to consider alternatives

I'm not opposed to this, though I should point out that we can avoid many of the sslib_* imports by importing only the names we care about, you've done this in a couple of places – importing only the functions from a securesystemslib module that the tuf module is using – I assume expediency is the main reason you didn't do this throughout?

  • The patch is surprisingly large, ~900 lines. Roughly 350 are needed for the client vendoring but I modified the whole code base to at least be consistent. The tests have not been touched.

Completely agree with this rationale.

tuf/keydb.py Show resolved Hide resolved
tuf/developer_tool.py Outdated Show resolved Hide resolved
tuf/developer_tool.py Outdated Show resolved Hide resolved
tuf/repository_lib.py Outdated Show resolved Hide resolved
tuf/repository_lib.py Outdated Show resolved Hide resolved
tuf/client/updater.py Show resolved Hide resolved
tuf/log.py Show resolved Hide resolved
tuf/scripts/repo.py Outdated Show resolved Hide resolved
tuf/client/updater.py Show resolved Hide resolved
tuf/developer_tool.py Show resolved Hide resolved
@lukpueh
Copy link
Member

lukpueh commented Jan 15, 2021

Thanks a ton for taking a stab at this thankless task, and especially for the thorough separation of commits! As requested, I only skimmed the patches here and in secure-systems-lab/securesystemslib#316. Let me know when you want a full review.

Here are some thoughts regarding your notes from above.

  • tuf modules are now imported with this style from tuf import download.

I'd like to add that this does not only fix the vendoring issues but also aligns with our style recommendation, even though the Google guide accepts both.

  • as result securesystemslib inports are now like from securesystemslib import formats as sslib_formats in most cases. I don't particularly like it and am willing to consider alternatives

I'm fine with this approach. IMO the secondary goal (besides making vendoring work) should be to help the reader attribute function or other names to modules or packages. And sslib_interface.import_publickeys_from_file seems to serve that purpose better than interface.import_publickeys_from_file.

  • The import lists that we're changed have been sorted so tuf imports are last

Excellent, this too is a style guide recommendation.

  • The patch is surprisingly large, ~900 lines. Roughly 350 are needed for the client vendoring but I modified the whole code base to at least be consistent. The tests have not been touched.

👍

Do you think it's worth to add an ADR for the rationale in this PR? Or to amend our style guide? Specifically in regards to:

from package import module vs. from package import module as xyz_module vs. from package.module import name

@jku
Copy link
Member Author

jku commented Jan 15, 2021

To you think it's worth to add an ADR for the rationale in this PR? Or to amend our style guide? Specifically in regards to:

from package import module vs. from package import module as xyz_module vs. from package.module import name

Eh, I think it maybe depends... So far I've mostly used the first (and second where confusion was more likely) but the third one makes sense for some modules. I've avoided the third option for now mostly to keep the changes to a minimum and so I only had to worry about one new local name (the module name) and not multiple as might be the case if we import individual things from modules.

Related thought (this might not be a good idea, just something I'm wondering), for some of our most common imports I've been thinking: If TUF uses e.g. schemas from tuf.formats and securesystemslibs.formats wouldn't it make sense for tuf.formats to expose the relevant items from securesystemslibs.formats? This way there would be one place (tuf.formats) that takes care of possible conflicts and other TUF code could just import tuf.formats or individual items from there (module name not really needed because now there's no confusion over where they come from). Same goes to a degree for exceptions -- where it's a bit weird that code that does not call securesystemslib code might have to import securesystemslib.exceptions to handle errors.

@lukpueh
Copy link
Member

lukpueh commented Jan 18, 2021

Related thought (this might not be a good idea, just something I'm wondering), for some of our most common imports I've been thinking: If TUF uses e.g. schemas from tuf.formats and securesystemslibs.formats wouldn't it make sense for tuf.formats to expose the relevant items from securesystemslibs.formats?

I generally think that's a good idea, but given that we want to get away from schemas (secure-systems-lab/securesystemslib#183) maybe not worth the effort?

Same goes to a degree for exceptions -- where it's a bit weird that code that does not call securesystemslib code might have to import securesystemslib.exceptions to handle errors.

I agree that it's weird. But I think the solution should be a revision of the exception taxonomy (#1131, secure-systems-lab/securesystemslib#191). AFAICS there is no big win in defining any tuf exceptions in securesystemslib.

@jku jku force-pushed the vendoring-compatible-imports branch from 88a9f8d to dabc57d Compare January 21, 2021 14:43
@jku jku force-pushed the vendoring-compatible-imports branch 2 times, most recently from a8e722f to 70f4fae Compare March 4, 2021 08:41
@jku jku marked this pull request as ready for review March 4, 2021 14:07
@jku
Copy link
Member Author

jku commented Mar 4, 2021

I've marked this ready for review.

I think this is the one question that hasn't been answered (in this issue):

I'm not opposed to this, though I should point out that we can avoid many of the sslib_* imports by importing only the names we care about, you've done this in a couple of places – importing only the functions from a securesystemslib module that the tuf module is using – I assume expediency is the main reason you didn't do this throughout?

I think the places where I did it were already using this format for some other formats from this module (so I was aiming for least disruption to existing code). Otherwise I tried to follow the guideline of importing modules, not module contents. It's true that in some instances the latter would work better: schemas are an example but modifying them is a lot of work that might not be 100% trivial and that I'd rather leave for a follow up if needed

@jku jku requested a review from lukpueh March 4, 2021 14:22
Copy link
Member

@lukpueh lukpueh left a comment

Choose a reason for hiding this comment

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

Thanks again for doing this dull deed, @jku! Here is how I reviewed your PR:

I have not verified if this patch

  • indeed makes tuf vendoring-compatible,
  • is complete,
  • doesn't shadow any names.

Also, I have not commented on inconsistent adoption of new module/sybmol paths in docstrings, most notably in <Exceptions>, or Raises: sections. I noticed some and briefly considered pointing them out, but I'm unsure if it is worth the effort.

What I did do is I

  • went through each commit,
  • read each diff line by line, and
  • checked that each diff corresponds to the commit message.
  • I also made sure you addressed @joshuagl's comments.

Based on that, your PR LGTM.

If that's enough, I'd say we merge, after you have rebased and fixed the conflict in tuf/api/metadata.py.

ps: I'd also like to land this before #1314 because that way it will be easier to resolve conflicts (nothing big, I checked, but still).

@@ -14,7 +14,7 @@
import urllib3.exceptions

from tuf import exceptions
import tuf.settings
from tuf import settings
Copy link
Member

Choose a reason for hiding this comment

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

Nit pick: I think the patch in this file should have gone into 7841008. (Note that I mostly point this out so that you see that I actually read the diff 😄 . Feel free to ignore.)

@joshuagl joshuagl mentioned this pull request Mar 19, 2021
17 tasks
Jussi Kukkonen added 14 commits March 19, 2021 16:53
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make sure mirrors is not used as variable name (so it can be used for
the module import name later).

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Remove one unused import.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make the import compatible with vendoring tool and alias the import so
it does not clash with the local module. Fix all references
to the module in the code.

Remove a related repo.py comment that was badly duplicated from module
docstring.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make the updater imports compatible with vendoring tool by importing
the Updater class directly (don't import the whole module to avoid the
clash with the obvious variable name 'updater').

Also update the example: This is not required in the clients but tuf
source code will be vendored and this import line (even though in a
comment) might trigger an error in future vendoring tool releases.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make the import compatible with vendoring tool and alias the import so
it does not clash with the local module. Fix all references
to the module in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make them compatible with vendoring, use
  from securesystemslib import keys as sslib_keys
to have the same style as other securesystemslib imports.

Note that developer_tool already used a
   from securesystemslib.keys import ...
for some functions so that style was used consistently there.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make them compatible with vendoring, use
  from securesystemslib import interface as sslib_interface
to have the same style as other securesystemslib imports.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Jussi Kukkonen added 11 commits March 19, 2021 16:56
Make the import compatible with vendoring tool and alias the import so
it does not clash with the local module. Fix all references
to the module in the code.

In one instance import a specific function to avoid a more complex
redirection in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make them compatible with vendoring, use
  from securesystemslib import storage as sslib_storage
to have the same style as other securesystemslib imports.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make them compatible with vendoring, use
  from securesystemslib import hash as sslib_hash
to have the same style as other securesystemslib imports (and to avoid
potential conflict with system hash()).

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make the import compatible with vendoring tool and alias the import so
it does not clash with the local module. Fix all references
to the module in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Also fix import orders so tuf internal imports are last.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
The linter now understands our imports (yay), and complains a lot (boo):
* Remove really unused imports
* disable lints for tuf.log and securesystemslib imports: these imports
  have logging side-effects (they set default loggers for tuf and
  securesystemslib respectively) and I'm cautious about just removing
  them

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Make it compatible with vendoring: import the exception only to avoid
having to rename the module locally.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
requests_fetcher uses tuf.__version__ for user-agent, move the import to
the correct file.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
@jku jku force-pushed the vendoring-compatible-imports branch from 70f4fae to ab56344 Compare March 19, 2021 15:14
@jku
Copy link
Member Author

jku commented Mar 19, 2021

Changes since last push:

  • rebased to develop
  • fixed rebase issues in "imports: Make 'formats' imports vendoring-compatible"
  • fixed rebase issues in "imports: Make 'exceptions' imports vendoring-compatible"
  • Added a commit for a missed requests_fetcher import
  • Added a commit to bundle imports like isort likes them

@lukpueh
Copy link
Member

lukpueh commented Mar 19, 2021

Still LGTM! :)

@lukpueh lukpueh merged commit b5c8ba0 into theupdateframework:develop Mar 19, 2021
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

Successfully merging this pull request may close these issues.

3 participants