@@ -360,6 +360,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
360360 if d .stage .BaseName == emptyImageName {
361361 d .state = llb .Scratch ()
362362 d .image = emptyImage (platformOpt .targetPlatform )
363+ d .platform = & platformOpt .targetPlatform
363364 continue
364365 }
365366 func (i int , d * dispatchState ) {
@@ -486,11 +487,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
486487
487488 // make sure that PATH is always set
488489 if _ , ok := shell .BuildEnvs (d .image .Config .Env )["PATH" ]; ! ok {
489- var pathOS string
490- if d .platform != nil {
491- pathOS = d .platform .OS
492- }
493- d .image .Config .Env = append (d .image .Config .Env , "PATH=" + system .DefaultPathEnv (pathOS ))
490+ d .image .Config .Env = append (d .image .Config .Env , "PATH=" + system .DefaultPathEnv (d .platform .OS ))
494491 }
495492
496493 // initialize base metadata from image conf
@@ -899,6 +896,7 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE
899896 st := llb .Scratch ().Dir (sourcePath ).File (
900897 llb .Mkfile (f , 0755 , []byte (data )),
901898 dockerui .WithInternalName ("preparing inline document" ),
899+ llb .Platform (* d .platform ),
902900 )
903901
904902 mount := llb .AddMount (destPath , st , llb .SourcePath (sourcePath ), llb .Readonly )
@@ -1002,12 +1000,20 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE
10021000}
10031001
10041002func dispatchWorkdir (d * dispatchState , c * instructions.WorkdirCommand , commit bool , opt * dispatchOpt ) error {
1005- d .state = d .state .Dir (c .Path )
1006- wd := c .Path
1007- if ! path .IsAbs (c .Path ) {
1008- wd = path .Join ("/" , d .image .Config .WorkingDir , wd )
1003+ wd , err := system .NormalizeWorkdir (d .image .Config .WorkingDir , c .Path , d .platform .OS )
1004+ if err != nil {
1005+ return errors .Wrap (err , "normalizing workdir" )
10091006 }
1007+
1008+ // NormalizeWorkdir returns paths with platform specific separators. For Windows
1009+ // this will be of the form: \some\path, which is needed later when we pass it to
1010+ // HCS.
10101011 d .image .Config .WorkingDir = wd
1012+
1013+ // From this point forward, we can use UNIX style paths.
1014+ wd = system .ToSlash (wd , d .platform .OS )
1015+ d .state = d .state .Dir (wd )
1016+
10111017 if commit {
10121018 withLayer := false
10131019 if wd != "/" {
@@ -1026,6 +1032,7 @@ func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand, commit bo
10261032 d .state = d .state .File (llb .Mkdir (wd , 0755 , mkdirOpt ... ),
10271033 llb .WithCustomName (prefixCommand (d , uppercaseCmd (processCmdEnv (opt .shlex , c .String (), env )), d .prefixPlatform , & platform , env )),
10281034 location (opt .sourceMap , c .Location ()),
1035+ llb .Platform (* d .platform ),
10291036 )
10301037 withLayer = true
10311038 }
@@ -1035,11 +1042,11 @@ func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand, commit bo
10351042}
10361043
10371044func dispatchCopy (d * dispatchState , cfg copyConfig ) error {
1038- pp , err := pathRelativeToWorkingDir (d .state , cfg .params .DestPath )
1045+ dest , err := pathRelativeToWorkingDir (d .state , cfg .params .DestPath , * d . platform )
10391046 if err != nil {
10401047 return err
10411048 }
1042- dest := path . Join ( "/" , pp )
1049+
10431050 if cfg .params .DestPath == "." || cfg .params .DestPath == "" || cfg .params .DestPath [len (cfg .params .DestPath )- 1 ] == filepath .Separator {
10441051 dest += string (filepath .Separator )
10451052 }
@@ -1137,6 +1144,11 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
11371144 a = a .Copy (st , f , dest , opts ... )
11381145 }
11391146 } else {
1147+ src , err = system .NormalizePath ("/" , src , d .platform .OS , false )
1148+ if err != nil {
1149+ return errors .Wrap (err , "removing drive letter" )
1150+ }
1151+
11401152 opts := append ([]llb.CopyOption {& llb.CopyInfo {
11411153 Mode : mode ,
11421154 FollowSymlinks : true ,
@@ -1148,9 +1160,9 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
11481160 }}, copyOpt ... )
11491161
11501162 if a == nil {
1151- a = llb .Copy (cfg .source , filepath . Join ( "/" , src ) , dest , opts ... )
1163+ a = llb .Copy (cfg .source , src , dest , opts ... )
11521164 } else {
1153- a = a .Copy (cfg .source , filepath . Join ( "/" , src ) , dest , opts ... )
1165+ a = a .Copy (cfg .source , src , dest , opts ... )
11541166 }
11551167 }
11561168 }
@@ -1159,10 +1171,14 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
11591171 commitMessage .WriteString (" <<" + src .Path )
11601172
11611173 data := src .Data
1162- f := src .Path
1174+ f , err := system .CheckSystemDriveAndRemoveDriveLetter (src .Path , d .platform .OS )
1175+ if err != nil {
1176+ return errors .Wrap (err , "removing drive letter" )
1177+ }
11631178 st := llb .Scratch ().File (
11641179 llb .Mkfile (f , 0644 , []byte (data )),
11651180 dockerui .WithInternalName ("preparing inline document" ),
1181+ llb .Platform (* d .platform ),
11661182 )
11671183
11681184 opts := append ([]llb.CopyOption {& llb.CopyInfo {
@@ -1171,9 +1187,9 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
11711187 }}, copyOpt ... )
11721188
11731189 if a == nil {
1174- a = llb .Copy (st , f , dest , opts ... )
1190+ a = llb .Copy (st , system . ToSlash ( f , d . platform . OS ) , dest , opts ... )
11751191 } else {
1176- a = a .Copy (st , f , dest , opts ... )
1192+ a = a .Copy (st , filepath . ToSlash ( f ) , dest , opts ... )
11771193 }
11781194 }
11791195
@@ -1204,7 +1220,9 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
12041220 d .cmdIndex -- // prefixCommand increases it
12051221 pgName := prefixCommand (d , name , d .prefixPlatform , & platform , env )
12061222
1207- var copyOpts []llb.ConstraintsOpt
1223+ copyOpts := []llb.ConstraintsOpt {
1224+ llb .Platform (* d .platform ),
1225+ }
12081226 copy (copyOpts , fileOpt )
12091227 copyOpts = append (copyOpts , llb .ProgressGroup (pgID , pgName , true ))
12101228
@@ -1397,15 +1415,24 @@ func dispatchArg(d *dispatchState, c *instructions.ArgCommand, metaArgs []instru
13971415 return commitToHistory (& d .image , "ARG " + strings .Join (commitStrs , " " ), false , nil , d .epoch )
13981416}
13991417
1400- func pathRelativeToWorkingDir (s llb.State , p string ) (string , error ) {
1401- if path .IsAbs (p ) {
1402- return p , nil
1403- }
1404- dir , err := s .GetDir (context .TODO ())
1418+ func pathRelativeToWorkingDir (s llb.State , p string , platform ocispecs.Platform ) (string , error ) {
1419+ dir , err := s .GetDir (context .TODO (), llb .Platform (platform ))
14051420 if err != nil {
14061421 return "" , err
14071422 }
1408- return path .Join (dir , p ), nil
1423+
1424+ if len (p ) == 0 {
1425+ return dir , nil
1426+ }
1427+ p , err = system .CheckSystemDriveAndRemoveDriveLetter (p , platform .OS )
1428+ if err != nil {
1429+ return "" , errors .Wrap (err , "removing drive letter" )
1430+ }
1431+
1432+ if system .IsAbs (p , platform .OS ) {
1433+ return system .NormalizePath ("/" , p , platform .OS , false )
1434+ }
1435+ return system .NormalizePath (dir , p , platform .OS , false )
14091436}
14101437
14111438func addEnv (env []string , k , v string ) []string {
0 commit comments