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  }