-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
vendor: github.com/containerd/containerd v1.7.7 #4315
Conversation
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.
Looks like the windows error is legit
eeeeab3
to
5a1dad7
Compare
Same as #4301 (comment)
|
5a1dad7
to
60915b0
Compare
This one is expected, see #4316 |
util/purl/image_test.go
Outdated
@@ -91,7 +91,6 @@ func TestRefToPURL(t *testing.T) { | |||
func TestPURLToRef(t *testing.T) { | |||
testDgst := digest.FromBytes([]byte("test")).String() | |||
p := platforms.Normalize(platforms.DefaultSpec()) | |||
p.OSVersion = "" // OSVersion is not supported in PURL |
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 removed this "reset", per #4301 (comment)
But I'm somewhat wondering if that's "correct"; are package-URLs meant to be a canonical URL for a specific platform, and if so, should (could) they be os-version specific? (and include the os-version?)
Looking at containerd/containerd#8778 again, I'm starting to wonder if that change was the right thing to do (although, admitted, "Parse" was already filling in missing information). The main issue is that it does not provide for a os-version element, but now does "dream up" one, and it somewhat feels like the paints shut the option of adding an element for os-version in the string-representation.
I wonder if Parse
and <insert defaults>
should be separate things, but maybe that ship already sailed when it was decided to "only architecture OR platform are required, everything else being optional".
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, I don't see at all how containerd/containerd#8778 could be correct. The Parse()
converts from input string to struct, but with that PR it doesn't use the input string, but the properties of the machine that does the parsing, which is completely unrelated.
Same for this test. If the input for the test is empty OSVersion
then one should not just magically appear from purl conversion.
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 was considering doing the reverse, and update the Purl function to explicitly reset the os-version field; but that's assuming the string format would never support an os-version field. It would perhaps be slightly more correct though; WDYT?
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.
@tonistiigi @jedevc I updated the PR, and updated PURLToRef
to explicitly exclude the OSVersion
(and OSFeatures
) from the result.
3979486
to
52afe1d
Compare
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.
Dockerfile should also be updated (can be another PR)
Line 4 in 4c93208
ARG CONTAINERD_VERSION=v1.7.2 |
full diff: containerd/continuity@v0.4.1...v0.4.2 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: stretchr/testify@v1.8.3...v1.8.4 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: golang/sys@v0.8.0...v0.10.0 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: golang/crypto@v0.2.0...v0.11.0 full diff: golang/text@v0.9.0...v0.11.0 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: golang/net@v0.10.0...v0.13.0 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: - microsoft/hcsshim@v0.10.0-rc.8...v0.11.1 - containerd/containerd@v1.7.2...v1.7.7 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
52afe1d
to
f7e0ee1
Compare
Rebased to get a fresh run of CI, and I noticed that the |
Is there a strong reason to not do this? If there isn't, we should always keep these in sync. |
No, don't think there's a strong reason (honestly, forgot doing so) I do think it's good to do so in either a separate commit, or a separate PR though to verify that updating just the binary / just the vendor code / vice-versa all works; updating them individually should work, and if updating one of them breaks CI, there's a serious issue in containerd. I'll open a PR to update the binaries as well. |
@@ -86,6 +86,21 @@ func PURLToRef(purl string) (string, *ocispecs.Platform, error) { | |||
if err != nil { | |||
return "", nil, err | |||
} | |||
|
|||
// OS-version and OS-features are not included when serializing a |
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 problem in here looks pretty clearly a bug in the new version of platforms.Parse()
where it does not do the job of parsing the string to a struct https://github.com/containerd/containerd/blame/main/platforms/platforms.go#L240-L253 . We shouldn't try to patch this by covering up these side-effects in the caller to make the test pass. There are 10+ calls of platforms.Parse()
in buildkit. The only reason this showed up in purl test is likely that the integration tests are not running on windows atm. (might be missing some coverage as well).
I think the containerd patches should be reverted and if a string can be parsed to a struct with OSVersion/OSFeatures
then the first step is to define how OSVersion
is represented in string form.
cc @dmcgowan
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.
Which PR specifically? Seems this should be easy to unit test but for some reason none of these have unit tests. Microsoft folks last changed this code, we can request better test coverage around it. I don't know enough about what the behavior should even be for these fields.
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.
Changes to parser.Parse
in containerd/containerd#8778 . They read the configuration of the current system instead of parsing the input, so the return value will always be different depending on the caller's operating system or windows versions.
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.
Yes, I agree that the latest changes to Parse()
are far from ideal. It's digging in deeper into an already taken direction, where Parse()
doesn't just parse but also "fills in the missing pieces" by applying defaults that are based on the host;
amd64
(arch only) gets "parsed" intolinux/amd64
,darwin/amd64
,windows/amd64
(etc) depending on the hostlinux
(os only) gets "parsed" intolinux/amd64
,linux/arm64
(etc), depending on the host- and now
windows
gets "parsed" intowindows/<host-arch>/<host OS version>
The first two are already somewhat problematic (depending on "what" the result is used for), but the os-version
is (imo) even more problematic because there is no string-representation of that field.
I guess in an ideal world, Parse
would do just that; parse the string representation into a struct (possibly with some amount of normalizing), but leave it to the consumer to fill in defaults (if any). Some options could be to;
- make
Parse
accept functional argument(s) to apply defaults (and/or normalizing) - make
Parse
accept a struct with defaults
And ideally also have a string representation of the additional fields (os-version
, os-features
?), so that information can be preserved when serializing to a string.
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 first two are already somewhat problematic (depending on "what" the result is used for), but the os-version is (imo) even more problematic because there is no string-representation of that field.
Yes, the first two could maybe be better with a more explicit API, but these are not blocking for us. These are the "incomplete" values that make it more obvious that the behavior might be undefined and if we wanted to we could just not allow these (we never document/promote them anyway and users should never use them imho). But for the new windows one, these are the full representations and there is no way to provide input where the parser would just parse the input in a stable form.
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.
CC @kiashok @profnandaa for visibility on this from the MSFT side.
To summarise, Parse()
should just parse and return a struct with fields accurately populated based on the string we've just parsed. We absolutely need OSVersion
on Windows to satisfy the matcher and fetch an image that can actually run on the host we're running on, but that value should be explicitly set (if needed) before sending it to the matcher. We should not add defaults that can vary based on the environment we're running on, when parsing.
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.
To summarise, Parse() should just parse and return a struct with fields accurately populated based on the string we've just parsed.
Correct; parsing should just parse what's in the string. The current "fill in host OS or host Architecture if missing" is something we should look at deprecating (but not currently the highest priority as it's not a commonly used or advertised feature).
We absolutely need OSVersion on Windows to satisfy the matcher and fetch an image that can actually run on the host we're running on, but that value should be explicitly set (if needed) before sending it to the matcher.
Yes, matching should be a separate concern from Parsing; in an ideal world, the platform's string representation would also allow for os_version
to be included, in which case matching should probably skip heuristics (and just do what's requested) but that's not the case yet.
But I guess a specific MatchComparer
could be used to either fill in the missing os_version
based on the host/environment, or to set the os_version
before matching.
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 definitely needs to be up to the MatchComparer
that decides how the host's details are intermingled, because the same Platform
object can be a match or a non-match depending on the type of container to be run: Process-Isolated, HyperV-isolated, and Host-Process containers all have different rules for OSVersion
values are selectable (They're approximately super-sets in that order, as it happens; empty OSVersion
is semantically meaningful: "there's no OS present in this image" which only Host-Process mode can execute) and MatchComparer
is the thing we want to vary in containerd to achieve this; I don't recall if the actual mechanism for this variation has been implemented yet though, I recall that it turns out to be a frontend (containerd/CRI, buildkit) concern and there was some issues found in a containerd/cri prototype, but I haven't looked for a while.
So the platforms.Parse
(and presumably the reverse?) is intermingling concerns that should be in the Windows-specific MatchComparer
implementations. (Which is already a thing: you can only currently get one via the Windows-build DefaultComparer call, as I recall; that could be nicer... And it implements the Process-Isolation logic)
It's a fair way down the track, but at some point we may also want, e.g., --platform windows/amd64//10.0.0.19242
to be able to be used with a HyperV runtime to build Windows-ABI-incompatible images from the same Dockerfile on a single host, rather than needing to maintain a build-farm of down-level hosts. Presumably that'll rely on being able to parse an OSVersion out of the string, either in buildkit or internally to containerd.
Outside MatchComparers, purl's use of the same function has different purpose, highlighting the problem. Here, we need to specify the string form of a specific image rather than an execution platform, and cannot assume the host's details; so for this code to be correct, we need OSVersion
in the canonical string format, or any purl formed for for a Windows image index reference will only be able to round-trip back to a HostProcess image, breaking the current use-case of attestations/provenance on Windows. (That said, GitHub Search says the only caller of PurlToRef
is the BuildKit test suite, so incorrect parsing is probably a less-pressing issue than ambiguous stringification)
I assume from those current use-cases that a partial Platform value (filled in by host-provided-defaults) isn't desirable here.
Poking around at the purl docs (I haven't looked at them before AFAIK) it seems like platform
is not currently specified for the docker
type, but I assume we're treating it as "containerd's platforms.Parse
implementation-defined string serialisation". I see arch
is specified for the oci
type, but buildkit doesn't support parsing the oci
type, and the other Platform
fields are not present there.
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's a fair way down the track, but at some point we may also want, e.g., --platform windows/amd64//10.0.0.19242 to
Yes, I don't see any other way around it. I would just make it windows/amd64/10.0.0.19242
, windows/arm64/10.0.0.19242
, windows/arm64/v9/10.0.0.19242
as we know it is only used for windows. I'd also suggest that if platform is just windows/amd64
then the OSVersion
is not taken from host (even for matcher or build target platform) but there is a defined value that is normalized to empty string. Same as v8
for arm64
and v7
for arm
.
but I assume we're treating it as "containerd's platforms.Parse implementation-defined string serialisation
Yes, we don't define any other serialization in buildkit.
vendor: github.com/containerd/continuity v0.4.2
full diff: containerd/continuity@v0.4.1...v0.4.2
vendor: github.com/stretchr/testify v1.8.4
full diff: stretchr/testify@v1.8.3...v1.8.4
vendor: golang.org/x/sys v0.10.0
full diff: golang/sys@v0.8.0...v0.10.0
vendor: golang.org/x/crypto v0.11.0, golang.org/x/text v0.11.0
full diff: golang/crypto@v0.2.0...v0.11.0
full diff: golang/text@v0.9.0...v0.11.0
vendor: golang.org/x/net v0.13.0
full diff: golang/net@v0.10.0...v0.13.0
vendor: github.com/containerd/containerd v1.7.7
full diff: