-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Handle file paths base on target platform #3908
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
Changes from all commits
686a84b
236d00b
7a503ae
b29ec0b
fbbaa39
0519491
edae0c6
d425c7c
45b4617
805b993
69f2c06
f1657ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
| continue | ||
| } | ||
| func(i int, d *dispatchState) { | ||
|
|
@@ -478,11 +479,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS | |
|
|
||
| // make sure that PATH is always set | ||
| if _, ok := shell.BuildEnvs(d.image.Config.Env)["PATH"]; !ok { | ||
| var pathOS string | ||
| if d.platform != nil { | ||
| pathOS = d.platform.OS | ||
| } | ||
| d.image.Config.Env = append(d.image.Config.Env, "PATH="+system.DefaultPathEnv(pathOS)) | ||
| d.image.Config.Env = append(d.image.Config.Env, "PATH="+system.DefaultPathEnv(d.platform.OS)) | ||
| } | ||
|
|
||
| // initialize base metadata from image conf | ||
|
|
@@ -891,6 +888,7 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE | |
| st := llb.Scratch().Dir(sourcePath).File( | ||
| llb.Mkfile(f, 0755, []byte(data)), | ||
| dockerui.WithInternalName("preparing inline document"), | ||
| llb.Platform(*d.platform), | ||
| ) | ||
|
|
||
| mount := llb.AddMount(destPath, st, llb.SourcePath(sourcePath), llb.Readonly) | ||
|
|
@@ -994,12 +992,20 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE | |
| } | ||
|
|
||
| func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand, commit bool, opt *dispatchOpt) error { | ||
| d.state = d.state.Dir(c.Path) | ||
| 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) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Follow-up: Naming is confusing here
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 err != nil { | ||
| return errors.Wrap(err, "normalizing workdir") | ||
| } | ||
|
|
||
| // NormalizeWorkdir returns paths with platform specific separators. For Windows | ||
| // this will be of the form: \some\path, which is needed later when we pass it to | ||
| // HCS. | ||
| d.image.Config.WorkingDir = wd | ||
|
|
||
| // From this point forward, we can use UNIX style paths. | ||
| wd = system.ToSlash(wd, d.platform.OS) | ||
| d.state = d.state.Dir(wd) | ||
|
|
||
| if commit { | ||
| withLayer := false | ||
| if wd != "/" { | ||
|
|
@@ -1018,6 +1024,7 @@ func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand, commit bo | |
| d.state = d.state.File(llb.Mkdir(wd, 0755, mkdirOpt...), | ||
| llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(opt.shlex, c.String(), env)), d.prefixPlatform, &platform, env)), | ||
| location(opt.sourceMap, c.Location()), | ||
| llb.Platform(*d.platform), | ||
| ) | ||
| withLayer = true | ||
| } | ||
|
|
@@ -1027,11 +1034,11 @@ func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand, commit bo | |
| } | ||
|
|
||
| func dispatchCopy(d *dispatchState, cfg copyConfig) error { | ||
| pp, err := pathRelativeToWorkingDir(d.state, cfg.params.DestPath) | ||
| dest, err := pathRelativeToWorkingDir(d.state, cfg.params.DestPath, *d.platform) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| dest := path.Join("/", pp) | ||
|
|
||
| if cfg.params.DestPath == "." || cfg.params.DestPath == "" || cfg.params.DestPath[len(cfg.params.DestPath)-1] == filepath.Separator { | ||
| dest += string(filepath.Separator) | ||
| } | ||
|
|
@@ -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) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can remove the calls to The current code in the Would you prefer we do away with this and just use It's fine with me, either way 😄
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you don't need
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can revert the change to that file and bring back Will change in the morning. I need to see if anything breaks (with a clear head).
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| if err != nil { | ||
| return errors.Wrap(err, "removing drive letter") | ||
| } | ||
|
|
||
| opts := append([]llb.CopyOption{&llb.CopyInfo{ | ||
| Mode: mode, | ||
| FollowSymlinks: true, | ||
|
|
@@ -1146,9 +1158,9 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error { | |
| }}, copyOpt...) | ||
|
|
||
| if a == nil { | ||
| a = llb.Copy(cfg.source, filepath.Join("/", src), dest, opts...) | ||
| a = llb.Copy(cfg.source, src, dest, opts...) | ||
| } else { | ||
| a = a.Copy(cfg.source, filepath.Join("/", src), dest, opts...) | ||
| a = a.Copy(cfg.source, src, dest, opts...) | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -1157,10 +1169,14 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error { | |
| commitMessage.WriteString(" <<" + src.Path) | ||
|
|
||
| data := src.Data | ||
| f := src.Path | ||
| f, err := system.CheckSystemDriveAndRemoveDriveLetter(src.Path, d.platform.OS) | ||
| if err != nil { | ||
| return errors.Wrap(err, "removing drive letter") | ||
| } | ||
| st := llb.Scratch().File( | ||
| llb.Mkfile(f, 0664, []byte(data)), | ||
| dockerui.WithInternalName("preparing inline document"), | ||
| llb.Platform(*d.platform), | ||
| ) | ||
|
|
||
| opts := append([]llb.CopyOption{&llb.CopyInfo{ | ||
|
|
@@ -1169,9 +1185,9 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error { | |
| }}, copyOpt...) | ||
|
|
||
| if a == nil { | ||
| a = llb.Copy(st, f, dest, opts...) | ||
| a = llb.Copy(st, system.ToSlash(f, d.platform.OS), dest, opts...) | ||
| } else { | ||
| a = a.Copy(st, f, dest, opts...) | ||
| a = a.Copy(st, filepath.ToSlash(f), dest, opts...) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -1202,7 +1218,9 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error { | |
| d.cmdIndex-- // prefixCommand increases it | ||
| pgName := prefixCommand(d, name, d.prefixPlatform, &platform, env) | ||
|
|
||
| var copyOpts []llb.ConstraintsOpt | ||
| copyOpts := []llb.ConstraintsOpt{ | ||
| llb.Platform(*d.platform), | ||
| } | ||
| copy(copyOpts, fileOpt) | ||
| copyOpts = append(copyOpts, llb.ProgressGroup(pgID, pgName, true)) | ||
|
|
||
|
|
@@ -1394,15 +1412,24 @@ func dispatchArg(d *dispatchState, c *instructions.ArgCommand, metaArgs []instru | |
| return commitToHistory(&d.image, "ARG "+strings.Join(commitStrs, " "), false, nil, d.epoch) | ||
| } | ||
|
|
||
| func pathRelativeToWorkingDir(s llb.State, p string) (string, error) { | ||
| if path.IsAbs(p) { | ||
| return p, nil | ||
| } | ||
| dir, err := s.GetDir(context.TODO()) | ||
| 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 | ||
| } | ||
| return path.Join(dir, p), nil | ||
|
|
||
| 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) | ||
| } | ||
|
|
||
| func addEnv(env []string, k, v string) []string { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
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
DefaultSpecThere 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
DefaultSpecif it's not set viaConvertOptand targetPlatform is set to&buildPlatforms[0]if it'snil, 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 theplatformOpttype.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.