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

daemon: add notices API #13364

Merged
merged 10 commits into from
Dec 6, 2023
Merged

Conversation

olivercalder
Copy link
Member

This PR adds the notices API endpoints, which are originally from pebble. The spec for pebble notices is JUu48

Various modifications are required to adapt the notices API to snapd. The most notable are the removal of the custom notice type and the removal of the POST notices handler, both of which result from the fact that snapd does not have a notices client or user-defined notices.

Additionally, snapd uses the strutil package internal to snapd, while pebble uses strutil from github.com/canonical/x-go. The prior addition of MultiCommaSeparatedList to the x-go/strutil package must be ported to snapd/strutil as well.

The corresponding PR from pebble can be found at: canonical/pebble#296

@github-actions github-actions bot added the Needs Documentation -auto- Label automatically added which indicates the change needs documentation label Nov 15, 2023
@olivercalder olivercalder added Needs Samuele review Needs a review from Samuele before it can land Needs Documentation 📖 and removed Needs Documentation -auto- Label automatically added which indicates the change needs documentation labels Nov 15, 2023
@olivercalder
Copy link
Member Author

NEWS.md will need to be modified to note that the notices API has been added. This can likely occur along with other API documentation changes.

@github-actions github-actions bot added the Needs Documentation -auto- Label automatically added which indicates the change needs documentation label Nov 15, 2023
@olivercalder olivercalder marked this pull request as ready for review November 15, 2023 16:09
Copy link
Contributor

@miguelpires miguelpires left a comment

Choose a reason for hiding this comment

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

LGTM

