@@ -115,7 +115,8 @@ func (c *CertSyncController) sync(ctx context.Context, syncCtx factory.SyncConte
115
115
116
116
contentDir := getConfigMapDir (c .destinationDir , cm .Name )
117
117
118
- data := map [string ]string {}
118
+ data := make (map [string ]string , len (configMap .Data ))
119
+ dataBytes := make (map [string ][]byte , len (configMap .Data ))
119
120
for filename := range configMap .Data {
120
121
fullFilename := filepath .Join (contentDir , filename )
121
122
@@ -128,6 +129,7 @@ func (c *CertSyncController) sync(ctx context.Context, syncCtx factory.SyncConte
128
129
}
129
130
130
131
data [filename ] = string (existingContent )
132
+ dataBytes [filename ] = existingContent
131
133
}
132
134
133
135
// Check if cached configmap differs
@@ -152,27 +154,7 @@ func (c *CertSyncController) sync(ctx context.Context, syncCtx factory.SyncConte
152
154
continue
153
155
}
154
156
155
- klog .Infof ("Creating directory %q ..." , contentDir )
156
- if err := os .MkdirAll (contentDir , 0755 ); err != nil && ! os .IsExist (err ) {
157
- c .eventRecorder .Warningf ("CertificateUpdateFailed" , "Failed creating directory for configmap: %s/%s: %v" , configMap .Namespace , configMap .Name , err )
158
- errors = append (errors , err )
159
- continue
160
- }
161
- for filename , content := range configMap .Data {
162
- fullFilename := filepath .Join (contentDir , filename )
163
- // if the existing is the same, do nothing
164
- if reflect .DeepEqual (data [fullFilename ], content ) {
165
- continue
166
- }
167
-
168
- klog .Infof ("Writing configmap manifest %q ..." , fullFilename )
169
- if err := staticpod .WriteFileAtomic ([]byte (content ), 0644 , fullFilename ); err != nil {
170
- c .eventRecorder .Warningf ("CertificateUpdateFailed" , "Failed writing file for configmap: %s/%s: %v" , configMap .Namespace , configMap .Name , err )
171
- errors = append (errors , err )
172
- continue
173
- }
174
- }
175
- c .eventRecorder .Eventf ("CertificateUpdated" , "Wrote updated configmap: %s/%s" , configMap .Namespace , configMap .Name )
157
+ errors = append (errors , c .writeData (configMap .Namespace , configMap .Name , "configmap" , contentDir , dataBytes )... )
176
158
}
177
159
178
160
klog .Infof ("Syncing secrets: %v" , c .secrets )
@@ -220,7 +202,7 @@ func (c *CertSyncController) sync(ctx context.Context, syncCtx factory.SyncConte
220
202
221
203
contentDir := getSecretDir (c .destinationDir , s .Name )
222
204
223
- data := map [string ][]byte {}
205
+ data := make ( map [string ][]byte , len ( secret . Data ))
224
206
for filename := range secret .Data {
225
207
fullFilename := filepath .Join (contentDir , filename )
226
208
@@ -257,29 +239,64 @@ func (c *CertSyncController) sync(ctx context.Context, syncCtx factory.SyncConte
257
239
continue
258
240
}
259
241
260
- klog .Infof ("Creating directory %q ..." , contentDir )
261
- if err := os .MkdirAll (contentDir , 0755 ); err != nil && ! os .IsExist (err ) {
262
- c .eventRecorder .Warningf ("CertificateUpdateFailed" , "Failed creating directory for secret: %s/%s: %v" , secret .Namespace , secret .Name , err )
242
+ errors = append (errors , c .writeData (secret .Namespace , secret .Name , "secret" , contentDir , data )... )
243
+ }
244
+
245
+ return utilerrors .NewAggregate (errors )
246
+ }
247
+
248
+ func (c * CertSyncController ) writeData (
249
+ objectNamespace , objectName , kind string ,
250
+ contentDir string , data map [string ][]byte ,
251
+ ) []error {
252
+ var errors []error
253
+
254
+ // We are going to atomically swap the new data directory for the old one.
255
+ // In case the target directory does not exist, create it so that the directory not existing is not a special case.
256
+ klog .Infof ("Ensuring directory %q exists ..." , contentDir )
257
+ if err := os .MkdirAll (contentDir , 0755 ); err != nil && ! os .IsExist (err ) {
258
+ c .eventRecorder .Warningf ("CertificateUpdateFailed" ,
259
+ "Failed creating content directory for %s: %s/%s: %v" , kind , objectNamespace , objectName , err )
260
+ errors = append (errors , err )
261
+ return errors
262
+ }
263
+
264
+ // Create a tmp source directory to be swapped.
265
+ srcDir , err := os .MkdirTemp (filepath .Dir (contentDir ), filepath .Base (contentDir )+ "-*" )
266
+ if err != nil {
267
+ c .eventRecorder .Warningf ("CertificateUpdateFailed" ,
268
+ "Failed to create source %s directory for %s/%s: %v" , kind , objectNamespace , objectName , err )
269
+ errors = append (errors , err )
270
+ return errors
271
+ }
272
+ defer os .RemoveAll (srcDir )
273
+
274
+ // Populate the tmp directory with files.
275
+ for filename , content := range data {
276
+ // TODO: Fix permissions
277
+ fullFilename := filepath .Join (srcDir , filename )
278
+ klog .Infof ("Writing %s manifest %q ..." , kind , fullFilename )
279
+
280
+ if err := os .WriteFile (fullFilename , content , 0600 ); err != nil {
281
+ c .eventRecorder .Warningf ("CertificateUpdateFailed" ,
282
+ "Failed writing file for %s: %s/%s: %v" , kind , objectNamespace , objectName , err )
263
283
errors = append (errors , err )
264
284
continue
265
285
}
266
- for filename , content := range secret .Data {
267
- // TODO fix permissions
268
- fullFilename := filepath .Join (contentDir , filename )
269
- // if the existing is the same, do nothing
270
- if reflect .DeepEqual (data [fullFilename ], content ) {
271
- continue
272
- }
286
+ }
287
+ if len (errors ) > 0 {
288
+ return errors
289
+ }
273
290
274
- klog .Infof ("Writing secret manifest %q ..." , fullFilename )
275
- if err := staticpod .WriteFileAtomic (content , 0600 , fullFilename ); err != nil {
276
- c .eventRecorder .Warningf ("CertificateUpdateFailed" , "Failed writing file for secret: %s/%s: %v" , secret .Namespace , secret .Name , err )
277
- errors = append (errors , err )
278
- continue
279
- }
280
- }
281
- c .eventRecorder .Eventf ("CertificateUpdated" , "Wrote updated secret: %s/%s" , secret .Namespace , secret .Name )
291
+ // Swap directories atomically.
292
+ if err := staticpod .SwapDirectoriesAtomic (contentDir , srcDir ); err != nil {
293
+ c .eventRecorder .Warningf ("CertificateUpdateFailed" ,
294
+ "Failed to enable new %s directory for %s/%s: %v" , kind , objectNamespace , objectName , err )
295
+ errors = append (errors , err )
296
+ return errors
282
297
}
283
298
284
- return utilerrors .NewAggregate (errors )
299
+ c .eventRecorder .Eventf ("CertificateUpdated" ,
300
+ "Wrote updated %s: %s/%s" , kind , objectNamespace , objectName )
301
+ return nil
285
302
}
0 commit comments