@@ -30,6 +30,8 @@ import (
30
30
"sigs.k8s.io/controller-runtime/pkg/reconcile"
31
31
32
32
catalogdv1 "github.com/operator-framework/operator-controller/catalogd/api/v1"
33
+ "github.com/operator-framework/operator-controller/internal/rukpak/source"
34
+ "github.com/operator-framework/operator-controller/internal/util"
33
35
)
34
36
35
37
const ConfigDirLabel = "operators.operatorframework.io.index.configs.v1"
@@ -76,12 +78,11 @@ func (i *ContainersImageRegistry) Unpack(ctx context.Context, catalog *catalogdv
76
78
//
77
79
//////////////////////////////////////////////////////
78
80
unpackPath := i .unpackPath (catalog .Name , canonicalRef .Digest ())
79
- if unpackStat , err := os .Stat (unpackPath ); err == nil {
80
- if ! unpackStat .IsDir () {
81
- panic (fmt .Sprintf ("unexpected file at unpack path %q: expected a directory" , unpackPath ))
82
- }
81
+ if isUnpacked , unpackTime , err := source .IsImageUnpacked (unpackPath ); isUnpacked && err == nil {
83
82
l .Info ("image already unpacked" , "ref" , imgRef .String (), "digest" , canonicalRef .Digest ().String ())
84
- return successResult (unpackPath , canonicalRef , unpackStat .ModTime ()), nil
83
+ return successResult (unpackPath , canonicalRef , unpackTime ), nil
84
+ } else if err != nil {
85
+ return nil , fmt .Errorf ("error checking image already unpacked: %w" , err )
85
86
}
86
87
87
88
//////////////////////////////////////////////////////
@@ -154,7 +155,7 @@ func (i *ContainersImageRegistry) Unpack(ctx context.Context, catalog *catalogdv
154
155
//
155
156
//////////////////////////////////////////////////////
156
157
if err := i .unpackImage (ctx , unpackPath , layoutRef , specIsCanonical , srcCtx ); err != nil {
157
- if cleanupErr := deleteRecursive (unpackPath ); cleanupErr != nil {
158
+ if cleanupErr := source . DeleteReadOnlyRecursive (unpackPath ); cleanupErr != nil {
158
159
err = errors .Join (err , cleanupErr )
159
160
}
160
161
return nil , fmt .Errorf ("error unpacking image: %w" , err )
@@ -195,7 +196,7 @@ func successResult(unpackPath string, canonicalRef reference.Canonical, lastUnpa
195
196
}
196
197
197
198
func (i * ContainersImageRegistry ) Cleanup (_ context.Context , catalog * catalogdv1.ClusterCatalog ) error {
198
- if err := deleteRecursive (i .catalogPath (catalog .Name )); err != nil {
199
+ if err := source . DeleteReadOnlyRecursive (i .catalogPath (catalog .Name )); err != nil {
199
200
return fmt .Errorf ("error deleting catalog cache: %w" , err )
200
201
}
201
202
return nil
@@ -296,8 +297,8 @@ func (i *ContainersImageRegistry) unpackImage(ctx context.Context, unpackPath st
296
297
return wrapTerminal (fmt .Errorf ("catalog image is missing the required label %q" , ConfigDirLabel ), specIsCanonical )
297
298
}
298
299
299
- if err := os . MkdirAll (unpackPath , 0700 ); err != nil {
300
- return fmt .Errorf ("error creating unpack directory: %w" , err )
300
+ if err := util . EnsureEmptyDirectory (unpackPath , 0700 ); err != nil {
301
+ return fmt .Errorf ("error ensuring empty unpack directory: %w" , err )
301
302
}
302
303
l := log .FromContext (ctx )
303
304
l .Info ("unpacking image" , "path" , unpackPath )
@@ -315,10 +316,10 @@ func (i *ContainersImageRegistry) unpackImage(ctx context.Context, unpackPath st
315
316
l .Info ("applied layer" , "layer" , i )
316
317
return nil
317
318
}(); err != nil {
318
- return errors .Join (err , deleteRecursive (unpackPath ))
319
+ return errors .Join (err , source . DeleteReadOnlyRecursive (unpackPath ))
319
320
}
320
321
}
321
- if err := setReadOnlyRecursive (unpackPath ); err != nil {
322
+ if err := source . SetReadOnlyRecursive (unpackPath ); err != nil {
322
323
return fmt .Errorf ("error making unpack directory read-only: %w" , err )
323
324
}
324
325
return nil
@@ -362,69 +363,13 @@ func (i *ContainersImageRegistry) deleteOtherImages(catalogName string, digestTo
362
363
continue
363
364
}
364
365
imgDirPath := filepath .Join (catalogPath , imgDir .Name ())
365
- if err := deleteRecursive (imgDirPath ); err != nil {
366
+ if err := source . DeleteReadOnlyRecursive (imgDirPath ); err != nil {
366
367
return fmt .Errorf ("error removing image directory: %w" , err )
367
368
}
368
369
}
369
370
return nil
370
371
}
371
372
372
- func setReadOnlyRecursive (root string ) error {
373
- if err := filepath .WalkDir (root , func (path string , d os.DirEntry , err error ) error {
374
- if err != nil {
375
- return err
376
- }
377
-
378
- fi , err := d .Info ()
379
- if err != nil {
380
- return err
381
- }
382
-
383
- if err := func () error {
384
- switch typ := fi .Mode ().Type (); typ {
385
- case os .ModeSymlink :
386
- // do not follow symlinks
387
- // 1. if they resolve to other locations in the root, we'll find them anyway
388
- // 2. if they resolve to other locations outside the root, we don't want to change their permissions
389
- return nil
390
- case os .ModeDir :
391
- return os .Chmod (path , 0500 )
392
- case 0 : // regular file
393
- return os .Chmod (path , 0400 )
394
- default :
395
- return fmt .Errorf ("refusing to change ownership of file %q with type %v" , path , typ .String ())
396
- }
397
- }(); err != nil {
398
- return err
399
- }
400
- return nil
401
- }); err != nil {
402
- return fmt .Errorf ("error making catalog cache read-only: %w" , err )
403
- }
404
- return nil
405
- }
406
-
407
- func deleteRecursive (root string ) error {
408
- if err := filepath .WalkDir (root , func (path string , d os.DirEntry , err error ) error {
409
- if os .IsNotExist (err ) {
410
- return nil
411
- }
412
- if err != nil {
413
- return err
414
- }
415
- if ! d .IsDir () {
416
- return nil
417
- }
418
- if err := os .Chmod (path , 0700 ); err != nil {
419
- return err
420
- }
421
- return nil
422
- }); err != nil {
423
- return fmt .Errorf ("error making catalog cache writable for deletion: %w" , err )
424
- }
425
- return os .RemoveAll (root )
426
- }
427
-
428
373
func wrapTerminal (err error , isTerminal bool ) error {
429
374
if ! isTerminal {
430
375
return err
0 commit comments