-
Notifications
You must be signed in to change notification settings - Fork 12
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
Add format for platform string #6
Conversation
Adding everyone who were part of discussion in containerd PR here : @dmcgowan @cpuguy83 @aravindhp @jsturtevant @TBBle @tonistiigi @thaJeztah |
81db5ed
to
e39f85d
Compare
Not as an opinion, but just to share prior art: https://github.com/google/go-containerregistry/blob/8dadbe76ff8c20d0e509406f04b7eade43baa6c1/pkg/v1/platform.go#L54-L75 ( |
8721eff
to
a11cef4
Compare
@tianon I almost like it but it seems to actually be |
Thanks @kiashok for opening this here! |
@dmcgowan does this current change for os(osversion) look good to you or do you want me to change to os:osversion ? |
I still think its safer to include |
f585855
to
508d5d9
Compare
There's only one known value for
Similarly, we might get rid of os.features itself in the future, either just dropping it, or if it gets subsumed into whatever the OCI Image Compat WG comes up with as their generalised approach. OCI Image Compat WG appears to be discussing hierarchical trees of features (in a separate artifact) and are not yet (AFAIK) looking at how that would interact with Image Indexes or the Platform Object: the topic has been raised a couple of times, so it's not forgotten, just at the far end of the process for now. (Note, I seem to have misplaced my Slack link, so my OCI Image Compat WG notes here are based on perusing the docs and skimming the meeting transcripts. If anyone is better-connected at the moment, feel free to correct me.) |
I agree. I am not sure we need to include osFeature as it is not being used today and I have heard conversations of wanting to remove that field from ocispec as well. |
Hmm I think the format is mostly defined in code and the rest of the fields are not prepended with "os", "arch" or "variant". So no not having "version" would make it uniform and consistent with the rest of the grammar for platform string. |
Off the top of my head, for Windows, the host OS should always have an So for the current situation of only Also, only a mild concern for this PR, but what about cases where absence and empty-string need to be distinguished? The discussion on the earlier PR mooted such a case when parsing these strings, in that we need to inform the caller of This case is hard because Go's Platform object doesn't have a way to directly make that distinction, and also tells the JSON codec not to make that distinction, but the spec allows it. So I don't have a better solution in-mind right now than either creating a special token string which is used for either the |
if for example you do a ctr image pull and --platform is windows or windows() it means that osversion is not given and windows image pull will fail at platform matcher as no host OSVersion can be "" . We should not support a behavior of empty host OS version to mean that they wanted a host process container compatible image. For windows, this should be an error. If HPC compatible image was needed, an appropriate image for that same much be constructed with OSVersion "" . For the OSFeature, I am not sure we need to cover all its cases as we do not know what it could entail as its type is []string and it is not being used and has plans to be removed. If it starts being used, we can revisit then IMO. If in the future it does become needed, I think it might be more helpful to have a separate field for it rather than trying to fit it into OS(OSVersion)? |
So I understand, are you suggesting that in this case, I'm not sure that an empty osversion in |
@TBBle an example of a base image for HPC is as follows: they do not have an OSVersion. Windows platform matchers need the host where image is being pulled for example or whatever string is mentioned for --platform to have the osversion. If one is not present, it will fail pulling layers. A simple test of pulling nanoserver 2022 with transfer service (ctr image pull by default used transfer service) and inspecting the content and image store will show that layer is not pulled as windows platform matcher fails. |
My point was that (as far as I recall; I don't have a HPC execution setup at-hand right now) I can also run the nanoserver LTSC 2022 image or images derived from it as a Host Process Container. So for a few-hundred megabytes, I don't need to build separate images for privileged and non-privileged execution. So in my mind, So in this case, the host is The feedback at containerd/containerd#9609 is not that "this pull should not work", the feedback is that "this pull should not be made to work by fudging in the host os.version when parsing a platform string or receiving Platform objects from callers". Only the caller of Basically, Host Process Containers need a different Platform Matcher behaviour, like Hyper-V Isolated containers do. "Exact match" is only correct for Process Isolated containers. We should not be trying to massage the input inside the Platform Matcher so that an "Exact Match" check will choose the right image; Platform Matchers are customisation points, the data should reflect truth. (Sadly, the Platform Matcher API doesn't provide a way to control the rules used, and AFAIK there's still some outstanding bugs or design issues when using a non-default Platform Matcher... and gosh, adding test coverage and fixing that has been on my TODO list for much longer than I realised. >_<) For The challenge which I raised at the start of this discussion is that this user-intent is not visible in We've seen the exact same issue in CRI, that the "ImagePull" operation hits a snag when the correct image to pull varies based on what's going to be done with it later. In |
Yes you can run definitely run the nanoserver as base but the only need for HPC is that the container image OSVersion can be "". There is no requirement that host OSVersion should or can be "" too. That is what I was meaning to put across. Since the other containerd PR suggested that we do not auto populate OSVersion's if it came in as empty and if we want to assume that host OSVersion being empty/"" and means that we assume they are asking for HPC image is behavior change that needs to be made in the windows platform matcher and not in containerd/platforms.
I am not familiar with nerdctl behavior and would have to review that before I have a thought on that behavior vs containerd windows platform matcher.
I don't think I meant that the PR said that :) I was referring to the fact that the feedback on that PR suggested that we do not auto populate OSVersion in platforms package if it was passed in as "" and instead it is a behavior that the windows platform matcher should take responsibility for.
Inside a UVM for hyperv cases too it is just like a process isolated container - exact match of the UVM image and container image is still needed. I just don't think that the parser functions in containerd/platform is the right place to address all of this. The functions in containerd/platform repo should barely only parse what is given and set the ocispec.Platform fields or convert them to a string representation as needed. |
That makes sense; reading back, I think we might have been agreeing at cross-purposes. I was assuming that if I was executing in Host Process mode, the Host's Platform object would have empty OSVersion, but hadn't really questioned that assumption. A HPC-specific Platform Matcher would never look at the host's OSVersion (it's irrelevant) so carrying the host's OSVersion isn't a problem, i.e. the There was some discussion that when BuildKit is told to build for |
@dmcgowan @mikebrow @TBBle @cpuguy83 could you please take a look when you have some time please? This change would be needed for image pull per runtime class : containerd/containerd#9832. Thanks! |
@@ -18,7 +18,7 @@ package platforms | |||
|
|||
// DefaultString returns the default string specifier for the platform. | |||
func DefaultString() string { | |||
return Format(DefaultSpec()) | |||
return FormatAll(DefaultSpec()) |
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 changing defaults here.
/cc @tonistiigi @tianon
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 seems expected to me, but highlights a possible issue.
A quick survey of the containerd code calling this function suggests that by-and-large it's used to hold a string that is given back to Parse
later; so in the same process it's fine, and in fact due to the removal of auto-insertion of Windows host OS version in Parse, this one needs to be FormatAll
or we're changing the observed behaviour of Parse(DefaultString())
on Windows.
The Windows v2 Runtime manager's supported platforms list might need to be hard-coded though. It already hard-codes linux/amd64
(that should probably be linux/$(GOARCH)
...?).
Some cases however are in the client library, and perhaps the string is being processed in containerd on the other side of the (stable API!) remote connection. If that's the case then depending on the direction of mismatch, we're either generating strings old containerd can't parse, or generating strings which new containerd will parse into a platform object unexpectedly absent OS version.
I haven't checked to confirm that the stable API actually contains these platform-as-strings, the ones I was able to trace through GitHub's WebUI seemed to still be Parse
d in the client library code, so maybe this problematic case doesn't exist here.
Direct consumers of this library will be affected by the defaults change, but AFAIK this library is not 1.0-versioned?
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.
Discussion in a Moby maintainers call, and there were still some concerns if this could break things 🤔 (we should probably check in what cases)
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.
@dmcgowan should we cut "1.x" tag from this repo or change DefaultString() to use Format() and have a new function that uses FormatAll() ?
3d5f21c
to
98ee22b
Compare
220143f
to
caa7d77
Compare
@thaJeztah review comments addressed. Could you please take a look and sign off if changes look ok? Thanks! |
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 noticed there were some stray calls to normalizeOSAndVersion
that are no longer needed (but would result in parsing multiple times)
One other comment about the redundant parsing in normalizeOSAndVersion
itself (which could save for another regex being executed altogether), but that's less critical.
caa7d77
to
0a0c0a5
Compare
Responded to the same review comment here: |
0a0c0a5
to
fa93967
Compare
@dmcgowan can we merge these changes? |
@tianon @thaJeztah Any concern that we should address before merging this PR? |
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.
LGTM per windows / docker team acceptance of the new default format
Platform string to be of the form <os>[(<osversion>)]|<arch>|<os>[(<OSVersion>)]/<arch>[/<variant>] OSVersion is optional only and currently used only by Windows OS. Signed-off-by: Kirtana Ashok <kiashok@microsoft.com>
fa93967
to
38a74d2
Compare
I think the addition to the format is fine and makes sense; I'm still very worried about how it's going to fit into the overall API / flows of containerd itself (and whether we're wrong about the number of applications passing these strings across a process or even system boundary, as in moby/moby#47679 for example). Without more changes, this will be mostly ignored by even If maintainers feel strongly that it's fine, I don't feel so strongly to try to block it, but I'm definitely worried that fixing/implementing this functionality properly is going to require looking at a much bigger swath of code and UX points than just this platforms module and CRI. |
We need to vendor in this pkg to containerd for supporting image pull per runtime class (kep 4216) which is being requested from Kata and the windows side as well. After vendor, If ctr specifies a platform with the OS version it will be taken into account. If the caller does not specify the OS version, nothing should change. Also, there a Format() and FormatAll() API that folks can use to pick old vs new behavior while converting ocispec.Platform to a string format. |
@tianon I agree with your concern, we should keep this string from creeping into cross system/process APIs. Its fine for it be used in UX cases (CLI or config files) but the full proto/json value should be used in APIs and storage. I think we can move forward on this PR though since it is just defining the string. More discussion is still needed on the Moby and containerd side where this string might be (mis)used. |
Sorry for being late (again); my last comment was a quick one as I was in the middle of a maintainers call where we were discussing these changes; I asked others to also post their input, but I forgot to post a summary. Let me post a brief one of what I recall came up;
That last bullet should probably be looked at more widely; from a quick look during that call, we found various existing code in this module / repository that (sometimes implicitly) sets defaults based on the current environment. We should make sure that those functions clearly document how they should be used, but perhaps also look at more explicit options to pass things (OS-version most notably), possibly deprecating "convenience" functions that do so automatically. In either case; those can be looked at in follow-ups; this change on its own LGTM (sorry for the delay). |
Platform string to be of the form
<os>[(<osversion>)]|<arch>|<os>[(<OSVersion>)]/<arch>[/<variant>]
See discussion in this PR: containerd/containerd#9609
PLEASE NOTE: The intent of this PR is NOT to solve the pull problems that exist for hyperV/process isolated containers OR to solve any platform matcher issue. This is plainly to fix the bug reported earlier to stop auto populating the host OS version in the formatting functions by using the grammar mentioned above (it gives the user a chance to specify the OSVersion if they want to. If one if not specified, this change will not autofill the host OS Version and will instead leave it empty. If the platform matchers do not like this, it is for them to handle it and not the platforms.Parse() or platforms.Format() functions).