-
Notifications
You must be signed in to change notification settings - Fork 788
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
proxy: Make OpenImageOptional
work with oci-archive:
#2114
base: main
Are you sure you want to change the base?
Conversation
acaf245
to
21aadaf
Compare
cmd/skopeo/proxy.go
Outdated
@@ -235,7 +235,8 @@ func isDockerManifestUnknownError(err error) bool { | |||
// TODO drive this into containers/image properly | |||
func isNotFoundImageError(err error) bool { | |||
return isDockerManifestUnknownError(err) || | |||
errors.Is(err, ocilayout.ImageNotFoundError{}) | |||
errors.Is(err, ocilayout.ImageNotFoundError{}) || | |||
errors.Is(err, os.ErrNotExist) |
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 self-review...perhaps the real fix is in c/image to map enoent there to ocilayout.ImageNotFoundError
?
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 documentation says
// ImageNotFoundError is used when the OCI structure, in principle, exists and seems valid enough,
// but nothing matches the “image” part of the provided reference.
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.
My first impression is to wonder why this needs special handling.
Obviously “an image not found on the registry” is something that can only be detected by talking to the registry with full credentials, i.e. inside Skopeo. Similarly “a tag not found inside an OCI archive” requires an OCI archive implementation.
But if the archive just doesn’t exist… it might make sense for Skopeo to treat that uniformly, for callers that provide an user-specified transport:
image syntax without understanding the details of that… and then we get to discuss semantics of what “uniformly” means.
But rpm-ostree compose image
seems to have its own format=oci
option, so the transport:
image value is not user-provided.
Maybe a different way to ask this: Would we be expected to similarly return 0 for docker://nxdomain.invalid/something
?) If not, what’s the difference?
Right now the documentation of OpenImageOptional
says “If the image does not exist, zero
is returned.”.
What is the criteria for classifying errors as “image does not exist” vs. “other error opening an image”? Does the documentation of OpenImageOptional
need clarifying, or updating?
*shrug* rpm-ostree
is the only known user, so pragmatically speaking it gets to shape the proxy API however it is useful for rpm-ostree
; but I’d like the Skopeo-repo documentation of that API to be reasonably clear about what are the properties that need maintaining. (“The ostree-rs-ext
tests continue to pass” is one way to document those properties, I guess. I find that inelegant but I can live with that.)
cmd/skopeo/proxy.go
Outdated
@@ -235,7 +235,8 @@ func isDockerManifestUnknownError(err error) bool { | |||
// TODO drive this into containers/image properly | |||
func isNotFoundImageError(err error) bool { | |||
return isDockerManifestUnknownError(err) || | |||
errors.Is(err, ocilayout.ImageNotFoundError{}) | |||
errors.Is(err, ocilayout.ImageNotFoundError{}) || | |||
errors.Is(err, os.ErrNotExist) |
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 documentation says
// ImageNotFoundError is used when the OCI structure, in principle, exists and seems valid enough,
// but nothing matches the “image” part of the provided reference.
cmd/skopeo/proxy.go
Outdated
@@ -235,7 +235,8 @@ func isDockerManifestUnknownError(err error) bool { | |||
// TODO drive this into containers/image properly | |||
func isNotFoundImageError(err error) bool { | |||
return isDockerManifestUnknownError(err) || | |||
errors.Is(err, ocilayout.ImageNotFoundError{}) | |||
errors.Is(err, ocilayout.ImageNotFoundError{}) || | |||
errors.Is(err, os.ErrNotExist) |
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 all that precise — e.g. I think it matches if /var/tmp
does not exist.
(See the top-level comment first — what is the condition isNotFoundImageError
should actually be checking for? Assuming that being precise about it matters at all…)
For registries, it's really that the server returns HTTP 404 and that's how it works now. Giving something that doesn't expose the registry API (for example) we correctly error out:
Other cases like failure to make a TCP connection, DNS doesn't resolve all should error out. Only the "HTTP server returned 404" or semantically equivalent should return (in Rust terms)
Yes, agree. In this scenario, that's suboptimal but still okay. The case I care about most are registry and |
How about this variant instead? (requires a patch to c/image)
|
(not going to lie, it took me at least 20 minutes of confusion to realize that there's two copies of |
Tangential to this of course is my very strong opinion that downcasting and parsing errors should be an extremely rare event in code, and in e.g. languages like Rust the right thing to do is exactly how we model this API in the Rust bindings:
The common "not found" case is the |
Yes, they are distinct options but they are very much intended to exactly map to the c/image transports and work the same way from a user PoV. (I just take the liberty to add a nicer |
This still matches the |
Hmm. So with |
(Many things in Go are awkward and unsafe, with no sum types, no optionality… The complete lack of compiler support for errors, and things like I think that works for a frequent expected cause of a specific operation; the c/image “transport” abstraction makes this harder (in a sense, that’s exactly what this PR is hitting — after abstracting to the c/image can just about manage to provide a common Ultimately, API stability does not allow us to change |
By adding the standard ENOENT to our list of errors. I hit this while working on coreos/rpm-ostree#4598 which is a tool that builds base images and wants to query if the image exists beforehand. Signed-off-by: Colin Walters <[email protected]>
21aadaf
to
b80b222
Compare
No, |
Thanks, I didn't know that. But...I guess then I'm arguing that at least for all use cases I can think of, I really do want to treat "oci-archive file doesn't exist" here the same as Unlike |
I've updated the main PR here so far to: In c/image:
In skopeo:
|
This is for containers/skopeo#2114 which is in turn a dependency of coreos/rpm-ostree#4598 Basically I want to map ENOENT to `ImageNotFound`, because the build tooling wants to treat "target image is not present" differently from "DNS lookup failed" or "we got EPERM". There's a bit of code motion here because we need to move the `os.Open()` call before creating a temporary directory. Signed-off-by: Colin Walters <[email protected]>
This is for containers/skopeo#2114 which is in turn a dependency of coreos/rpm-ostree#4598 Basically I want to map ENOENT to `ImageNotFound`, because the build tooling wants to treat "target image is not present" differently from "DNS lookup failed" or "we got EPERM". There's a bit of code motion here because we need to move the `os.Open()` call before creating a temporary directory.
Moved the c/image changes to containers/image#2123 |
This is for containers/skopeo#2114 which is in turn a dependency of coreos/rpm-ostree#4598 Basically I want to map ENOENT to a clear error, because the build tooling wants to treat "target image is not present" differently from "DNS lookup failed" or "we got EPERM". There's a bit of code motion here because we need to move the `os.Open()` call before creating a temporary directory. Signed-off-by: Colin Walters <[email protected]>
(The archives are not editable that way — they can either be read or written. But I do think that when reading a multi-image archive, differentiating the two failures should be possible.) |
This is for containers/skopeo#2114 which is in turn a dependency of coreos/rpm-ostree#4598 Basically I want to map ENOENT to a clear error, because the build tooling wants to treat "target image is not present" differently from "DNS lookup failed" or "we got EPERM". There's a bit of code motion here because we need to move the `os.Open()` call before creating a temporary directory. Signed-off-by: Colin Walters <[email protected]>
This is for containers/skopeo#2114 which is in turn a dependency of coreos/rpm-ostree#4598 Basically I want to map ENOENT to a clear error, because the build tooling wants to treat "target image is not present" differently from "DNS lookup failed" or "we got EPERM". There's a bit of code motion here because we need to move the `os.Open()` call before creating a temporary directory. Signed-off-by: Colin Walters <[email protected]>
This is for containers/skopeo#2114 which is in turn a dependency of coreos/rpm-ostree#4598 Basically I want to map ENOENT to a clear error, because the build tooling wants to treat "target image is not present" differently from "DNS lookup failed" or "we got EPERM". There's a bit of code motion here because we need to move the `os.Open()` call before creating a temporary directory. Signed-off-by: Colin Walters <[email protected]>
This is for containers/skopeo#2114 which is in turn a dependency of coreos/rpm-ostree#4598 Basically I want to map ENOENT to a clear error, because the build tooling wants to treat "target image is not present" differently from "DNS lookup failed" or "we got EPERM". There's a bit of code motion here because we need to move the `os.Open()` call before creating a temporary directory. Signed-off-by: Colin Walters <[email protected]>
This is for containers/skopeo#2114 which is in turn a dependency of coreos/rpm-ostree#4598 Basically I want to map ENOENT to a clear error, because the build tooling wants to treat "target image is not present" differently from "DNS lookup failed" or "we got EPERM". There's a bit of code motion here because we need to move the `os.Open()` call before creating a temporary directory. Signed-off-by: Colin Walters <[email protected]>
This is for containers/skopeo#2114 which is in turn a dependency of coreos/rpm-ostree#4598 Basically I want to map ENOENT to a clear error, because the build tooling wants to treat "target image is not present" differently from "DNS lookup failed" or "we got EPERM". There's a bit of code motion here because we need to move the `os.Open()` call before creating a temporary directory. Signed-off-by: Colin Walters <[email protected]>
A friendly reminder that this PR had no activity for 30 days. |
@cgwalters the c/image error type PR has merged; do you want to update this? |
By adding the standard ENOENT to our list of errors.
I hit this while working on
coreos/rpm-ostree#4598
which is a tool that builds base images and wants to query if the image exists beforehand.