github.com/apptainer/singularity@v3.1.1+incompatible/internal/app/singularity/cache_list_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 "strings" 14 15 "github.com/sylabs/singularity/internal/pkg/client/cache" 16 "github.com/sylabs/singularity/internal/pkg/sylog" 17 ) 18 19 func findSize(size int64) (string, error) { 20 var sizeF float64 21 if size <= 1000000 { 22 sizeF = float64(size) / 1000 23 return strings.Join([]string{fmt.Sprintf("%.2f", sizeF), " Kb"}, ""), nil 24 } else if size <= 1000000000 { 25 sizeF = float64(size) / 1000000 26 return strings.Join([]string{fmt.Sprintf("%.2f", sizeF), " Mb"}, ""), nil 27 } else if size >= 1000000000 { 28 sizeF = float64(size) / 1000000000 29 return strings.Join([]string{fmt.Sprintf("%.2f", sizeF), " Gb"}, ""), nil 30 } 31 return "", fmt.Errorf("failed to detect file size") 32 } 33 34 func listLibraryCache() error { 35 // loop through library cache 36 libraryCacheFiles, err := ioutil.ReadDir(cache.Library()) 37 if err != nil { 38 return fmt.Errorf("unable to open library cache folder: %v", err) 39 } 40 for _, f := range libraryCacheFiles { 41 cont, err := ioutil.ReadDir(filepath.Join(cache.Library(), f.Name())) 42 if err != nil { 43 return fmt.Errorf("unable to look in library cache: %v", err) 44 } 45 for _, c := range cont { 46 fileInfo, err := os.Stat(filepath.Join(cache.Library(), f.Name(), c.Name())) 47 if err != nil { 48 return fmt.Errorf("unable to get stat for library cache: %v", err) 49 } 50 printFileSize, err := findSize(fileInfo.Size()) 51 if err != nil { 52 // no need to describe the error, since it is already 53 sylog.Warningf("%v", err) 54 } 55 fmt.Printf("%-22s %-22s %-16s %s\n", c.Name(), fileInfo.ModTime().Format("2006-01-02 15:04:05"), printFileSize, "library") 56 } 57 } 58 return nil 59 } 60 61 func listOciCache() error { 62 // loop through oci-tmp cache 63 ociTmp, err := ioutil.ReadDir(cache.OciTemp()) 64 if err != nil { 65 return fmt.Errorf("unable to open oci-tmp folder: %v", err) 66 } 67 for _, f := range ociTmp { 68 blob, err := ioutil.ReadDir(filepath.Join(cache.OciTemp(), f.Name())) 69 if err != nil { 70 return fmt.Errorf("unable to look in oci-tmp cache: %v", err) 71 } 72 for _, b := range blob { 73 fileInfo, err := os.Stat(filepath.Join(cache.OciTemp(), f.Name(), b.Name())) 74 if err != nil { 75 return fmt.Errorf("unable to get stat for oci-tmp cache: %v", err) 76 } 77 printFileSize, err := findSize(fileInfo.Size()) 78 if err != nil { 79 // no need to describe the error, since it is already 80 sylog.Warningf("%v", err) 81 } 82 fmt.Printf("%-22s %-22s %-16s %s\n", b.Name(), fileInfo.ModTime().Format("2006-01-02 15:04:05"), printFileSize, "oci") 83 } 84 } 85 return nil 86 } 87 88 func listBlobCache(printList bool) error { 89 // loop through ociBlob cache 90 count := 0 91 var totalSize int64 92 93 _, err := os.Stat(filepath.Join(cache.OciBlob(), "/blobs")) 94 if os.IsNotExist(err) { 95 return nil 96 } 97 blobs, err := ioutil.ReadDir(filepath.Join(cache.OciBlob(), "/blobs/")) 98 if err != nil { 99 return fmt.Errorf("unable to open oci-blob folder: %v", err) 100 } 101 for _, f := range blobs { 102 blob, err := ioutil.ReadDir(filepath.Join(cache.OciBlob(), "/blobs/", f.Name())) 103 if err != nil { 104 return fmt.Errorf("unable to look in oci-blob cache: %v", err) 105 } 106 for _, b := range blob { 107 fileInfo, err := os.Stat(filepath.Join(cache.OciBlob(), "/blobs/", f.Name(), b.Name())) 108 if err != nil { 109 return fmt.Errorf("unable to get stat for oci-blob cache: %v", err) 110 } 111 if printList == true { 112 printFileSize, err := findSize(fileInfo.Size()) 113 if err != nil { 114 // no need to describe the error, since it is already 115 sylog.Warningf("%v", err) 116 } 117 fmt.Printf("%-22.20s %-22s %-16s %s\n", b.Name(), fileInfo.ModTime().Format("2006-01-02 15:04:05"), printFileSize, "blob") 118 } 119 count++ 120 totalSize += fileInfo.Size() 121 } 122 } 123 if printList != true && count >= 1 { 124 printFileSize, err := findSize(totalSize) 125 if err != nil { 126 // no need to describe the error, since it is already 127 sylog.Warningf("%v", err) 128 } 129 fmt.Printf("\nThere are %d oci blob file(s) using %v of space. Use: '-T=blob' to list\n", count, printFileSize) 130 } 131 return nil 132 } 133 134 // ListSingularityCache : list local singularity cache, typeNameList : is a string of what cache 135 // to list (seprate each type with a comma; like this: library,oci,blob) allList : force list all cache. 136 func ListSingularityCache(cacheListTypes []string, listAll bool) error { 137 libraryList := false 138 ociList := false 139 blobList := false 140 listBlobSum := false 141 142 for _, t := range cacheListTypes { 143 switch t { 144 case "library": 145 libraryList = true 146 case "oci": 147 ociList = true 148 case "blob", "blobs": 149 blobList = true 150 case "blobSum": 151 listBlobSum = true 152 case "all": 153 listAll = true 154 default: 155 sylog.Fatalf("Not a valid type: %v", t) 156 os.Exit(2) 157 } 158 } 159 160 fmt.Printf("%-22s %-22s %-16s %s\n", "NAME", "DATE CREATED", "SIZE", "TYPE") 161 162 if libraryList || listAll { 163 if err := listLibraryCache(); err != nil { 164 return err 165 } 166 } 167 if ociList || listAll { 168 if err := listOciCache(); err != nil { 169 return err 170 } 171 } 172 if blobList || listAll { 173 if err := listBlobCache(true); err != nil { 174 return err 175 } 176 // dont list blob summary after listing all blobs 177 listBlobSum = false 178 } 179 if listBlobSum { 180 if err := listBlobCache(false); err != nil { 181 return err 182 } 183 } 184 return nil 185 }