-
Notifications
You must be signed in to change notification settings - Fork 395
Close with error #236
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
Close with error #236
Conversation
mtrmac
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
skopeo should be similarly updated to handle the errors.
I am still not sold on this being truly worthwhile (all this only to report a failure in daemonImageSource when we fail to remove a temporary file which will be very likely cleaned up by systemd-tmpfiles in the worst case?), but if we are doing this, let’s actually do it right.
docker/daemon/daemon_dest.go
Outdated
| var err error | ||
| if !d.committed { | ||
| logrus.Debugf("docker-daemon: Closing tar stream to abort loading") | ||
| err = errors.New("Aborting upload, daemonImageDestination closed without a previous .Commit()") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not an error in .Close(); if the caller decides to abort without a .Commit(), and the upload is successfully aborted, .Close() should indicate success.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still outstanding.
| Reference() ImageReference | ||
| // Close removes resources associated with an initialized ImageDestination, if any. | ||
| Close() | ||
| Close() error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The caller in copy.Image should be updated to handle the error.
| Reference() ImageReference | ||
| // Close removes resources associated with an initialized UnparsedImage, if any. | ||
| Close() | ||
| Close() error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The callers in copy.Image (both for UnparseImage and Image) should be updated to handle the error.
And perhaps doc.go as well?
|
To link the two, this fixes #82. |
|
Will make adjustments, and file a PR on skopeo in the next few days. |
484c771 to
2682f2f
Compare
|
Ok I updated this to handle close errors, I also changed the return convention (read the comments at the inner-top of copy.Image) to use output variables. All is explained in comments, but if this feels too cumbersome for the benefits we can talk about alternatives. |
2682f2f to
5bcdf40
Compare
| // source image admissibility. | ||
| func Image(policyContext *signature.PolicyContext, destRef, srcRef types.ImageReference, options *Options) (retErr error) { | ||
| // XXX this function uses an output parameter for the error return value. | ||
| // Setting this and returning is the ideal way to return an error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at https://golang.org/ref/spec#Return_statements , even with a named return value it would be perfectly fine to just return somerrorvalue AFAICS.
(Also, doesn’t XXX mean “this is bad”? Perhaps just NOTE: or something like that.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I typically use it to say "WARNING" or something of the like: "pay attention" basically.
copy/copy.go
Outdated
| defer dest.Close() | ||
| defer func() { | ||
| if err := dest.Close(); err != nil { | ||
| retErr = errors.Wrapf(retErr, "dest: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only happen if retErr == nil; the original value of retErr was the primary cause we are failing; that dest.Close() has failed may be completely unrelated, or it may be a side effect of the original retErr failure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok sure, I was just thinking that maybe it'd be nice to have all the error context in the event of a copy failure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry, I wasn’t paying enough attention to notice that this preserves both. Let me check…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
… something like this would be nice if we can make that human-readable. See how the other errors.Wrapf calls in here try to tell the user what is going on. I am not sure that this is workable here:
errors.Wrapf(retErr, "Error closing destination: %v, after primary failure", err)
is bordering on incomprehensible, especially if err were long / created by several errors.Wrapf calls. (We can make the underlying data type situation better by using something like aggregateErr from openshift-copies.go, but that is probably even worse for readability.)
If we can’t make that human-readable, I think preserving a non-nil retErr is more important than the failure from .Close.
@runcom ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I get the concern.
What if I did something like this:
errors.Wrapf(retErr, "(destination error %v) ", err)
That way each indepednent error would be wrapped by parens. I could also add newlines.
I think the errors will be valuable context in the face of other, higher level errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s certainly better than my attempt.
The code as is (making daemonImageSource.Close fail using an invalid path):
$ sudo ./x docker-daemon:busybox:latest dir:d
FATA[0000] Error copying: source: remove makethisfail//var/tmp/docker-daemon-tar266436759: no such file or directory: Error writing blob: open d/dir-put-blob135662858: no such file or directory
quite misleading about the cause/effect relationships
“primary error” wording:
FATA[0000] Error copying: Error closing source: remove makethisfail//var/tmp/docker-daemon-tar088311212: no such file or directory, after primary failure: Error writing blob: open d/dir-put-blob812853531: no such file or directory
Still focusing on the wrong thing (closing failure)
With the parentheses:
FATA[0000] Error copying: (source error remove makethisfail//var/tmp/docker-daemon-tar460112488: no such file or directory): Error writing blob: open d/dir-put-blob983238823: no such file or directory
Certainly better. Good enough?
Newlines are attractive (they would even allow us to build a bulleted list :) ) but risky, the caller is fairly likely not expecting them.
At this point I am really not sure, I’ll let @runcom weigh in.
copy/copy.go
Outdated
| if unparsedImage != nil { | ||
| unparsedImage.Close() | ||
| if err := unparsedImage.Close(); err != nil { | ||
| retErr = errors.Wrapf(retErr, "unparsed: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
copy/copy.go
Outdated
| defer src.Close() | ||
| defer func() { | ||
| if err := src.Close(); err != nil { | ||
| retErr = errors.Wrapf(retErr, "source: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
docker/daemon/daemon_dest.go
Outdated
| var err error | ||
| if !d.committed { | ||
| logrus.Debugf("docker-daemon: Closing tar stream to abort loading") | ||
| err = errors.New("Aborting upload, daemonImageDestination closed without a previous .Commit()") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still outstanding.
copy/copy.go
Outdated
| if err != nil { | ||
| return errors.Wrapf(err, "Error initializing destination %s", transports.ImageName(destRef)) | ||
| retErr = errors.Wrapf(err, "Error initializing destination %s", transports.ImageName(destRef)) | ||
| return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is not necessary. return X will set retErr = x implicitly.
5bcdf40 to
33ad61a
Compare
|
PTAL changes:
|
1c797ef to
eca0900
Compare
|
#240 is blocking this. |
|
LGTM pending tests. (Shouldn't
|
|
👍 |
eca0900 to
9d270bc
Compare
|
rebased |
|
@erikh sorry needs one last rebase before I merge this |
This allows us to provide in the image interfaces a method of providing an error at close time. This is only currently used in a few situations. Signed-off-by: Erik Hollensbe <github@hollensbe.org>
9d270bc to
cdb838d
Compare
|
done
…On Sat, Feb 25, 2017 at 3:31 AM, Antonio Murdaca ***@***.***> wrote:
@erikh <https://github.com/erikh> sorry needs one last rebase before I
merge this
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#236 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AABJ6-qzkfc8JfWeurltFgnwDkS-3Iyyks5rgBElgaJpZM4L32DS>
.
|
This patch augments the interfaces' close methods with an error return which is
only actually useful in one or two spots for now. However, it can be utilized
later as things fill in.
Fixes #82