if !noticeType.Valid() {
// Ignore invalid notice types (so requests from newer clients
// with unknown types succeed).
continue
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: there could be a short test for this

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point, thanks! Technically, I'm not sure that this check is even necessary, since the notice filter within overlord/state/notices.go will happily accept arbitrary strings, but I agree it's safer to sanity check them here before they make it to the state notices code. I'll add a test for this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, if the user only has invalid notice types, the current behavior would return all notices (assuming no other filters), since this is equivalent to an empty types filter. I'll add a check and tests to make sure no notices are returned in this case.

Comment on lines 215 to 217
elapsed := time.Since(start)
c.Check(elapsed > 10*time.Millisecond, Equals, true)
c.Check(elapsed < time.Second, Equals, true)
Copy link
Contributor

Choose a reason for hiding this comment

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

This feels a bit brittle. It's probably fine but I'm thinking about the slower systems on which spread runs, we've had issues with timing dependent things before I think. Just something to be on the lookout in the first runs

Copy link
Member Author

Choose a reason for hiding this comment

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

I think checking elapsed > 10*time.Millisecond is the brittle part, as it could be that the goroutine waiting to cancel the context runs for a while before start time is recorded. I think the solution is to record the start time before spawning the cancel goroutine. Checking that elapsed time is less than 1s should be safe, I would think, on all systems.


st := s.d.Overlord().State()
go func() {
time.Sleep(10 * time.Millisecond)
Copy link
Contributor

Choose a reason for hiding this comment

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

If we do see any timing-related issues and end up having to mock WaitNotices, we could also change this one

Copy link
Member

@Meulengracht Meulengracht 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, the code looks nice in general, and nice tests! A couple of comments

daemon/api_notices.go Show resolved Hide resolved
strutil/strutil.go Show resolved Hide resolved
@@ -231,6 +231,16 @@ func CommaSeparatedList(str string) []string {
return filtered
}

// MultiCommaSeparatedList parses each string in strs with CommaSeparatedList
// and returns the concatenation of all parsed values.
func MultiCommaSeparatedList(strs []string) []string {
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick, but I think it provides clearer intent:

Suggested change
func MultiCommaSeparatedList(strs []string) []string {
func FlattenCommaSeparatedLists(strs []string) []string {

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree and prefer your approach to this naming and description, but this is an existing function in the "github.com/canonical/x-go/strutil" package, so for compatibility's sake I don't think we should change them here, if the code body is otherwise unchanged.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, a bit annoying we have a copy of another package, but I see

@codecov-commenter
Copy link

Codecov Report

Attention: 3 lines in your changes are missing coverage. Please review.

Comparison is base (d01f435) 78.80% compared to head (d1cf801) 78.85%.
Report is 22 commits behind head on master.

Files Patch % Lines
daemon/api_notices.go 96.00% 2 Missing and 1 partial ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #13364      +/-   ##
==========================================
+ Coverage   78.80%   78.85%   +0.04%     
==========================================
  Files        1022     1024       +2     
  Lines      127295   127648     +353     
==========================================
+ Hits       100317   100654     +337     
- Misses      20697    20707      +10     
- Partials     6281     6287       +6     
Flag Coverage Δ
unittests 78.85% <96.70%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@Meulengracht Meulengracht left a comment

Choose a reason for hiding this comment

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

Thanks for the changes, +1

Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

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

thanks, one remark about ReadAccess

Comment on lines 31 to 37
ReadAccess: openAccess{},
}

noticeCmd = &Command{
Path: "/v2/notices/{id}",
GET: getNotice,
ReadAccess: openAccess{},
Copy link
Collaborator

Choose a reason for hiding this comment

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

until we have the distinction of public|private coming together with the per-user work we probably want authenticatedAccess here (that also matches UserOK on the pebble side)

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point, thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see that this was added just like this on the pebble side, I wonder though if both there and here more helper could move here, otoh it's really an orthogonal issue to the PR

@olivercalder
Copy link
Member Author

@ernestl or @Meulengracht , could you please advise me on what I need to do for recording the addition of the notices API in NEWS.md?

@pedronis pedronis self-requested a review December 4, 2023 16:38
Copy link
Collaborator

@pedronis pedronis 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

@olivercalder olivercalder added the Skip spread Indicate that spread job should not run label Dec 6, 2023
@olivercalder
Copy link
Member Author

olivercalder commented Dec 6, 2023

Added "Skip" spread so I can rebase without running spread tests. Previous spread run had only 1 failure, on Ubuntu 20.04-arm (log here: https://github.com/snapcore/snapd/actions/runs/7105573085/job/19355042068?pr=13364)

benhoyt and others added 6 commits December 6, 2023 11:13
This is a port from Pebble into snapd of the notices API. The original
PR can be found at: canonical/pebble#296

Signed-off-by: Oliver Calder <[email protected]>
This new function is useful for parsing `url.Values` where there may be
multiple values for the same key, and those values may themselves be
comma-separated values.

This is a port of a commit from the `x-go` package, which was originally
intended to be used in pebble. The commit can be found here:

canonical/x-go@32684ae

Signed-off-by: Oliver Calder <[email protected]>
As notices are originally from pebble, various adjustments must be made
in order for the ported API to work with snapd.

Signed-off-by: Oliver Calder <[email protected]>
Unlike pebble, snapd does not have a client for notices, and notices
should not be created from outside of snapd. As a result, there is no
need for a POST handler on the notices API.

Signed-off-by: Oliver Calder <[email protected]>
In snapd, there are no user-defined notices, so there is no need for a
custom notice type.

Signed-off-by: Oliver Calder <[email protected]>
Invalid notice types are ignored when parsing the API request to
construct the notice filter. However, if only invalid notice types are
included in the request, discarding all types results in a filter
indistinguishable from one which never had any types in the first place,
and thus should return notices of any type. This commit fixes this
behaviour, so no notices are returned if only invalid notice types are
requested.

Signed-off-by: Oliver Calder <[email protected]>
Most importantly, wait to lock the state until after the optional
duration has been parsed, in case an error occurs. Also, moves the types
query parsing/sanitization into its own function, since this cleans up
the GET notices handler and better matches future handling of user ID
filtering.

Signed-off-by: Oliver Calder <[email protected]>
TODO: probably revert this commit once per-user notices are implemented,
as that will provide the proper restrictions so that non-privileged
users cannot read private notices intended for other users.

Signed-off-by: Oliver Calder <[email protected]>
@olivercalder olivercalder reopened this Dec 6, 2023
@olivercalder olivercalder merged commit 593f383 into canonical:master Dec 6, 2023
64 of 72 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Documentation -auto- Label automatically added which indicates the change needs documentation Needs Documentation 📖 Needs Samuele review Needs a review from Samuele before it can land Skip spread Indicate that spread job should not run
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants