github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/client/cache/dir.go (about) 1 // Copyright (c) 2018-2019, Sylabs Inc. All rights reserved. 2 // This software is licensed under a 3-clause BSD license. Please consult the 3 // LICENSE.md file distributed with the sources of this project regarding your 4 // rights to use or distribute this software. 5 6 // Package cache provides support for automatic caching of any image supported by containers/image 7 package cache 8 9 import ( 10 "fmt" 11 "os" 12 "os/user" 13 "path" 14 "path/filepath" 15 16 "github.com/sylabs/singularity/internal/pkg/sylog" 17 "github.com/sylabs/singularity/internal/pkg/util/fs" 18 ) 19 20 const ( 21 // DirEnv specifies the environment variable which can set the directory 22 // for image downloads to be cached in 23 DirEnv = "SINGULARITY_CACHEDIR" 24 25 // RootDefault specifies the directory inside of ${HOME} that images are 26 // cached in by default. 27 // Uses "~/.singularity/cache" which will not clash with any 2.x cache 28 // directory. 29 RootDefault = ".singularity/cache" 30 ) 31 32 var root string 33 34 // Root is the root location where all of singularity caching happens. Library, Shub, 35 // and oci image formats supported by containers/image repository will be cached inside 36 // 37 // Defaults to ${HOME}/.singularity/cache 38 func Root() string { 39 updateCacheRoot() 40 41 return root 42 } 43 44 // Clean : wipes all files in the cache directory, will return a error if one occurs 45 func Clean() error { 46 sylog.Debugf("Removing: %v", Root()) 47 48 if err := os.RemoveAll(Root()); err != nil { 49 return fmt.Errorf("unable to clean all cache: %s", err) 50 } 51 52 return nil 53 } 54 55 func updateCacheRoot() { 56 usr, err := user.Current() 57 if err != nil { 58 sylog.Fatalf("Couldn't determine user home directory: %v", err) 59 } 60 61 if d := os.Getenv(DirEnv); d != "" { 62 root = d 63 } else { 64 root = path.Join(usr.HomeDir, RootDefault) 65 } 66 67 if err := initCacheDir(root); err != nil { 68 sylog.Fatalf("Unable to initialize caching directory: %v", err) 69 } 70 } 71 72 func updateCacheSubdir(subdir string) string { 73 updateCacheRoot() 74 75 absdir, err := filepath.Abs(filepath.Join(root, subdir)) 76 if err != nil { 77 sylog.Fatalf("Unable to get abs filepath: %v", err) 78 } 79 80 if err := initCacheDir(absdir); err != nil { 81 sylog.Fatalf("Unable to initialize caching directory: %v", err) 82 } 83 84 sylog.Debugf("Caching directory set to %s", absdir) 85 return absdir 86 } 87 88 func initCacheDir(dir string) error { 89 if _, err := os.Stat(dir); os.IsNotExist(err) { 90 sylog.Debugf("Creating cache directory: %s", dir) 91 if err := fs.MkdirAll(dir, 0755); err != nil { 92 return fmt.Errorf("couldn't create cache directory %v: %v", dir, err) 93 } 94 } else if err != nil { 95 return fmt.Errorf("unable to stat %s: %s", dir, err) 96 } 97 98 return nil 99 }