File: cache_list_linux.go

package info (click to toggle)
singularity-container 4.0.3%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 21,672 kB
  • sloc: asm: 3,857; sh: 2,125; ansic: 1,677; awk: 414; makefile: 110; python: 99
file content (145 lines) | stat: -rw-r--r-- 4,188 bytes parent folder | download | duplicates (2)
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
}