@@ -29,6 +29,8 @@ import (
29
29
"sigs.k8s.io/controller-runtime/pkg/reconcile"
30
30
31
31
catalogdv1 "github.com/operator-framework/operator-controller/catalogd/api/v1"
32
+ "github.com/operator-framework/operator-controller/internal/rukpak/source"
33
+ "github.com/operator-framework/operator-controller/internal/util"
32
34
)
33
35
34
36
const ConfigDirLabel = "operators.operatorframework.io.index.configs.v1"
@@ -70,12 +72,11 @@ func (i *ContainersImageRegistry) Unpack(ctx context.Context, catalog *catalogdv
70
72
//
71
73
//////////////////////////////////////////////////////
72
74
unpackPath := i .unpackPath (catalog .Name , canonicalRef .Digest ())
73
- if unpackStat , err := os .Stat (unpackPath ); err == nil {
74
- if ! unpackStat .IsDir () {
75
- panic (fmt .Sprintf ("unexpected file at unpack path %q: expected a directory" , unpackPath ))
76
- }
75
+ if isUnpacked , unpackTime , err := source .IsImageUnpacked (unpackPath ); isUnpacked && err == nil {
77
76
l .Info ("image already unpacked" , "ref" , imgRef .String (), "digest" , canonicalRef .Digest ().String ())
78
- return successResult (unpackPath , canonicalRef , unpackStat .ModTime ()), nil
77
+ return successResult (unpackPath , canonicalRef , unpackTime ), nil
78
+ } else if err != nil {
79
+ return nil , fmt .Errorf ("error checking image already unpacked: %w" , err )
79
80
}
80
81
81
82
//////////////////////////////////////////////////////
@@ -148,7 +149,7 @@ func (i *ContainersImageRegistry) Unpack(ctx context.Context, catalog *catalogdv
148
149
//
149
150
//////////////////////////////////////////////////////
150
151
if err := i .unpackImage (ctx , unpackPath , layoutRef , specIsCanonical , srcCtx ); err != nil {
151
- if cleanupErr := deleteRecursive (unpackPath ); cleanupErr != nil {
152
+ if cleanupErr := source . DeleteReadOnlyRecursive (unpackPath ); cleanupErr != nil {
152
153
err = errors .Join (err , cleanupErr )
153
154
}
154
155
return nil , fmt .Errorf ("error unpacking image: %w" , err )
@@ -189,7 +190,7 @@ func successResult(unpackPath string, canonicalRef reference.Canonical, lastUnpa
189
190
}
190
191
191
192
func (i * ContainersImageRegistry ) Cleanup (_ context.Context , catalog * catalogdv1.ClusterCatalog ) error {
192
- if err := deleteRecursive (i .catalogPath (catalog .Name )); err != nil {
193
+ if err := source . DeleteReadOnlyRecursive (i .catalogPath (catalog .Name )); err != nil {
193
194
return fmt .Errorf ("error deleting catalog cache: %w" , err )
194
195
}
195
196
return nil
@@ -288,8 +289,8 @@ func (i *ContainersImageRegistry) unpackImage(ctx context.Context, unpackPath st
288
289
return wrapTerminal (fmt .Errorf ("catalog image is missing the required label %q" , ConfigDirLabel ), specIsCanonical )
289
290
}
290
291
291
- if err := os . MkdirAll (unpackPath , 0700 ); err != nil {
292
- return fmt .Errorf ("error creating unpack directory: %w" , err )
292
+ if err := util . EnsureEmptyDirectory (unpackPath , 0700 ); err != nil {
293
+ return fmt .Errorf ("error ensuring empty unpack directory: %w" , err )
293
294
}
294
295
l := log .FromContext (ctx )
295
296
l .Info ("unpacking image" , "path" , unpackPath )
@@ -307,10 +308,10 @@ func (i *ContainersImageRegistry) unpackImage(ctx context.Context, unpackPath st
307
308
l .Info ("applied layer" , "layer" , i )
308
309
return nil
309
310
}(); err != nil {
310
- return errors .Join (err , deleteRecursive (unpackPath ))
311
+ return errors .Join (err , source . DeleteReadOnlyRecursive (unpackPath ))
311
312
}
312
313
}
313
- if err := setReadOnlyRecursive (unpackPath ); err != nil {
314
+ if err := source . SetReadOnlyRecursive (unpackPath ); err != nil {
314
315
return fmt .Errorf ("error making unpack directory read-only: %w" , err )
315
316
}
316
317
return nil
@@ -354,69 +355,13 @@ func (i *ContainersImageRegistry) deleteOtherImages(catalogName string, digestTo
354
355
continue
355
356
}
356
357
imgDirPath := filepath .Join (catalogPath , imgDir .Name ())
357
- if err := deleteRecursive (imgDirPath ); err != nil {
358
+ if err := source . DeleteReadOnlyRecursive (imgDirPath ); err != nil {
358
359
return fmt .Errorf ("error removing image directory: %w" , err )
359
360
}
360
361
}
361
362
return nil
362
363
}
363
364
364
- func setReadOnlyRecursive (root string ) error {
365
- if err := filepath .WalkDir (root , func (path string , d os.DirEntry , err error ) error {
366
- if err != nil {
367
- return err
368
- }
369
-
370
- fi , err := d .Info ()
371
- if err != nil {
372
- return err
373
- }
374
-
375
- if err := func () error {
376
- switch typ := fi .Mode ().Type (); typ {
377
- case os .ModeSymlink :
378
- // do not follow symlinks
379
- // 1. if they resolve to other locations in the root, we'll find them anyway
380
- // 2. if they resolve to other locations outside the root, we don't want to change their permissions
381
- return nil
382
- case os .ModeDir :
383
- return os .Chmod (path , 0500 )
384
- case 0 : // regular file
385
- return os .Chmod (path , 0400 )
386
- default :
387
- return fmt .Errorf ("refusing to change ownership of file %q with type %v" , path , typ .String ())
388
- }
389
- }(); err != nil {
390
- return err
391
- }
392
- return nil
393
- }); err != nil {
394
- return fmt .Errorf ("error making catalog cache read-only: %w" , err )
395
- }
396
- return nil
397
- }
398
-
399
- func deleteRecursive (root string ) error {
400
- if err := filepath .WalkDir (root , func (path string , d os.DirEntry , err error ) error {
401
- if os .IsNotExist (err ) {
402
- return nil
403
- }
404
- if err != nil {
405
- return err
406
- }
407
- if ! d .IsDir () {
408
- return nil
409
- }
410
- if err := os .Chmod (path , 0700 ); err != nil {
411
- return err
412
- }
413
- return nil
414
- }); err != nil {
415
- return fmt .Errorf ("error making catalog cache writable for deletion: %w" , err )
416
- }
417
- return os .RemoveAll (root )
418
- }
419
-
420
365
func wrapTerminal (err error , isTerminal bool ) error {
421
366
if ! isTerminal {
422
367
return err
0 commit comments