ATM installing a snap uses the /details store API, while refreshes use the /metadata API. Since we have grown some more requirements that made us consider reviewing these APIs:
we need to send validation context (all currently installed snaps) for all operations, so we avoid an install choosing a revision ignoring validation constraints but the later refresh immediately switching to a different validated revision
we are also switching to sticky ignore-validation flags for snap to ask the store not to enforce validation
the special case of snap refresh --revision is using the /details API but given epochs we would like to send the current revision (and so implicitly epoch) as well
The proposal for a new API is to have a single bulk endpoint for both install and refreshes. A request in JSON to it would look like this:
{
"context": [ // information about the current installed snaps
{
"snap-id":
"revision": // the current revision
"tracking-channel":
"ignore-validation": // current flag about enforcing validation for the snap
},...],
"actions": [ // call this "intents" instead ?
{
"action": "install"|"refresh|refresh-all" // distinguish auto-refresh vs cmdline "snap refresh" ?
// if action is install
"name":
"channel": // optional, defaults to stable
"tag": // ? tag where from is the install requested
"ignore-validation": true|false // defaults to false
// if action is refresh
"snap-id":
// common
"revision": // explicit requested revision (optional)
// if action refresh-all
}...],
"fields": [...] // which detail fields to send in the response? do we need install-fields vs refresh-fields?
}
The response would look like:
{
"results": [{
"snap-id":
"name":
"result": "install"|"refresh"|"error"
"message": // if result is error
"snap": {
... // requested detail fields
}
}...],
}
These request/response assume we would start switching for new store APIs to use ā-ā for field names instead of ā_ā.
Some open questions:
final naming of request/response fields
do we need to be able to specify different field sets for the response entries about installs vs refreshes?
do we want to distinguish a snap refresh vs auto-refreshes in the actions?
We started to work on this, have two questions and some behaviour details (mostly to see if weāre in the same page):
Questions:
Why you need to send the epoch to te server? IMO this doesnāt make sense anymore as the snap is not āin an epochā anymore, now epochs is just two sets of capabilities (read & write), and the server already has this info, soā¦
What is the ātagā? How is it useful or used server side?
Details:
Iām still collecting the list of fields that could be returned for the snap revision, but the āchannel mapā is not needed at all in this response, right?
If there is an error for any snap (e.g. you are not allowed to access it) the response would be 200 in general, but only that snap will be in error state, while the rest of the response is useful, right?
The server will return a 400 in the following cases:
a ārefresh-allā action was combined with a ārefreshā and/or āinstallā actions
the same snap is included in the āinstallā and ārefreshā list
a snap is included in the ārefreshā list, but itās not included in the Context
(for the last two items we could just error on the specific snap, but weāre proposing to completely fail as if youāre mixing the snaps that way you may have a deeper problem when building the request)
about sending epoch, I think it will be the two fields explode likely, I think we discussed this at the rally and @niemeyer asked it for completeness, also not directly related but we might have to deal with refreshing out of a local install, in which case revision wouldnāt be useful or missing in context and the server would need to consider the explicit epoch info.
not super important for now, is just information about the āsourceā of the install, like a marketing campaign tag from an install url but we discussed that
I donāt know, just saying we have that corner case, it might be that it is an install but the install has an epoch field which is to be used as a constraint. My main point is that we have cases where we have an epoch constraints that can come only from the client.
no, I discussed with Gustavo yesterday, and we are thinking to leave out epochs from context, there will still be some special case where the client will pass epoch info but it will be in the operation object and we donāt need to worry about it in the first pass.
This is the list of available fields that could be selected using the fields field in the request:
architectures
base
binary_filesize
binary_path
binary_sha3_384
binary_sha512
confinement
created_at
created_by
epoch
is_released
revision
snap_id
snap_yaml
type
version
was_released
Two notes regarding field:
if field is not included, the response will include ALL snap revisions fields (this is very useful in the default case, or when exploring by hand, as itās an easy way to check which are the available fields or their spelling)
if field is included with an empty list, no specific fields would be returned: each item in the response list will have snap id, name , result (and maybe message) but no snap entry
Please, if you could verify this ASAP it would be great, because it impacts heavily in which internal services and databases we consume to retrieve the needed data. Thanks!
I can try, but @chipaca is off, what exactly is needed depends also how we plan to get metadata (summary, description etc), atm we are getting them with what are now the install/refresh API calls
In order to simplify the API a bit more and stop cargo-culting implementation details from past solutions we will now:
return āappā instead of āapplicationā as the ātypeā field (āapplicationā was mostly returned for CPI compatibility, which is no longer needed in the new api)
return ānullā for base if that field wasnāt specified in the revisionās yaml file (this would otherwise be a single exception in how nullable fields are treated)
return āsnap-nameā instead of ānameā (it was considered a plain ānameā could be confused with the snapās title)
itās a bit strange though that we take ānameā in the input and return āsnap-nameā in the output, thereās a precedent though in snap-declaration to use āsnap-nameā instead of just ānameā, otherwise the only thing commonly prefixed with āsnap-ā is āsnap-idā (we rarely tend to use/say just āidā)
I agree⦠I was going to ask if we could not instead use āsnap-nameā for the input as well. This would also make the api more self-consistent (snap-id and snap-name instead of snap-id and name).