@@ -29,6 +29,8 @@ import (
2929 "sigs.k8s.io/controller-runtime/pkg/reconcile"
3030
3131 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"
3234)
3335
3436const ConfigDirLabel = "operators.operatorframework.io.index.configs.v1"
@@ -70,12 +72,11 @@ func (i *ContainersImageRegistry) Unpack(ctx context.Context, catalog *catalogdv
7072 //
7173 //////////////////////////////////////////////////////
7274 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 {
7776 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 )
7980 }
8081
8182 //////////////////////////////////////////////////////
@@ -148,7 +149,7 @@ func (i *ContainersImageRegistry) Unpack(ctx context.Context, catalog *catalogdv
148149 //
149150 //////////////////////////////////////////////////////
150151 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 {
152153 err = errors .Join (err , cleanupErr )
153154 }
154155 return nil , fmt .Errorf ("error unpacking image: %w" , err )
@@ -189,7 +190,7 @@ func successResult(unpackPath string, canonicalRef reference.Canonical, lastUnpa
189190}
190191
191192func (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 {
193194 return fmt .Errorf ("error deleting catalog cache: %w" , err )
194195 }
195196 return nil
@@ -288,8 +289,8 @@ func (i *ContainersImageRegistry) unpackImage(ctx context.Context, unpackPath st
288289 return wrapTerminal (fmt .Errorf ("catalog image is missing the required label %q" , ConfigDirLabel ), specIsCanonical )
289290 }
290291
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 )
293294 }
294295 l := log .FromContext (ctx )
295296 l .Info ("unpacking image" , "path" , unpackPath )
@@ -307,10 +308,10 @@ func (i *ContainersImageRegistry) unpackImage(ctx context.Context, unpackPath st
307308 l .Info ("applied layer" , "layer" , i )
308309 return nil
309310 }(); err != nil {
310- return errors .Join (err , deleteRecursive (unpackPath ))
311+ return errors .Join (err , source . DeleteReadOnlyRecursive (unpackPath ))
311312 }
312313 }
313- if err := setReadOnlyRecursive (unpackPath ); err != nil {
314+ if err := source . SetReadOnlyRecursive (unpackPath ); err != nil {
314315 return fmt .Errorf ("error making unpack directory read-only: %w" , err )
315316 }
316317 return nil
@@ -354,69 +355,13 @@ func (i *ContainersImageRegistry) deleteOtherImages(catalogName string, digestTo
354355 continue
355356 }
356357 imgDirPath := filepath .Join (catalogPath , imgDir .Name ())
357- if err := deleteRecursive (imgDirPath ); err != nil {
358+ if err := source . DeleteReadOnlyRecursive (imgDirPath ); err != nil {
358359 return fmt .Errorf ("error removing image directory: %w" , err )
359360 }
360361 }
361362 return nil
362363}
363364
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-
420365func wrapTerminal (err error , isTerminal bool ) error {
421366 if ! isTerminal {
422367 return err
0 commit comments