@@ -12,6 +12,7 @@ import (
12
12
"path/filepath"
13
13
"regexp"
14
14
"runtime"
15
+ "strconv"
15
16
"strings"
16
17
17
18
"github.com/go-git/go-billy/v5/helper/polyfill"
@@ -125,6 +126,13 @@ func (cr *containerReference) Start(attach bool) common.Executor {
125
126
cr .attach ().IfBool (attach ),
126
127
cr .start (),
127
128
cr .wait ().IfBool (attach ),
129
+ cr .tryReadUID (),
130
+ cr .tryReadGID (),
131
+ func (ctx context.Context ) error {
132
+ // If this fails, then folders have wrong permissions on non root container
133
+ _ = cr .Exec ([]string {"chown" , "-R" , fmt .Sprintf ("%d:%d" , cr .UID , cr .GID ), cr .input .WorkingDir }, nil , "0" , "" )(ctx )
134
+ return nil
135
+ },
128
136
).IfNot (common .Dryrun ),
129
137
)
130
138
}
@@ -154,8 +162,12 @@ func (cr *containerReference) Copy(destPath string, files ...*FileEntry) common.
154
162
func (cr * containerReference ) CopyDir (destPath string , srcPath string , useGitIgnore bool ) common.Executor {
155
163
return common .NewPipelineExecutor (
156
164
common .NewInfoExecutor ("%sdocker cp src=%s dst=%s" , logPrefix , srcPath , destPath ),
157
- cr .Exec ([]string {"mkdir" , "-p" , destPath }, nil , "" , "" ),
158
165
cr .copyDir (destPath , srcPath , useGitIgnore ),
166
+ func (ctx context.Context ) error {
167
+ // If this fails, then folders have wrong permissions on non root container
168
+ _ = cr .Exec ([]string {"chown" , "-R" , fmt .Sprintf ("%d:%d" , cr .UID , cr .GID ), destPath }, nil , "0" , "" )(ctx )
169
+ return nil
170
+ },
159
171
).IfNot (common .Dryrun )
160
172
}
161
173
@@ -211,6 +223,8 @@ type containerReference struct {
211
223
cli client.APIClient
212
224
id string
213
225
input * NewContainerInput
226
+ UID int
227
+ GID int
214
228
}
215
229
216
230
func GetDockerClient (ctx context.Context ) (cli client.APIClient , err error ) {
@@ -581,6 +595,47 @@ func (cr *containerReference) exec(cmd []string, env map[string]string, user, wo
581
595
}
582
596
}
583
597
598
+ func (cr * containerReference ) tryReadID (opt string , cbk func (id int )) common.Executor {
599
+ return func (ctx context.Context ) error {
600
+ idResp , err := cr .cli .ContainerExecCreate (ctx , cr .id , types.ExecConfig {
601
+ Cmd : []string {"id" , opt },
602
+ AttachStdout : true ,
603
+ AttachStderr : true ,
604
+ })
605
+ if err != nil {
606
+ return nil
607
+ }
608
+
609
+ resp , err := cr .cli .ContainerExecAttach (ctx , idResp .ID , types.ExecStartCheck {})
610
+ if err != nil {
611
+ return nil
612
+ }
613
+ defer resp .Close ()
614
+
615
+ sid , err := resp .Reader .ReadString ('\n' )
616
+ if err != nil {
617
+ return nil
618
+ }
619
+ exp := regexp .MustCompile (`\d+\n` )
620
+ found := exp .FindString (sid )
621
+ id , err := strconv .ParseInt (found [:len (found )- 1 ], 10 , 32 )
622
+ if err != nil {
623
+ return nil
624
+ }
625
+ cbk (int (id ))
626
+
627
+ return nil
628
+ }
629
+ }
630
+
631
+ func (cr * containerReference ) tryReadUID () common.Executor {
632
+ return cr .tryReadID ("-u" , func (id int ) { cr .UID = id })
633
+ }
634
+
635
+ func (cr * containerReference ) tryReadGID () common.Executor {
636
+ return cr .tryReadID ("-g" , func (id int ) { cr .GID = id })
637
+ }
638
+
584
639
func (cr * containerReference ) waitForCommand (ctx context.Context , isTerminal bool , resp types.HijackedResponse , idResp types.IDResponse , user string , workdir string ) error {
585
640
logger := common .Logger (ctx )
586
641
@@ -670,6 +725,9 @@ func (cr *containerReference) copyDir(dstPath string, srcPath string, useGitIgno
670
725
SrcPrefix : srcPrefix ,
671
726
Handler : & tarCollector {
672
727
TarWriter : tw ,
728
+ UID : cr .UID ,
729
+ GID : cr .GID ,
730
+ DstDir : dstPath [1 :],
673
731
},
674
732
}
675
733
@@ -686,7 +744,7 @@ func (cr *containerReference) copyDir(dstPath string, srcPath string, useGitIgno
686
744
if err != nil {
687
745
return fmt .Errorf ("failed to seek tar archive: %w" , err )
688
746
}
689
- err = cr .cli .CopyToContainer (ctx , cr .id , dstPath , tarFile , types.CopyToContainerOptions {})
747
+ err = cr .cli .CopyToContainer (ctx , cr .id , "/" , tarFile , types.CopyToContainerOptions {})
690
748
if err != nil {
691
749
return fmt .Errorf ("failed to copy content to container: %w" , err )
692
750
}
@@ -705,6 +763,8 @@ func (cr *containerReference) copyContent(dstPath string, files ...*FileEntry) c
705
763
Name : file .Name ,
706
764
Mode : file .Mode ,
707
765
Size : int64 (len (file .Body )),
766
+ Uid : cr .UID ,
767
+ Gid : cr .GID ,
708
768
}
709
769
if err := tw .WriteHeader (hdr ); err != nil {
710
770
return err
0 commit comments