github.com/apptainer/singularity@v3.1.1+incompatible/internal/app/singularity/cache_clean_linux.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 singularity 7 8 import ( 9 "fmt" 10 "io/ioutil" 11 "os" 12 "path/filepath" 13 14 "github.com/sylabs/singularity/internal/pkg/client/cache" 15 "github.com/sylabs/singularity/internal/pkg/sylog" 16 ) 17 18 func cleanLibraryCache() error { 19 sylog.Debugf("Removing: %v", cache.Library()) 20 21 err := os.RemoveAll(cache.Library()) 22 if err != nil { 23 return fmt.Errorf("unable to clean library cache: %v", err) 24 } 25 26 return nil 27 } 28 29 func cleanOciCache() error { 30 sylog.Debugf("Removing: %v", cache.OciTemp()) 31 32 err := os.RemoveAll(cache.OciTemp()) 33 if err != nil { 34 return fmt.Errorf("unable to clean oci-tmp cache: %v", err) 35 } 36 37 return nil 38 } 39 40 func cleanBlobCache() error { 41 sylog.Debugf("Removing: %v", cache.OciBlob()) 42 43 err := os.RemoveAll(cache.OciBlob()) 44 if err != nil { 45 return fmt.Errorf("unable to clean oci-blob cache: %v", err) 46 } 47 48 return nil 49 50 } 51 52 // CleanCache : clean a type of cache (cacheType string). will return a error if one occurs. 53 func CleanCache(cacheType string) error { 54 switch cacheType { 55 case "library": 56 err := cleanLibraryCache() 57 return err 58 case "oci": 59 err := cleanOciCache() 60 return err 61 case "blob", "blobs": 62 err := cleanBlobCache() 63 return err 64 case "all": 65 err := cache.Clean() 66 return err 67 default: 68 sylog.Fatalf("Not a valid type: %v", cacheType) 69 os.Exit(2) 70 } 71 return nil 72 } 73 74 func cleanLibraryCacheName(cacheName string) (bool, error) { 75 foundMatch := false 76 libraryCacheFiles, err := ioutil.ReadDir(cache.Library()) 77 if err != nil { 78 return false, fmt.Errorf("unable to opening library cache folder: %v", err) 79 } 80 for _, f := range libraryCacheFiles { 81 cont, err := ioutil.ReadDir(filepath.Join(cache.Library(), f.Name())) 82 if err != nil { 83 return false, fmt.Errorf("unable to look in library cache folder: %v", err) 84 } 85 for _, c := range cont { 86 if c.Name() == cacheName { 87 sylog.Debugf("Removing: %v", filepath.Join(cache.Library(), f.Name(), c.Name())) 88 err = os.RemoveAll(filepath.Join(cache.Library(), f.Name(), c.Name())) 89 if err != nil { 90 return false, fmt.Errorf("unable to remove library cache: %v", err) 91 } 92 foundMatch = true 93 } 94 } 95 } 96 return foundMatch, nil 97 } 98 99 func cleanOciCacheName(cacheName string) (bool, error) { 100 foundMatch := false 101 blobs, err := ioutil.ReadDir(cache.OciTemp()) 102 if err != nil { 103 return false, fmt.Errorf("unable to opening oci-tmp cache folder: %v", err) 104 } 105 for _, f := range blobs { 106 blob, err := ioutil.ReadDir(filepath.Join(cache.OciTemp(), f.Name())) 107 if err != nil { 108 return false, fmt.Errorf("unable to look in oci-tmp cache folder: %v", err) 109 } 110 for _, b := range blob { 111 if b.Name() == cacheName { 112 sylog.Debugf("Removing: %v", filepath.Join(cache.OciTemp(), f.Name(), b.Name())) 113 err = os.RemoveAll(filepath.Join(cache.OciTemp(), f.Name(), b.Name())) 114 if err != nil { 115 return false, fmt.Errorf("unable to remove oci-tmp cache: %v", err) 116 } 117 foundMatch = true 118 } 119 } 120 } 121 return foundMatch, nil 122 } 123 124 // CleanCacheName : will clean a container with the same name as cacheName (in the cache directory). 125 // if libraryCache == true; only search thrught library cache. if ociCache == true; only search the 126 // oci-tmp cache. if both are false; search all cache, and if both are true; again, search all cache. 127 func CleanCacheName(cacheName string, libraryCache, ociCache bool) (bool, error) { 128 if libraryCache == ociCache { 129 matchLibrary, err := cleanLibraryCacheName(cacheName) 130 if err != nil { 131 return false, err 132 } 133 matchOci, err := cleanOciCacheName(cacheName) 134 if err != nil { 135 return false, err 136 } 137 if matchLibrary == true || matchOci == true { 138 return true, nil 139 } 140 return false, nil 141 } 142 143 match := false 144 if libraryCache == true { 145 match, err := cleanLibraryCacheName(cacheName) 146 if err != nil { 147 return false, err 148 } 149 return match, nil 150 } else if ociCache == true { 151 match, err := cleanOciCacheName(cacheName) 152 if err != nil { 153 return false, err 154 } 155 return match, nil 156 } 157 return match, nil 158 } 159 160 // CleanSingularityCache : the main function that drives all these other functions, if allClean == true; clean 161 // all cache. if typeNameClean contains somthing; only clean that type. if cacheName contains somthing; clean only 162 // cache with that name. 163 func CleanSingularityCache(cleanAll bool, cacheCleanTypes []string, cacheName string) error { 164 libraryClean := false 165 ociClean := false 166 blobClean := false 167 168 for _, t := range cacheCleanTypes { 169 switch t { 170 case "library": 171 libraryClean = true 172 case "oci": 173 ociClean = true 174 case "blob", "blobs": 175 blobClean = true 176 case "all": 177 cleanAll = true 178 default: 179 sylog.Fatalf("Not a valid type: %v", t) 180 os.Exit(2) 181 } 182 } 183 184 if len(cacheName) >= 1 && cleanAll != true { 185 foundMatch, err := CleanCacheName(cacheName, libraryClean, ociClean) 186 if err != nil { 187 return err 188 } 189 if foundMatch != true { 190 sylog.Warningf("No cache found with givin name: %v", cacheName) 191 os.Exit(0) 192 } 193 return nil 194 } 195 196 if cleanAll { 197 if err := CleanCache("all"); err != nil { 198 return err 199 } 200 } 201 202 if libraryClean { 203 if err := CleanCache("library"); err != nil { 204 return err 205 } 206 } 207 if ociClean { 208 if err := CleanCache("oci"); err != nil { 209 return err 210 } 211 } 212 if blobClean { 213 if err := CleanCache("blob"); err != nil { 214 return err 215 } 216 } 217 return nil 218 }