-
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
Handle file paths base on target platform #3908
Handle file paths base on target platform #3908
Conversation
83cada2
to
ac3d451
Compare
Rebased, now that the dependencies have been merged. This should now be ready for review. |
frontend/gateway/container.go
Outdated
@@ -261,7 +262,7 @@ func PrepareMounts(ctx context.Context, mm *mounts.MountManager, cm cache.Manage | |||
} else { | |||
mws := mountWithSession(mountable, g) | |||
dest := m.Dest | |||
if !filepath.IsAbs(filepath.Clean(dest)) { | |||
if !system.IsAbs(filepath.Clean(dest), platform) { |
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 path is coming from LLB. How is it not already normalized?
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 function is also called from NewContainer()
. I can't remember for sure why I needed this here (first PR was proposed in November), but I can track it down and give you a more detailed answer.
On the other hand, I think that whenever we are dealing with paths that may be meant for a different OS than the one the code is running on, we should use the helper functions in util/system
.
ba7f3b9
to
5a4f37f
Compare
@tonistiigi kind reminder. I would love to unblock the rest of the PRs. The executor work depends on this PR. |
client/llb/state.go
Outdated
if c.Platform == nil { | ||
c.Platform = &ocispecs.Platform{ | ||
OS: "linux", | ||
Architecture: "amd64", |
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.
Is the architecture in here used anywhere? If not then I would prefer if the nil case is handled inside FileOp
for OS
only and it is clear that this only controls the path conversions.
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.
Removed the Architecture
.
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.
What I meant was to handle nil platform inside FileOp. If the logic is only based on OS then we shouldn't control it by passing full platform (or passing an invalid partial platform).
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.
Gotcha. Misread what you meant.
@@ -360,6 +360,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS | |||
if d.stage.BaseName == emptyImageName { | |||
d.state = llb.Scratch() | |||
d.image = emptyImage(platformOpt.targetPlatform) | |||
d.platform = &platformOpt.targetPlatform |
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 this can be nil pointer dereference. In that nil case we should use 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.
If I am reading the code correctly, the buildPlatforms field defaults to DefaultSpec
if it's not set via ConvertOpt
and targetPlatform is set to &buildPlatforms[0]
if it's nil
, before returning.
platformOpt seems to be set at the beginning of this function using buildPlatformOpt()
which always seems to return a non-nil instance of the platformOpt
type.
Would you prefer I add a nil pointer check here, in case buildPlatformOpt()
changes at some point?
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.
Ah, I read it wrong. This is not even a pointer, so it can't be nil.
@@ -1135,6 +1142,11 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error { | |||
a = a.Copy(st, f, dest, opts...) | |||
} | |||
} else { | |||
src, err = system.NormalizePath("/", src, d.platform.OS, false) |
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'm still confused why are doing these path transformations twice. If we already are always converting paths to UNIX in Dockerfile before passing to the LLB then why are we still carrying OS value in LLB and doing extra conversions 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.
I can remove the calls to NormalizePath()
from client/llb
and just use the paths as they come in, if you wish.
The current code in the master
branch calls normalizePath(). This code is now incorporated into system.NormalizePath()
, with additional logic to take into account the input platform
.
Would you prefer we do away with this and just use path.Join()
in toProtoAction()
(example: https://github.com/moby/buildkit/blob/master/client/llb/fileop.go#L340) ?
It's fine with me, either way 😄
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.
Alternatively, in the client I can just hardcode "linux" as the platform sent into NormalizePath()
and it would behave just like the current normalizePath()
in client/llb
, but I am not sure ignoring the input platform (if set) is worth it. In any case, let me know what you prefer and I will make the change.
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 you don't need NormalizePath
calls inside client/llb
to make windows work then better to remove it.
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 can revert the change to that file and bring back normalizePath()
as it is in the master
branch, because that is somewhat still needed. Although that code is now incorporated in system.NormalizePath()
.
Will change in the morning. I need to see if anything breaks (with a clear head).
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 reverted most of the changes to the client. Please take another look.
5d2cdce
to
b7985be
Compare
This change properly handles paths on different platforms. In short, this change checks the target platform we're building an image for and applies normalization steps to make sure the file paths are valid. This makes buildkit properly handle paths on both *nix systems and on Windows. Signed-off-by: Gabriel Adrian Samfira <[email protected]>
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
* Set default platform for scratch images * Set default platform constraint for FileOps if none is set via ConstraintOpt. * Explicitly set platform ConstraintOpt in dockerfile frontend based on dispatch state platform. Signed-off-by: Gabriel Adrian Samfira <[email protected]>
In dockerfile2llb we ensure we use proper path separators before we send them to LLB. In LLB we default to linux/amd64 if no constraints are set by the caller. Signed-off-by: Gabriel Adrian Samfira <[email protected]>
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
7022827
to
1045713
Compare
When running on Linux, filepath.ToSlash() is not suitable to convert paths containing Windows path delimiter to Unix delimiters. To enable this, we export system.ToSlash() that takes a platform flag, based on which we use the proper file path separator, regardless of the platform we run on. Signed-off-by: Gabriel Adrian Samfira <[email protected]>
1045713
to
69f2c06
Compare
wd := c.Path | ||
if !path.IsAbs(c.Path) { | ||
wd = path.Join("/", d.image.Config.WorkingDir, wd) | ||
wd, err := system.NormalizeWorkdir(d.image.Config.WorkingDir, c.Path, d.platform.OS) |
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.
Follow-up: Naming is confusing here NormalizeWorkdir
returns OS-specific paths and NormalizePath
Unix-only paths. "Normalize" should mean the same thing.
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 am terrible at naming things, and can't really think of a better name right now. I did make sure that the doc string for the function does state explicitly that for Windows, we convert path delimiter with \
. If it's alright with you, I'd like to revisit the name at a later time. Or if you have any suggestions for a better name, I'll gladly change it.
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
b829c52
to
f1657ec
Compare
This change properly handles paths on different platforms. In short, this change checks the target platform we're building an image for and applies normalization steps to make sure the file paths are valid. This makes buildkit properly handle paths on both *nix systems and on Windows.
Depends on:
Replaces:
Note: This branch will fail to build until dependencies are merged. Leaving the old branch up, as it contains a longer discussion related to the changes in these 3 PRs.
Here is a test run with all 3 branches merged: https://github.com/gabriel-samfira/buildkit/actions/runs/5091195907
CC: @crazy-max @jedevc