1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
// Copyright (c) 2018-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE.md file distributed with the sources of this project regarding your
// rights to use or distribute this software.
package singularity
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/sylabs/singularity/v4/internal/pkg/cache"
"github.com/sylabs/singularity/v4/internal/pkg/util/fs"
"github.com/sylabs/singularity/v4/pkg/util/slice"
)
// listTypeCache will list a cache type with given name (cacheType). The options are 'library', and 'oci'.
// Will return: the number of containers for that type (int), the total space the container type is using (int64),
// and an error if one occurs.
func listTypeCache(printList bool, name, cachePath string) (int, int64, error) {
_, err := os.Stat(cachePath)
if os.IsNotExist(err) {
return 0, 0, nil
} else if err != nil {
return 0, 0, fmt.Errorf("unable to open cache %s at directory %s: %v", name, cachePath, err)
}
cacheEntries, err := os.ReadDir(cachePath)
if err != nil {
return 0, 0, fmt.Errorf("unable to open cache %s at directory %s: %v", name, cachePath, err)
}
var totalSize int64
for _, entry := range cacheEntries {
fi, err := entry.Info()
if err != nil {
return 0, 0, fmt.Errorf("unable to get info for cache entry %s: %v", entry.Name(), err)
}
if printList {
fmt.Printf("%-24.22s %-22s %-16s %s\n",
entry.Name(),
fi.ModTime().Format("2006-01-02 15:04:05"),
fs.FindSize(fi.Size()),
name)
}
totalSize += fi.Size()
}
return len(cacheEntries), totalSize, nil
}
// ListSingularityCache will list the local singularity cache for the
// types specified by cacheListTypes. If cacheListTypes contains the
// value "all", all the cache entries are considered. If cacheListVerbose is
// true, the entries will be shown in the output, otherwise only a
// summary is provided.
func ListSingularityCache(imgCache *cache.Handle, cacheListTypes []string, cacheListVerbose bool) error {
if imgCache == nil {
return errInvalidCacheHandle
}
var (
containerCount, blobCount int
containerSpace, blobSpace, totalSpace int64
)
if cacheListVerbose {
fmt.Printf("%-24s %-22s %-16s %s\n", "NAME", "DATE CREATED", "SIZE", "TYPE")
}
containersShown := false
blobsShown := false
// If types requested includes "all" then we don't want to filter anything
if slice.ContainsString(cacheListTypes, "all") {
cacheListTypes = []string{}
}
for _, cacheType := range cache.OciCacheTypes {
// the type blob is special: 1. there's a
// separate counter for it; 2. the cache entries
// are actually one level deeper
if len(cacheListTypes) > 0 && !slice.ContainsString(cacheListTypes, cacheType) {
continue
}
cacheDir, err := imgCache.GetOciCacheDir(cacheType)
if err != nil {
return err
}
cacheDir = filepath.Join(cacheDir, "blobs", "sha256")
blobsCount, blobsSize, err := listTypeCache(cacheListVerbose, cacheType, cacheDir)
if err != nil {
fmt.Print(err)
return err
}
blobCount = blobsCount
blobSpace = blobsSize
totalSpace += blobsSize
blobsShown = true
}
for _, cacheType := range cache.FileCacheTypes {
if len(cacheListTypes) > 0 && !slice.ContainsString(cacheListTypes, cacheType) {
continue
}
cacheDir, err := imgCache.GetFileCacheDir(cacheType)
if err != nil {
return err
}
count, size, err := listTypeCache(cacheListVerbose, cacheType, cacheDir)
if err != nil {
fmt.Print(err)
return err
}
containerCount += count
containerSpace += size
totalSpace += size
containersShown = true
}
if cacheListVerbose {
fmt.Print("\n")
}
out := new(strings.Builder)
out.WriteString("There are")
if containersShown {
fmt.Fprintf(out, " %d container file(s) using %s", containerCount, fs.FindSize(containerSpace))
}
if containersShown && blobsShown {
fmt.Fprintf(out, " and")
}
if blobsShown {
fmt.Fprintf(out, " %d oci blob file(s) using %s", blobCount, fs.FindSize(blobSpace))
}
out.WriteString(" of space\n")
fmt.Print(out.String())
fmt.Printf("Total space used: %s\n", fs.FindSize(totalSpace))
return nil
}
|