-
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
fix: use unix path separator since windows path already normalized #4825
fix: use unix path separator since windows path already normalized #4825
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.
I think the intent could have been that the llb.File
functions already expect the paths to be in unix-style. Is there some calls that don't do that? Eg. look at system.NormalizePath
.
From your previous comments here with Gabriel #3908, looks like that was the intention; and it was to be a stripped-down version of Also, I'm trying to understand how this edge-case isn't covered. This is only happening for the root directory, something like
Is there anywhere up the stack that the cleaning is supposed to happen? Will appreciate some pointers. |
@tonistiigi -- Found it, the path was being normalized but this one line was breaking it by adding a Windows suffix. So, you were right, the expectation is that once we get at
|
520d30f
to
54261cb
Compare
54261cb
to
02c144e
Compare
It's not related to this code, but it's nearby: Is line 1126 faulty, should |
@TBBle -- no, WORKDIR is now handled correctly. With the following lines:
buildkit/frontend/dockerfile/dockerfile2llb/convert.go Lines 1104 to 1105 in fb97e6d
and
Testing with both: WORKDIR C:\\
# and
WORKDIR C:\\test both resolve correctly to Thanks for checking it out for verification! |
@@ -1139,7 +1139,10 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error { | |||
} | |||
|
|||
if cfg.params.DestPath == "." || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { |
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.
Would it be bit more correct if this condition also checked:
lastChar := cfg.params.DestPath[len(cfg.params.DestPath)-1]
isWindows :=
if cfg.params.DestPath == "." || cfg.params.DestPath == "" || lastChar == "/" || (lastChar == "\" && isWindows) {
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.
BTW, given what pathRelativeToWorkingDir
is doing at L1136
(normalizing the path cfg.params.DestPath
already) , do we actually need this block now or we just continue with dest
from here onwards?
buildkit/frontend/dockerfile/dockerfile2llb/convert.go
Lines 1550 to 1568 in fb97e6d
func pathRelativeToWorkingDir(s llb.State, p string, platform ocispecs.Platform) (string, error) { | |
dir, err := s.GetDir(context.TODO(), llb.Platform(platform)) | |
if err != nil { | |
return "", err | |
} | |
if len(p) == 0 { | |
return dir, nil | |
} | |
p, err = system.CheckSystemDriveAndRemoveDriveLetter(p, platform.OS) | |
if err != nil { | |
return "", errors.Wrap(err, "removing drive letter") | |
} | |
if system.IsAbs(p, platform.OS) { | |
return system.NormalizePath("/", p, platform.OS, false) | |
} | |
return system.NormalizePath(dir, p, 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.
Afaics, pathRelativeToWorkingDir
calls system.NormalizePath()
and NormalizePath()
takes keepSlash bool
, but pathRelativeToWorkingDir
is setting it to false
. If we would set it to true
instead then it looks like we don't need this extra block.
cc @gabriel-samfira to double-check the intention of keepSlash=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.
Perhaps this was for some old code, since? there's no where system.NormalizePath()
is called with keepSlash=true
, as far as I can see. At some point, may be we should do away with that param?
$ grep -rn "\.NormalizePath("
frontend/dockerfile/dockerfile2llb/convert.go:1279: pattern, err = system.NormalizePath("/", pattern, d.platform.OS, false)
frontend/dockerfile/dockerfile2llb/convert.go:1287: src, err = system.NormalizePath("/", src, d.platform.OS, false)
frontend/dockerfile/dockerfile2llb/convert.go:1565: return system.NormalizePath("/", p, platform.OS, false)
frontend/dockerfile/dockerfile2llb/convert.go:1567: return system.NormalizePath(dir, p, 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 think I would rather keep keepSlash
or add a new helper function for this functionality (if there is only one caller then it can remain private). The current long if statement is not very robust, can't be tested and is easy to break.
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 keepSlash
logic was carried forward from the function that NormalizePath()
replaced.
Looking over the rest of the PR now.
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 think it's safe to switch NormalizePath
to true
in pathRelativeToWorkingDir
. That function is only used once, in convert.go
. And we seem to be duplicating some of its logic in that if statement that follows right after we call pathRelativeToWorkingDir()
. Let's just remove that if block and flip that boolean in pathRelativeToWorkingDir
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.
Thank @gabriel-samfira for the review. I've made the change, PTAL.
Okay, so |
@TBBle -- oh, my bad, that's right. |
In the case for Windows, this line at frontend/dockerfile/dockerfile2llb/convert.go#L1142 ```go dest += string(filepath.Separator) ``` was adding the `\\` to a path that is already normalized to unix-format, hence ending up with dest paths like `/\\` for `C:\\` and `/test\\` for `C:\\test\\`. the src paths are well normalized too at ~L1290. This change removes the block of code and instead does the "/" appending using the keepSlash logic that is in system.NormalizePath called in pathRelativeToWorkingDir() function before. fixes moby#4696 Signed-off-by: Anthony Nandaa <[email protected]>
02c144e
to
018155f
Compare
Let me make this fix as a separate PR @TBBle |
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` scenario. `""`, `"/"` are all handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation. Signed-off-by: Anthony Nandaa <[email protected]>
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` scenario. `""`, `"/"` are all handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation. fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` scenario. `""`, `"/"` are all handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation. fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` scenario. `""`, `"/"` are all handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation. fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` and `""` scenarios. `""`. The `"/"`case is handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation. fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` and `""` scenarios. `""`. The `"/"`case is handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation, same to "" -> "/". fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` and `""` scenarios. `""`. The `"/"`case is handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation, same to "" -> "/". fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` and `""` scenarios. `""`. The `"/"`case is handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation, same to "" -> "./". This is important especially for WORKDIR that are not `/`, so that `COPY --link` operations are handled properly. fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` and `""` scenarios. `""`. The `"/"`case is handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation, same to "" -> "./". This is important especially for WORKDIR that are not `/`, so that `COPY --link` operations are handled properly. fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
In my previous fix on moby#4825, I had removed this line knowing that all that had been addressed in `pahtRelativeToWorkingDir`: ```go if cfg.params.DestPath == "." // <-- this one || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { dest += string(filepath.Separator) } ``` However, I had overlooked the `"."` and `""` scenarios. `""`. The `"/"`case is handled correctly in `system.NormalizePath()`. This change therefore undoes this, to make sure "." is transformed correctly to "./" during COPY operation, same to "" -> "./". This is important especially for WORKDIR that are not `/`, so that `COPY --link` operations are handled properly. fixes moby#5070 Signed-off-by: Anthony Nandaa <[email protected]>
In the case for Windows, this line at
frontend/dockerfile/dockerfile2llb/convert.go#L1142
was adding the\\
to a path that is already normalized to unix-format, hence ending up withdest
paths like:/\\
forC:\\
and/test\\
forC:\\test\\
.buildkit/frontend/dockerfile/dockerfile2llb/convert.go
Line 1142 in fb97e6d
The
src
paths are well normalized too at ~L1290:buildkit/frontend/dockerfile/dockerfile2llb/convert.go
Line 1287 in fb97e6d
This change removes the block of code and instead does the "/" appending using the
keepSlash
logicthat is in
system.NormalizePath
called inpathRelativeToWorkingDir
function before.Additionally in
solver/llbsolver/file/backend.go
, the error message is enhanced to specify "destination" path, since "source" path is also specified in it's error message. This was the "cleaning path" wrapped error reported in issue #4696 :fixes #4696