Skip to content

Experimental client: use bundle #1396

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

Merged

Conversation

jku
Copy link
Member

@jku jku commented May 18, 2021

Use the MetadataBundle in the new Updater:

  • Remove MetadataWrapper
  • Update and expand tests
  • Stop using tuf.settings, store the constants in updater_rework.py
  • Use MetadataBundle to verify current set of metadata, remove all verification code from Updater
  • load local metadata from disk
  • persist new verified metadata to disk

Fixes #1304
Fixes #1320
Fixes #1319

@jku
Copy link
Member Author

jku commented May 18, 2021

The constants could use some thought: We definitely don't want to keep using tuf.settings, but I guess the question is, should these be instance variables in Updater instead of module level ones:

MAX_ROOT_ROTATIONS = 32
MAX_DELEGATIONS = 32
DEFAULT_ROOT_MAX_LENGTH = 512000  # bytes
DEFAULT_TIMESTAMP_MAX_LENGTH = 16384  # bytes
DEFAULT_SNAPSHOT_MAX_LENGTH = 2000000  # bytes
DEFAULT_TARGETS_MAX_LENGTH = 5000000  # bytes

Maybe it does not hurt if they were instance variables instead. They don't even need to be optional constructor arguments (as initialization does not use any of them: caller can initialize the Updater and then modify the values).
I guess the fanciest option is that constructor takes an optional argument dataclass UpdaterOptions with those attributes ...

@sechkova sechkova added the experimental-client Items related to the development of a new client (see milestone/8 and theexperimental-client branch) label May 18, 2021
@jku jku force-pushed the experimental-client-use-bundle branch from 228a01c to 05421e0 Compare May 18, 2021 08:57
Jussi Kukkonen added 2 commits May 18, 2021 20:56
Use the MetadataBundle to verify metadata validity.
* Updater now handles reading metadata files (from filesystem as
  well as network
* Updater feeds bytes to MetadataBundle for verification
* Updater persists data on disk after it had been verified

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Add test for a refresh with just a local root.json.

Remove unused code. Add docstrings for raised exceptions, add TODOs for
the missing exception handling.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
@jku jku force-pushed the experimental-client-use-bundle branch from 05421e0 to 2bbf5bc Compare May 18, 2021 18:05
@jku jku marked this pull request as ready for review May 19, 2021 13:23
@jku jku requested review from sechkova and joshuagl May 19, 2021 13:24
@MVrachev
Copy link
Collaborator

After I made consistent_snapshot optional for root here, I realized that the MetadataBundle was created before that.
Can we check that if consistent_snapshot is not provided everything will work with the update process?

Copy link
Contributor

@sechkova sechkova left a comment

Choose a reason for hiding this comment

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

The constants could use some thought: We definitely don't want to keep using tuf.settings, but I guess the question is, should these be instance variables in Updater instead of module level ones:

MAX_ROOT_ROTATIONS = 32
MAX_DELEGATIONS = 32
DEFAULT_ROOT_MAX_LENGTH = 512000  # bytes
DEFAULT_TIMESTAMP_MAX_LENGTH = 16384  # bytes
DEFAULT_SNAPSHOT_MAX_LENGTH = 2000000  # bytes
DEFAULT_TARGETS_MAX_LENGTH = 5000000  # bytes

Maybe it does not hurt if they were instance variables instead. They don't even need to be optional constructor arguments (as initialization does not use any of them: caller can initialize the Updater and then modify the values).
I guess the fanciest option is that constructor takes an optional argument dataclass UpdaterOptions with those attributes ...

Given the proposed structure in #1397 (comment) where the idea is to expose only the Updater class in the client __init__ , probably the constants need to be inside the class (or the fancier options). However this can happen when solving #1397.

I left some minor comments but I in general I like how Updater looks now.

f"{settings.MAX_NUMBER_OF_DELEGATIONS}",
" delegations.",
f"{len(role_names)} roles left to visit, but allowed to ",
f"visit at most {MAX_DELEGATIONS} delegations.",
)
logger.debug(msg)
Copy link
Contributor

Choose a reason for hiding this comment

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

This trick of mine with logging needs to be reverted now that we agreed on %s-strings in the logging calls.
But not in this PR. I'll note it for myself.

Copy link
Contributor

Choose a reason for hiding this comment

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

Captured in #1400


return intermediate_targets
data = self._load_local_metadata(role)
self._bundle.update_delegated_targets(data, role, parent_role)
Copy link
Contributor

Choose a reason for hiding this comment

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

Using self._bundle.update_delegated_targets here leaves MetadataBundle.update_targets() unused.
Not a big deal but mentioning it.

@jku
Copy link
Member Author

jku commented May 19, 2021

Addressed the resolved discussions. Also checked that consistent_snapshots=None seems to work fine (using a falsy test)

@jku jku mentioned this pull request May 19, 2021
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.

This looks very concise, nice. It took me a couple of reads to figure out why the fetching of metadata only happened in the exception handler of a load. That might want some attention in terms of comments and/or function names? 🤔

I also noticed there are some unhandled exceptions which I am not sure whether it is reasonable to leave those to a caller to handle or not. Would welcome thoughts on that.

Overall, very solid. LGTM.

Comment on lines +283 to +284
self._bundle.update_snapshot(data)
self._persist_metadata("snapshot", data)
Copy link
Member

Choose a reason for hiding this comment

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

Here, and other _load_*() functions, the exceptions raised by MetadataBundle.update_snapshot and the open and write calls in _persist_metadata become errors the user must handle. The former seems reasonable enough, I'm less certain about the latter. Especially when get_one_valid_targetinfo() -> _preorder_depth_first_walk() could result in a myriad of errors (download, file open/write, ???).

Probably a topic for #1312 ?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes I vote for handling in 1312. I think the three classes of exceptions (repository / download / file IO) are logical and also the granularity that I could see a serious client wanting to handle (or not handle as might be reasonable with e.g. file IO ).

Mostly remove comments that provide little value after all the changes.
Also remove a unused variable from a test.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
@jku jku force-pushed the experimental-client-use-bundle branch from ad4e671 to d35fc27 Compare May 20, 2021 12:42
@jku jku merged commit db02fa6 into theupdateframework:experimental-client May 20, 2021
@jku jku deleted the experimental-client-use-bundle branch December 30, 2024 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
experimental-client Items related to the development of a new client (see milestone/8 and theexperimental-client branch)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants