@@ -125,17 +125,17 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
125
125
if ! mountExists {
126
126
logger .Debug ("creating bind mount" , zap .String ("src" , src ), zap .String ("dst" , dst ))
127
127
128
- if err = createBindMount (src , dst , spec .TypedSpec ().Mode ); err != nil {
128
+ if err = createBindMountFile (src , dst , spec .TypedSpec ().Mode ); err != nil {
129
129
return fmt .Errorf ("failed to create shadow bind mount %q -> %q: %w" , src , dst , err )
130
130
}
131
131
132
132
ctrl .bindMounts [filename ] = struct {}{}
133
133
}
134
134
135
- logger .Debug ("writing file contents" , zap .String ("dst " , dst ), zap .Stringer ("version" , spec .Metadata ().Version ()))
135
+ logger .Debug ("writing file contents" , zap .String ("src " , src ), zap .Stringer ("version" , spec .Metadata ().Version ()))
136
136
137
- if err = UpdateFile (dst , spec .TypedSpec ().Contents , spec .TypedSpec ().Mode , spec .TypedSpec ().SelinuxLabel ); err != nil {
138
- return fmt .Errorf ("error updating %q: %w" , dst , err )
137
+ if err = UpdateFile (src , spec .TypedSpec ().Contents , spec .TypedSpec ().Mode , spec .TypedSpec ().SelinuxLabel ); err != nil {
138
+ return fmt .Errorf ("error updating %q: %w" , src , err )
139
139
}
140
140
141
141
if err = safe .WriterModify (ctx , r , files .NewEtcFileStatus (files .NamespaceName , filename ), func (r * files.EtcFileStatus ) error {
@@ -168,10 +168,10 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
168
168
}
169
169
}
170
170
171
- // createBindMount creates a common way to create a writable source file with a
171
+ // createBindMountFile creates a common way to create a writable source file with a
172
172
// bind mounted destination. This is most commonly used for well known files
173
173
// under /etc that need to be adjusted during startup.
174
- func createBindMount (src , dst string , mode os.FileMode ) (err error ) {
174
+ func createBindMountFile (src , dst string , mode os.FileMode ) (err error ) {
175
175
if err = os .MkdirAll (filepath .Dir (src ), 0o755 ); err != nil {
176
176
return err
177
177
}
@@ -186,8 +186,37 @@ func createBindMount(src, dst string, mode os.FileMode) (err error) {
186
186
return err
187
187
}
188
188
189
- if err = unix .Mount (src , dst , "" , unix .MS_BIND | unix .MS_RDONLY , "" ); err != nil {
190
- return fmt .Errorf ("failed to create bind mount for %s: %w" , dst , err )
189
+ return bindMount (src , dst )
190
+ }
191
+
192
+ // createBindMountDir creates a common way to create a writable source dir with a
193
+ // bind mounted destination. This is most commonly used for well known directories
194
+ // under /etc that need to be adjusted during startup.
195
+ func createBindMountDir (src , dst string ) (err error ) {
196
+ if err = os .MkdirAll (src , 0o755 ); err != nil {
197
+ return err
198
+ }
199
+
200
+ return bindMount (src , dst )
201
+ }
202
+
203
+ // bindMount creates a common way to create a readonly bind mounted destination.
204
+ func bindMount (src , dst string ) (err error ) {
205
+ sourceFD , err := unix .OpenTree (unix .AT_FDCWD , src , unix .OPEN_TREE_CLONE | unix .OPEN_TREE_CLOEXEC )
206
+ if err != nil {
207
+ return fmt .Errorf ("failed to opentree source %s: %w" , src , err )
208
+ }
209
+
210
+ defer unix .Close (sourceFD ) //nolint:errcheck
211
+
212
+ if err := unix .MountSetattr (sourceFD , "" , unix .AT_EMPTY_PATH , & unix.MountAttr {
213
+ Attr_set : unix .MOUNT_ATTR_RDONLY ,
214
+ }); err != nil {
215
+ return fmt .Errorf ("failed to set mount attribute: %w" , err )
216
+ }
217
+
218
+ if err := unix .MoveMount (sourceFD , "" , unix .AT_FDCWD , dst , unix .MOVE_MOUNT_F_EMPTY_PATH ); err != nil {
219
+ return fmt .Errorf ("failed to move mount from %s to %s: %w" , src , dst , err )
191
220
}
192
221
193
222
return nil
0 commit comments