-
Notifications
You must be signed in to change notification settings - Fork 83
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
validate media type of manifest and its descendants #10
Conversation
@@ -149,6 +150,19 @@ func (v *validateCmd) validatePath(name string) error { | |||
|
|||
switch typ { | |||
case image.TypeManifest: | |||
fv, err := os.Open(name) |
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.
I don't think we need to open the file again. Can't we put all the manifest validation behind a single function that takes a ReadCloser
?
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.
fixed.
@@ -240,3 +244,32 @@ loop: | |||
} | |||
return nil | |||
} | |||
|
|||
// ValidateManifestPatten validate the manifest's internal |
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.
Patten
? Is the idea here to separate blob-only validation from blob+descendant validation? In that case, I think the names should be something like ValidateManifestBlob
and ValidateManifestDescendants
with a ValidateManifest
that calls both of those parts.
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.
Or have a single ValidateManifest(reader io.ReadCloser, descendants bool) error
where ValidateManifest(reader, false)
will just look at the blob and `ValidateManifest(reader, true) will look at the blob and descendants.
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.
fixed.
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.
It should be done by a signal function, which I've fixed. But descendants bool
seems unnecessary. I use bytes.NewReader()
for the buffer, instead of re-opening file. The new reader handler can be released when it is finished, so io.ReadCloser
may be not mandatory. it is my own understanding.
Layers []struct { | ||
MediaType string `json:"mediaType"` | ||
} `json:"layers"` | ||
}{} |
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.
Why define your own type instead of using v1.Manifest
?
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.
Yeah, it is my fault. Fixed.
// and its descendants fields media type, such as config and layers, | ||
// to make sure they match to spec definition, or returns an error if | ||
// the validation failed. | ||
func ValidateManifestMediaType(r io.Reader) 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.
I don't see a reason to expose media-type validation as a separate thing. There's just “validation”, which includes checking media types against spec requirements as well as checking other parameter values against spec requirements. That probably means we want a comparison with the appropriate JSON Schema (to catch things like schemaVersion
is unset) and additional checks for cases not covered by JSON Schema (e.g. schemaVersion != 2
). But I don't think a caller will care about picking and choosing particular subsets of validation.
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.
However, validate command will call schema.MediaTypeManifestList.Validate()
directly when validating signal manifest file. I think it is an efficient method to wrap descendants and schema checking in one function(ValidateManifestMediaType
).
But I don't think a caller will care about picking and choosing particular subsets of validation.
The callers are image layout validation and manifest file validation. According to current calling subsequence, they are checking schema. I present the new function to add descendants checking, make it efficient, and keep current checked subsets un-lost.
Am I missing something?
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.
With the call to schema.MediaTypeManifest.Validate
at the end of this function, the name should probably just be ValidateManifest
(since it covers descriptor media types locally and the JSON Schema via schema.MediaTypeManifest.Validate
.
On Mon, Sep 19, 2016 at 12:03:39AM -0700, xiekeyang wrote:
It's easy to build a ReadCloser around a Reader using ioutil.NopCloser |
@wking I fixed it to use |
err = json.NewDecoder(bytes.NewReader(buf)).Decode(&header) | ||
if err != nil { | ||
return errors.Wrap(err, "manifest format mismatch") | ||
} |
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.
You want an error-checked call to r.Close()
here. No need to keep the reader open after you've read it while you walk the descendants.
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.
fixed.
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.
On Mon, Sep 19, 2016 at 07:14:14PM -0700, xiekeyang wrote:
I think we want main → image → schema, and not have a main calling
We're also trying to provide an API that can be consumed directly by
I think we want to lose the current validation subsets ;). Do you see |
@wking |
On Tue, Sep 20, 2016 at 03:57:16AM -0700, xiekeyang wrote:
Collecting manifest validation into one function doesn't seem like a
If you feel like collecting the manifest validation into one function |
// and its descendants fields media type, such as config and layers, | ||
// to make sure they match to spec definition, or returns an error if | ||
// the validation failed. | ||
func ValidateManifestMediaType(r io.ReadCloser) 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.
Why does this take an io.ReadCloser
?
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.
bump
} | ||
|
||
for _, layer := range header.Layers { | ||
if layer.MediaType != string(v1.MediaTypeImageLayer) { |
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 probably way to strict. I'm not sure these media types are "illegal".
} | ||
} | ||
|
||
return schema.MediaTypeManifest.Validate(bytes.NewReader(buf)) |
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 above function should be covered by this Validate
call. What is going on here?
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.
You seems to mean schema.MediaTypeManifest.Validate()
have checked descendants as config and layer media types inside manifest? Actually it doesn't. Currently manifest validation is passed to:
{
"annotations": null,
"config": {
"digest": "sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749",
"mediaType": "foo",
"size": 1459
},
"layers": [
{
"digest": "sha256:8ddc19f16526912237dd8af81971d5e4dd0587907234be2b83e249518d5b673f",
"mediaType": "bar",
"size": 667590
}
],
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"schemaVersion": 2
}
schema.MediaTypeManifest.Validate()
just check manifest own media type and schema patten, not involving descendants media type.
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.
I don't see how this code is checking descendants. It decodes the manifest, then checks the mediatypes of the layers.
It looks like there is a bug in the validation. Go fix that rather than just adding more code.
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.
@stevvooe
This has been discussed [1]. The validation depends on JSON scheme, involving JSON patten files.
@wking and I think that JSON schema can not present all constraints and bug fix had better not to tie to JSON Schema too tightly.
According to current schema file, which shows common patten as below, it is some hard to add this constraints.
{
"mediaType": {
"id": "https://opencontainers.org/schema/image/mediaType",
"type": "string",
"pattern": "^[a-z]+/[0-9a-zA-Z.+]+$"
}
}
JSON schema is third party to image tools, and we just want to fix bug for implementor tool. So we select to fix it here.
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.
If json schema doesn't meet our validation needs, we need to drop it. Adding a new function is not the right way to fix it. It is just adding extra code. The Type.Validate(...)
function should do everything that is needed. There shouldn't be two functions to validate the same thing.
On Tue, Sep 20, 2016 at 12:12:46PM -0700, Stephen Day wrote:
To avoid holding an open file while we walk the descendants (after |
On Tue, Sep 20, 2016 at 12:12:46PM -0700, Stephen Day wrote:
No media types are currently illegal, but this tooling will never |
We have discussed if |
return errors.Wrapf(err, "error reading the io stream") | ||
} | ||
|
||
err = json.NewDecoder(bytes.NewReader(buf)).Decode(&header) |
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.
Don't use decoder when you already have a []byte
'
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.
fixed
} | ||
} | ||
|
||
return schema.MediaTypeManifest.Validate(bytes.NewReader(buf)) |
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.
I don't see how this code is checking descendants. It decodes the manifest, then checks the mediatypes of the layers.
It looks like there is a bug in the validation. Go fix that rather than just adding more code.
@wking Please respond inline. It is very confusing to have the response be in a random comment. The resource should be managed by the caller. It is almost always wrong to use |
I've some view on
Actually, if we define the arg as ReadCloser type, the
It seems to be impracticable. No matter Reader or ReadClose must be read to buffer, calling it means its pointer is seek. So continually using will meet EOF problem. I might not figure out the best solution yet, but I has been doubting |
migrate from opencontainers/image-spec/pull/273 Signed-off-by: xiekeyang <xiekeyang@huawei.com>
return errors.Wrapf(err, "error reading the io stream") | ||
} | ||
|
||
err = json.Unmarshal(buf, &header) |
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.
There is still no reason to read r
into a buffer and then unpack it to JSON. You've previously used:
buf, err := ioutil.ReadAll(r)
…
err = json.NewDecoder(bytes.NewReader(buf)).Decode(&header)
And we all agreed that the NewReader
call wasn't a good idea. But instead of Decode
→ Unmarshal
, I still think you just want to use:
func ValidateManifestMediaType(reader io.Reader) error {
manifest := v1.Manifest{}
err = json.NewDecoder(reader).Decode(&manifest)
…
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.
But if that we will meet the problem [1] that reader(pointer) is seek to end, and the next using reader is failed of EOF. How to avoid this?
So far I not find a example to reuse Reader
in context.
[1] #10 (comment)
On Wed, Sep 21, 2016 at 12:26:12AM -0700, xiekeyang wrote:
Ah, I missed you needing a reader later on for |
On Wed, Sep 21, 2016 at 05:35:57PM -0700, Stephen Day wrote:
I don't think that follows. JSON Schema has the benefit that there
And with this series, the |
@wking @stevvooe |
On Thu, Sep 22, 2016 at 02:49:44AM -0700, xiekeyang wrote:
I doubt this is possible. For example, a JSON-Schema-only validator
I'm fine having JSON-Schema validation being a portion of the full |
Given that this PR only checks that the string of the media is an expected type, what else is needed here? |
On Thu, Sep 22, 2016 at 10:15:43AM -0700, Vincent Batts wrote:
That's all it adds. It's also validating against the JSON Schema So I think cfbc9eb looks pretty good, except for:
|
Why isn't the validation handled in Fix |
I'd submitted a PR, fit to what you said, to opencontainers/image-spec#341. In that PR I modify schema json files, to check manifest descendants types, which is used by I put comment that we will select the better PR in these two and close the other. PTAL opencontainers/image-spec#341, Thanks. |
What's the next step here? |
On Thu, Oct 06, 2016 at 09:15:02AM -0700, Vincent Batts wrote:
Maintainers need to decide where they want this validation code to go. |
this should be closed |
migrate from opencontainers/image-spec/pull/273
cc @wking @runcom @stevvooe
Signed-off-by: xiekeyang xiekeyang@huawei.com