-
Notifications
You must be signed in to change notification settings - Fork 275
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
ngclient: reveal final form (finish API changes) #1580
Comments
re-implementing the current directory-creating cache style would be easy for a client that wants to do that (and knows that it is safe to do so). |
💯 this will make the API much nicer in use.
💯 the pluralised API has always felt a little off.
👍
I am less certain about this. We should try and get this right for 1.0 so we don't have to break API too soon. Is always refreshing going to cause problems anywhere? It might be problematic for an air-gapped client (with local/cached files) that can't reach out to the network to
How do we indicate the difference between a directory and a filename? directory paths must end with
Sounds reasonable. Will this work with how, for example, pip does caching today?
Other options:
metadata.py is already too large, let's avoid adding these until we have a use-case.
😆 yes! |
Doing the actual refresh has always been required so that's not changing with my plan... not being able to connect to remote always means failure (in this plan and current implementations). The question of "should we be able to do something with local metadata without checking remote metadata" is a reasonable one. Examples:
These sounds like post 1.0 material to me but I'll write some ideas on implementation: I think the first case is an optimization that might not be worth it... but a possible implementation could maybe be a Updater configuration where client could define The second case I guess could be done with similar configuration -- but a practical limit with this will be the timestamp expiry: I don't think we want to add code for allowing expired metadata in some cases. But imagining an update system designed for this (with long enough expiries), I guess the same approach would work?
my prototype code uses
pips actual cache is the http cache (and we planned to let that be the case for TUF downloads as well). For the project index download case, the file would be temporary and filename does not matter so I suppose pip will let Updater choose the filename. For the real target files, I think pip will want to build the local filename itself (but it will want to use get_local_target() as in some cases the file might already exist). |
Thanks for working through these with me Jussi.
I agree that this is post 1.0 material. I just want to keep it in mind so we are able to satisfy the requirements.
Agree, we do not want code to allow for expired metadata in some cases. What I think is the sensible approach for air-gaps is for the client to be able to use local valid metadata but not choke if fetching remote metadata fails. If Looking over ngclient interfaces, this might be an additional method (added post 1.0) to explicitly load local metadata and a config optional + checking in appropriate places (i.e.
and caller owns creating directories, makes sense. I'm still a bit concerned about how intuitive this method will feel to users. Are we OK with requiring users to ensure directories exist and possibly doing unexpected things when they do not? For example, the following to calls to updater.download_target(tgtinfo, "/tmp/badger/")
updater.download_target(tgtinfo, "/tmp/badger")
👍 |
Hmm, yes, maybe 'cache' is a better term than 'local' (when contrasted with |
requiring directories to exist seems fine to me but...
This is a reasonable criticism. My prototype code would indeed try to write to a file (first one would fail and second would succeed...). The only alternatives I can think of are adding duplicate functions for the two types of arguments (this seems unappealing) and adding separate arguments for filename and directory which looks a bit unique but could work:
I'm not super into either one of these. |
Of these options I prefer the latter, users either tell us where to store a file we name or precisely where to write the file. Separate arguments makes it clear they are different use-cases. Mutually exclusive optional arguments might be a little confusing, but feels safer for users than a single argument. @sechkova any thoughts on the proposed API here? |
From what I understand, the intention is that if I guess mutual exclusive if I have to choose from the options above, otherwise the result from this misunderstanding of the API:
(if /tmp exists) may come as a surpeise (
The |
can you explain which variant exactly you mean? I can't quite follow the question To summarize there have been three options so far I think:
Variant 1 feels ugly and unusual. I can live with variant 2 or original. |
My preference is variant 2, due to the concern I raised with the original proposal. |
Sorry, I've misunderstood partially. Let's go for variant 2 then. |
Doing so is not always safe and has various other issues (like target paths "a/../b" and "b" ending up as the same local path). Instead URL-encode the target path to make it a plain filename. This removes any opportunity for path trickery and removes the need to create the required sub directories (which we were not doing currently, leading to failed downloads). URL-encoding encodes much more than we really need but doing so should not hurt: the important thing is that it encodes all path separators. Return the actual filepath as return value. I would like to modify the destination argument to be either a directory or a filename so caller could decide the filename if they want to. But I won't do it now because updated_targets() (the caching mechanism) relies on filenames being chosen by TUF. The plan is to make it possible for caller to choose the filename though. This is part of bigger plan in theupdateframework#1580 Fixes theupdateframework#1571 Signed-off-by: Jussi Kukkonen <[email protected]>
Doing so is not always safe and has various other issues (like target paths "a/../b" and "b" ending up as the same local path). Instead URL-encode the target path to make it a plain filename. This removes any opportunity for path trickery and removes the need to create the required sub directories (which we were not doing currently, leading to failed downloads). URL-encoding encodes much more than we really need but doing so should not hurt: the important thing is that it encodes all path separators. Return the actual filepath as return value. I would like to modify the arguments so caller could decide the filename if they want to. But I won't do it now because updated_targets() (the caching mechanism) relies on filenames being chosen by TUF. The plan is to make it possible for caller to choose the filename though. This is clearly a "filesystem API break" for anyone depending on the actual target file names, and does not make sense if we do not plan to go forward with other updated_targets()/download_target() changes listed in theupdateframework#1580. This is part of bigger plan in theupdateframework#1580 Fixes theupdateframework#1571 Signed-off-by: Jussi Kukkonen <[email protected]>
Doing so is not always safe and has various other issues (like target paths "a/../b" and "b" ending up as the same local path). Instead URL-encode the target path to make it a plain filename. This removes any opportunity for path trickery and removes the need to create the required sub directories (which we were not doing currently, leading to failed downloads). URL-encoding encodes much more than we really need but doing so should not hurt: the important thing is that it encodes all path separators. Return the actual filepath as return value. I would like to modify the arguments so caller could decide the filename if they want to. But I won't do it now because updated_targets() (the caching mechanism) relies on filenames being chosen by TUF. The plan is to make it possible for caller to choose the filename though. This is clearly a "filesystem API break" for anyone depending on the actual target file names, and does not make sense if we do not plan to go forward with other updated_targets()/download_target() changes listed in theupdateframework#1580. This is part of bigger plan in theupdateframework#1580 Fixes theupdateframework#1571 Signed-off-by: Jussi Kukkonen <[email protected]>
Status report for this:
Other than those my WIP branch contains
I think those will be ~two more PRs -- I will make them when current open one merges, but if you want to see the end result, see https://github.com/jku/python-tuf/commits/ngclient-final-form |
Curently active PR for this is #1604 : Since there's a lot of target dir / filepath discussion here already, I'll mention that has a design that improves on the ones discussed here After this the only thing left is the implicit refresh which is quite trivial. |
Doing so is not always safe and has various other issues (like target paths "a/../b" and "b" ending up as the same local path). Instead URL-encode the target path to make it a plain filename. This removes any opportunity for path trickery and removes the need to create the required sub directories (which we were not doing currently, leading to failed downloads). URL-encoding encodes much more than we really need but doing so should not hurt: the important thing is that it encodes all path separators. Return the actual filepath as return value. I would like to modify the arguments so caller could decide the filename if they want to. But I won't do it now because updated_targets() (the caching mechanism) relies on filenames being chosen by TUF. The plan is to make it possible for caller to choose the filename though. This is clearly a "filesystem API break" for anyone depending on the actual target file names, and does not make sense if we do not plan to go forward with other updated_targets()/download_target() changes listed in theupdateframework#1580. This is part of bigger plan in theupdateframework#1580 Fixes theupdateframework#1571 Signed-off-by: Jussi Kukkonen <[email protected]>
First I think all points from this issue are done and it can be closed. |
Whoever closes that issue please have a look at #1135 as well as I think that's the only issue that stops it from being closed. |
closing: client looks complete to me |
There's a bunch of small API changes that I think would still make the API better (more consistent, simpler, safer). The implementations of the individual changes can probably be separate but I think it makes sense to discuss the design as a whole: it'll be a lot easier to discuss when the final form of the API is visible.
updated_targets()
before (since it's not really a specification feature) but... it looks like it can be just simplifieddownload_target()
should return the local file path, not force client to guessUpdater.updated_targets()
return value is not obvious, and using a list is weirdUpdater.get_one_valid_targetinfo()
: name is long without adding valueUpdater.refresh()
: there is no reason to force client to explicitly call thisPlanned API usage
NOTE: these examples have been updated as the ideas have crystallized: earlier comments may refer to a slightly different example
Things to note there:
refresh()
is available but not required: it will be done on firstget_targetinfo()
if not explicitly called beforedownload_target()
chooses the filename, it will encode the target path before using it as a filename.find_cached_target()
name is not great but I want it to be a counterpart to download_target (and I believe it's much better than the ambiguousupdated_targets()
)See #1604 for more details.
Considered, but not included changes
I considered these as well, but am currently not planning to include them:
download_target()
that returns the target file as bytes for the use case where writing to a real file is not necessary? As far as I can tell these would be entirely new functions though so this could be done at a later time without breaking API, so I'm planning to not do this now.The text was updated successfully, but these errors were encountered: