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  }