#I was considering `ForcePlatform` but
1 messages · Page 1 of 1 (latest)
all of those sound more like something you'd set at the end of the pipeline, not sure if we'd want that to be the norm
i wonder if there are other examples that are just as confusing as this though, and we're just giving it more attention
if everything is confusing, nothing is!
Yeah there's more confusing examples for sure. Even in my example I realized afterwards that c.Container().From("alpine").WithPlatform("x86") is technically different from c.Container().WithPlatform("x86").From("alpine"). The first one means you initially do ResolveImageConfig using the default platform (the buildkitd host platform). 99% of the time that's fine, but there are cases where if an image is only published for one platform you may have to put WithPlatform before the From or else you will get a non-sensible failure. Unless of course we make that ResolveImageConfig call lazy, but that also is much easier said than done
what if we made platform an optional param to Container() and that's the only way it can be set?
That forces all extensions to always accept platform as an arg for all their APIs and explicitly+correctly handle them. For instance, Alpine Build would have to accept platform because it returns Container. And every user extension ever written that returns or otherwise uses container will have to accept platform as an arg and handle it correctly. Becomes a huge source of boilerplate and potential for bugs forever I think.
The solution of allowing WithPlatform later in the pipeline fixed that. But if we are going to force platform be an arg to Container, then we honestly may as well just go back to putting WithPlatform under Query, because that's pretty much the same thing but also fixes the extension problem in that extensions don't have to know about platform at all.
got it. if you ask me, I'm OK with the behavior as-is, it doesn't seem to be a huge problem and the trade-offs seem to make it worth it
i don't even know if the argument that 'lower layer should use platform A and upper layer should use platform B' with overriding makes sense. would that even build an image that's usable by anyone?
No there should never be an image where one layer is of one platform and another is a different one. I don't want to support that, I just am concerned that users are going to set themselves up for weird, hard-to-explain situations when you can retroactively change the platform for the whole DAG underlying a Container. It gets worse when you are not constructing the Container entirely yourself (i.e. it's returned from a function or an extension in the future).
It also gets harder to understand once you consider that containers can have mounts which themselves can be platform specific. Including both Directories, CacheDirectories and Files.
For that, it actually does make sense to support mounting states that have a different platform from the rootfs. But then if you retroactively change the platform in the future, what should we do to all those mounts from earlier in the DAG?
I actually think I have answers to those questions, I'm just not sure if it will be comprehensible yet
@livid swan I implemented a good chunk of the whole "retroactively change the platform" thing (which involves walking the marshalled LLB DAG and modifying the platform carefully vertex by vertex based on the type) and then realized it devolved even further.
Cross-compilation requires that you have a Directory/File previously associated with the host platform now forcibly marked by the user as of a different platform. The problem is that API implies not retroactively rewriting the platform of the DAG, only using that platform going forward. So now we need to have:
- An API that retroactively changes the platform of everything
- An API that changes the platform only going forward
That's awful by itself but then the implementation problems I mentioned above make it way worse. There's disgusting corner cases involving overlapping LLB DAGs where you actually need to split a single vertex into one for one platform and one for another. ðŸ˜
I'm just falling back to putting platform at the start of the Container+Directory for now, I thought about it and think we can probably layer WithDefaultPlatform under Query in the future: https://github.com/dagger/dagger/pull/3119#issuecomment-1295416978
Signed-off-by: Erik Sipsma erik@sipsma.dev
See docs/guides/avxpq-multiplatform-support.md for more details: https://github.com/sipsma/dagger/blob/platform-dagger/docs/guides/avxpq-multiplatform-sup...
(This is why I've been slow to review your code the last two days, sorry about that, I'm gonna go look at the host dir one again now)
yeesh sounds not fun,
for digging into this
i like that we're starting simple, at least, feels safer since we can see how people use it and adjust course. maybe e.g. this means extensions do something like container { alpine(pkgs: ["foo"]) } instead so the user can set the platform ahead of time?
(which opens a pandora's box around extending builtin types)
Yeah that's a possibility and also a can of worms.
I forgot to mention in my comment that alpine(platform: Platform!) { build(pkgs...) } is also a possibility (basically, extensions are automatically namespaced and hardcoded to accept platform, which at least avoids user boilerplate). Another can of worms