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

many: make snap pack --check-skeleton error logs consistent #14547

Merged

Conversation

ZeyadYasser
Copy link
Contributor

This improves some inconsistencies in "snap pack --check-skeleton" error logs.

  • Shows detailed logs only if SNAPD_DEBUG is set.
  • Returns first error caught

It should be explored how to aggregate errors with consistency in mind as this is parsed by snapcraft.

For more context: https://warthogs.atlassian.net/browse/SNAPDENG-23795

This fixes inconsistencies in "snap pack --check-skeleton" error
logs consistent.

- shows detailed logs only if SNAPD_DEBUG is set.
- returns first error caught

It should be explored how to aggregate errors with consistency
in mind as this is parsed by snapcraft.

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
@ZeyadYasser ZeyadYasser added this to the 2.66 milestone Sep 27, 2024
Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
Copy link

codecov bot commented Sep 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 78.88%. Comparing base (ac897ee) to head (30aac23).
Report is 47 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #14547      +/-   ##
==========================================
+ Coverage   78.85%   78.88%   +0.02%     
==========================================
  Files        1079     1082       +3     
  Lines      145615   146075     +460     
==========================================
+ Hits       114828   115232     +404     
- Misses      23601    23646      +45     
- Partials     7186     7197      +11     
Flag Coverage Δ
unittests 78.88% <100.00%> (+0.02%) ⬆️

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
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

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

LGTM, looks very good.

I left a question about error wrapping with fmt.Errorf and a suggestion for one more like of tests but consider this approved.

if firstBadModeErr != nil {
// TODO: fmt.Errorf("%w: %w", ErrBadModes, firstBadModeErr) when using go 1.20+
// TODO: aggregate bad mode errors not just the first one
return fmt.Errorf("%w: %v", ErrBadModes, firstBadModeErr)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use %w twice? I think we can but I'm not sure if this goes all the way back to go 1.18.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately we can't, I believe we need go 1.20 for that https://tip.golang.org/doc/go1.20#errors

@@ -107,7 +107,7 @@ version: 1
c.Assert(err, IsNil)

err = snap.ValidateSnapContainer(s.container(), info, discard)
c.Check(err, Equals, snap.ErrBadModes)
c.Check(err, ErrorMatches, `snap is unusable due to bad permissions: "." should be world-readable and executable, and isn't: drwx------`)
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps add something that checks with the equivalent of errors.Is, for completeness.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point, thanks! I added those to all relevant tests

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
Copy link
Collaborator

@ernestl ernestl left a comment

Choose a reason for hiding this comment

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

Thanks, looks good, one nitpick question, and idea for generalising accumulation/first error.

@@ -122,7 +122,7 @@ func loadAndValidate(sourceDir string, yaml []byte) (*snap.Info, error) {
return nil, fmt.Errorf("cannot validate snap %q: %v", info.InstanceName(), err)
}

if err := snap.ValidateSnapContainer(container, info, logger.Noticef); err != nil {
if err := snap.ValidateSnapContainer(container, info, logger.Debugf); err != nil {
Copy link
Collaborator

@ernestl ernestl Sep 30, 2024

Choose a reason for hiding this comment

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

This seems little beyond the short term requirement. Concern is anyone relying on the log entries..., preference is to do this as part of larger rework for aggregation.

@pedronis

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switched back to Noticef to avoid breaking scripts that depend on the logs until we have a long term soln.

@@ -122,7 +122,7 @@ func loadAndValidate(sourceDir string, yaml []byte) (*snap.Info, error) {
return nil, fmt.Errorf("cannot validate snap %q: %v", info.InstanceName(), err)
}

if err := snap.ValidateSnapContainer(container, info, logger.Noticef); err != nil {
if err := snap.ValidateSnapContainer(container, info, logger.Debugf); err != nil {
return nil, err
Copy link
Collaborator

@ernestl ernestl Sep 30, 2024

Choose a reason for hiding this comment

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

Wondering if it makes sense to give context that we are busy with "container validation", similar to what is done for "snap validation" with "cannot validate snap %q:"...

but perhaps not worth the repercussions as part of short term minimal fix...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, it's better to avoid breaking scripts that depend on some regex until we have a good plan.

hasBadModes = true
err := fmt.Errorf("%q should be world-readable and executable, and isn't: %s", path, mode)
logf("in %s %q: %v", contType, name, err)
if firstBadModeErr == nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This works.
It made me think about error aggregation and identification of first instance as a generally useful concept.

Could create error type for aggregation, containing list of Errors []error that defaults to error[0] for message, but can be iterated to concert errors to e.g. json output or detail log entry etc as required.
This could the become e.g. accErrorBadModes.add(...)

Anyways, more applicable to longer term solution...

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
@ernestl
Copy link
Collaborator

ernestl commented Sep 30, 2024

Blocked, requested and now awaiting feedback from snapcraft team before merging.

Copy link

@mr-cal mr-cal left a comment

Choose a reason for hiding this comment

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

Is it possible to hide the container.go error? I'm still seeing it in stderr.

before:

> snapcraft pack
Cannot pack snap: 2024/09/30 08:52:01.680392 container.go:360: in snap "hello-world": "foo" should be world-readable and executable, and isn't: -rw-rw-r--
error: snap is unusable due to bad permissions
Full execution log: '/home/developer/.local/state/snapcraft/log/snapcraft-20240930-085200.474382.log'

after:

> snapcraft pack
Cannot pack snap: 2024/09/30 08:39:22.700825 container.go:366: in snap "hello-world": "foo" should be world-readable and executable, and isn't: -rw-rw-r--
error: snap is unusable due to bad permissions: "foo" should be world-readable and executable, and isn't: -rw-rw-r--
Full execution log: '/home/developer/.local/state/snapcraft/log/snapcraft-20240930-083921.722642.log'

@ZeyadYasser
Copy link
Contributor Author

Is it possible to hide the container.go error? I'm still seeing it in stderr.

That was the initial approach, but we decided to make the change smaller to avoid breaking anything that depended on those logs.

Copy link

@mr-cal mr-cal left a comment

Choose a reason for hiding this comment

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

Since the internal container.go messages can't be omitted at this time, snapcraft will have to parse the output. This should be feasible since only one line will begin with error: and now always contains details of the first error.

Thanks!

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
@ernestl
Copy link
Collaborator

ernestl commented Oct 1, 2024

Failures are all unrelated to the changes.

@ernestl ernestl merged commit 7446f59 into canonical:master Oct 1, 2024
48 of 56 checks passed
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.

4 participants