@@ -29,8 +29,6 @@ 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"
3432)
3533
3634const ConfigDirLabel = "operators.operatorframework.io.index.configs.v1"
@@ -72,11 +70,12 @@ func (i *ContainersImageRegistry) Unpack(ctx context.Context, catalog *catalogdv
7270 //
7371 //////////////////////////////////////////////////////
7472 unpackPath := i .unpackPath (catalog .Name , canonicalRef .Digest ())
75- if isUnpacked , unpackTime , err := source .IsImageUnpacked (unpackPath ); isUnpacked && err == nil {
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+ }
7677 l .Info ("image already unpacked" , "ref" , imgRef .String (), "digest" , canonicalRef .Digest ().String ())
77- return successResult (unpackPath , canonicalRef , unpackTime ), nil
78- } else if err != nil {
79- return nil , fmt .Errorf ("error checking image already unpacked: %w" , err )
78+ return successResult (unpackPath , canonicalRef , unpackStat .ModTime ()), nil
8079 }
8180
8281 //////////////////////////////////////////////////////
@@ -149,7 +148,7 @@ func (i *ContainersImageRegistry) Unpack(ctx context.Context, catalog *catalogdv
149148 //
150149 //////////////////////////////////////////////////////
151150 if err := i .unpackImage (ctx , unpackPath , layoutRef , specIsCanonical , srcCtx ); err != nil {
152- if cleanupErr := source . DeleteReadOnlyRecursive (unpackPath ); cleanupErr != nil {
151+ if cleanupErr := deleteRecursive (unpackPath ); cleanupErr != nil {
153152 err = errors .Join (err , cleanupErr )
154153 }
155154 return nil , fmt .Errorf ("error unpacking image: %w" , err )
@@ -190,7 +189,7 @@ func successResult(unpackPath string, canonicalRef reference.Canonical, lastUnpa
190189}
191190
192191func (i * ContainersImageRegistry ) Cleanup (_ context.Context , catalog * catalogdv1.ClusterCatalog ) error {
193- if err := source . DeleteReadOnlyRecursive (i .catalogPath (catalog .Name )); err != nil {
192+ if err := deleteRecursive (i .catalogPath (catalog .Name )); err != nil {
194193 return fmt .Errorf ("error deleting catalog cache: %w" , err )
195194 }
196195 return nil
@@ -289,8 +288,8 @@ func (i *ContainersImageRegistry) unpackImage(ctx context.Context, unpackPath st
289288 return wrapTerminal (fmt .Errorf ("catalog image is missing the required label %q" , ConfigDirLabel ), specIsCanonical )
290289 }
291290
292- if err := util . EnsureEmptyDirectory (unpackPath , 0700 ); err != nil {
293- return fmt .Errorf ("error ensuring empty unpack directory: %w" , err )
291+ if err := os . MkdirAll (unpackPath , 0700 ); err != nil {
292+ return fmt .Errorf ("error creating unpack directory: %w" , err )
294293 }
295294 l := log .FromContext (ctx )
296295 l .Info ("unpacking image" , "path" , unpackPath )
@@ -308,10 +307,10 @@ func (i *ContainersImageRegistry) unpackImage(ctx context.Context, unpackPath st
308307 l .Info ("applied layer" , "layer" , i )
309308 return nil
310309 }(); err != nil {
311- return errors .Join (err , source . DeleteReadOnlyRecursive (unpackPath ))
310+ return errors .Join (err , deleteRecursive (unpackPath ))
312311 }
313312 }
314- if err := source . SetReadOnlyRecursive (unpackPath ); err != nil {
313+ if err := setReadOnlyRecursive (unpackPath ); err != nil {
315314 return fmt .Errorf ("error making unpack directory read-only: %w" , err )
316315 }
317316 return nil
@@ -355,13 +354,69 @@ func (i *ContainersImageRegistry) deleteOtherImages(catalogName string, digestTo
355354 continue
356355 }
357356 imgDirPath := filepath .Join (catalogPath , imgDir .Name ())
358- if err := source . DeleteReadOnlyRecursive (imgDirPath ); err != nil {
357+ if err := deleteRecursive (imgDirPath ); err != nil {
359358 return fmt .Errorf ("error removing image directory: %w" , err )
360359 }
361360 }
362361 return nil
363362}
364363
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+
365420func wrapTerminal (err error , isTerminal bool ) error {
366421 if ! isTerminal {
367422 return err
0 commit comments