@@ -56,24 +56,30 @@ const (
56
56
type IgnoreListEntry struct {
57
57
Path string
58
58
PrefixMatchOnly bool
59
+ // AllowedPaths specifies **exact matches** to allow, even if they are under
60
+ // Path.
61
+ AllowedPaths []string
59
62
}
60
63
61
64
var defaultIgnoreList = []IgnoreListEntry {
62
65
{
63
66
Path : filepath .Clean (config .KanikoDir ),
64
67
PrefixMatchOnly : false ,
68
+ AllowedPaths : nil ,
65
69
},
66
70
{
67
71
// similarly, we ignore /etc/mtab, since there is no way to know if the file was mounted or came
68
72
// from the base image
69
73
Path : "/etc/mtab" ,
70
74
PrefixMatchOnly : false ,
75
+ AllowedPaths : nil ,
71
76
},
72
77
{
73
78
// we ingore /tmp/apt-key-gpghome, since the apt keys are added temporarily in this directory.
74
79
// from the base image
75
80
Path : "/tmp/apt-key-gpghome" ,
76
81
PrefixMatchOnly : true ,
82
+ AllowedPaths : nil ,
77
83
},
78
84
}
79
85
@@ -111,16 +117,29 @@ func AddToIgnoreList(entry IgnoreListEntry) {
111
117
ignorelist = append (ignorelist , IgnoreListEntry {
112
118
Path : filepath .Clean (entry .Path ),
113
119
PrefixMatchOnly : entry .PrefixMatchOnly ,
120
+ AllowedPaths : nil ,
114
121
})
115
122
}
116
123
117
124
func AddToDefaultIgnoreList (entry IgnoreListEntry ) {
118
125
defaultIgnoreList = append (defaultIgnoreList , IgnoreListEntry {
119
126
Path : filepath .Clean (entry .Path ),
120
127
PrefixMatchOnly : entry .PrefixMatchOnly ,
128
+ AllowedPaths : nil ,
121
129
})
122
130
}
123
131
132
+ func AddAllowedPathToDefaultIgnoreList (allowPath string ) error {
133
+ for _ , ile := range defaultIgnoreList {
134
+ if ! strings .HasPrefix (allowPath , ile .Path ) {
135
+ continue
136
+ }
137
+ ile .AllowedPaths = append (ile .AllowedPaths , allowPath )
138
+ return nil
139
+ }
140
+ return fmt .Errorf ("path %q is not covered by any current entry in ignore list" , allowPath )
141
+ }
142
+
124
143
func IncludeWhiteout () FSOpt {
125
144
return func (opts * FSConfig ) {
126
145
opts .includeWhiteout = true
@@ -500,6 +519,11 @@ func IsInIgnoreList(path string) bool {
500
519
501
520
func CheckCleanedPathAgainstProvidedIgnoreList (path string , wl []IgnoreListEntry ) bool {
502
521
for _ , wl := range ignorelist {
522
+ for _ , ap := range wl .AllowedPaths {
523
+ if ap == path {
524
+ return false
525
+ }
526
+ }
503
527
if hasCleanedFilepathPrefix (path , wl .Path , wl .PrefixMatchOnly ) {
504
528
return true
505
529
}
@@ -556,6 +580,7 @@ func DetectFilesystemIgnoreList(path string) error {
556
580
AddToIgnoreList (IgnoreListEntry {
557
581
Path : lineArr [4 ],
558
582
PrefixMatchOnly : false ,
583
+ AllowedPaths : nil ,
559
584
})
560
585
}
561
586
if err == io .EOF {
@@ -668,14 +693,30 @@ func CreateFile(path string, reader io.Reader, perm os.FileMode, uid uint32, gid
668
693
}
669
694
}
670
695
696
+ var renamed string
671
697
dest , err := os .Create (path )
672
698
if err != nil {
673
- return errors .Wrap (err , "creating file" )
699
+ if ! errors .Is (err , syscall .ETXTBSY ) {
700
+ return errors .Wrap (err , "creating file" )
701
+ }
702
+ // If the file is busy, just write to a temp file and
703
+ // move to dest.
704
+ dest , err = os .CreateTemp (os .TempDir (), "" )
705
+ if err != nil {
706
+ return errors .Wrap (err , "create temp file" )
707
+ }
708
+ defer os .Remove (dest .Name ())
709
+ renamed = dest .Name ()
674
710
}
675
711
defer dest .Close ()
676
712
if _ , err := io .Copy (dest , reader ); err != nil {
677
713
return errors .Wrap (err , "copying file" )
678
714
}
715
+ if renamed != "" {
716
+ if err := os .Rename (renamed , path ); err != nil {
717
+ return errors .Wrap (err , "rename temp file" )
718
+ }
719
+ }
679
720
return setFilePermissions (path , perm , int (uid ), int (gid ))
680
721
}
681
722
@@ -685,6 +726,7 @@ func AddVolumePathToIgnoreList(path string) {
685
726
AddToIgnoreList (IgnoreListEntry {
686
727
Path : path ,
687
728
PrefixMatchOnly : true ,
729
+ AllowedPaths : nil ,
688
730
})
689
731
volumes = append (volumes , path )
690
732
}
0 commit comments