Skip to content

Commit

Permalink
Delete paths to cached images
Browse files Browse the repository at this point in the history
  • Loading branch information
Priya Wadhwa committed Nov 21, 2017
1 parent 9f8ca74 commit 6652e7a
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 129 deletions.
83 changes: 14 additions & 69 deletions cmd/minikube/cmd/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@ import (
"fmt"
"github.com/spf13/cobra"
cmdConfig "k8s.io/minikube/cmd/minikube/cmd/config"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/sshutil"
"os"
)

Expand All @@ -42,14 +40,12 @@ var addCacheCmd = &cobra.Command{
Long: "Add an image to local cache.",
Run: func(cmd *cobra.Command, args []string) {
// Cache and load images into docker daemon
err := cacheAndLoadImages(args)
if err != nil {
if err := machine.CacheAndLoadImages(args); err != nil {
fmt.Fprintf(os.Stderr, "Error caching and loading images: %s\n", err)
os.Exit(1)
}
// Add images to config file
err = cmdConfig.AddToConfigArray("cache", args)
if err != nil {
if err := cmdConfig.AddToConfigMap(constants.Cache, args); err != nil {
fmt.Fprintf(os.Stderr, "Error adding cached images to config file: %s\n", err)
os.Exit(1)
}
Expand All @@ -62,25 +58,16 @@ var deleteCacheCmd = &cobra.Command{
Short: "Delete an image from the local cache.",
Long: "Delete an image from the local cache.",
Run: func(cmd *cobra.Command, args []string) {

cmdRunner, err := getCommandRunner()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting command runner: %s\n", err)
// Delete images from config file
if err := cmdConfig.DeleteFromConfigMap(constants.Cache, args); err != nil {
fmt.Fprintf(os.Stderr, "Error deleting images from config file: %s\n", err)
os.Exit(1)
}
// Delete images from docker daemon
err = machine.DeleteImages(cmdRunner, args)
if err != nil {
// Delete images from cache/images directory
if err := machine.DeleteFromImageCacheDir(args); err != nil {
fmt.Fprintf(os.Stderr, "Error deleting images: %s\n", err)
os.Exit(1)
}
// Delete images from config file
err = cmdConfig.DeleteFromConfigArray("cache", args)
if err != nil {
fmt.Fprintf(os.Stderr, "Error deleting images from config file: %s\n", err)
os.Exit(1)
}

},
}

Expand All @@ -90,56 +77,14 @@ func LoadCachedImagesInConfigFile() error {
if err != nil {
return err
}

values := configFile["cache"]

if values == nil {
return nil
}

var images []string

for _, v := range values.([]interface{}) {
images = append(images, v.(string))
}

return cacheAndLoadImages(images)

}

func cacheAndLoadImages(images []string) error {

err := machine.CacheImages(images, constants.ImageCacheDir)
if err != nil {
return err
}

cmdRunner, err := getCommandRunner()
if err != nil {
return err
}

return machine.LoadImages(cmdRunner, images, constants.ImageCacheDir)

}

func getCommandRunner() (*bootstrapper.SSHRunner, error) {
api, err := machine.NewAPIClient()
if err != nil {
return nil, err
}
defer api.Close()
h, err := api.Load(config.GetMachineName())
if err != nil {
return nil, err
}

client, err := sshutil.NewSSHClient(h.Driver)
if err != nil {
return nil, err
if values, ok := configFile[constants.Cache]; ok {
var images []string
for key := range values.(map[string]interface{}) {
images = append(images, key)
}
return machine.CacheAndLoadImages(images)
}
return bootstrapper.NewSSHRunner(client), nil

return nil
}

func init() {
Expand Down
61 changes: 20 additions & 41 deletions cmd/minikube/cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type setFn func(string, string) error
type Setting struct {
name string
set func(config.MinikubeConfig, string, string) error
setArray func(config.MinikubeConfig, string, []string) error
setMap func(config.MinikubeConfig, string, map[string]interface{}) error
validations []setFn
callbacks []setFn
}
Expand Down Expand Up @@ -195,8 +195,8 @@ var settings = []Setting{
set: SetBool,
},
{
name: "cache",
setArray: SetStringArray,
name: "cache",
setMap: SetMap,
},
}

Expand All @@ -218,38 +218,35 @@ func configurableFields() string {
return strings.Join(fields, "\n")
}

// AddToConfigArray adds entries to an array in the config file
func AddToConfigArray(name string, images []string) error {
// AddToConfigMap adds entries to a map in the config file
func AddToConfigMap(name string, images []string) error {
s, err := findSetting(name)
if err != nil {
return err
}

// Set the values
configFile, err := config.ReadConfig()
if err != nil {
return err
}
values := configFile[name]

// Add images to currently existing values in config file
if values != nil {
for _, v := range values.([]interface{}) {
images = append(images, v.(string))
newImages := make(map[string]interface{})
for _, image := range images {
newImages[image] = nil
}
if values, ok := configFile[name].(map[string]interface{}); ok {
for key := range values {
newImages[key] = nil
}
}

err = s.setArray(configFile, name, images)
if err != nil {
if err = s.setMap(configFile, name, newImages); err != nil {
return err
}

// Write the values
return WriteConfig(configFile)
}

// DeleteFromConfigArray deletes entries in an array in the config file
func DeleteFromConfigArray(name string, images []string) error {
// DeleteFromConfigMap deletes entries from a map in the config file
func DeleteFromConfigMap(name string, images []string) error {
s, err := findSetting(name)
if err != nil {
return err
Expand All @@ -259,34 +256,16 @@ func DeleteFromConfigArray(name string, images []string) error {
if err != nil {
return err
}
values := configFile[name]
if values == nil {
values, ok := configFile[name]
if !ok {
return nil
}
var finalImages []string

if values != nil {
// Add images that are in config file but not in images to finalImages
// These are the images that should remain in the config file after deletion
for _, v := range values.([]interface{}) {
addImage := true
for _, image := range images {
if v.(string) == image {
addImage = false
}
}
if addImage {
finalImages = append(finalImages, v.(string))
}

}
for _, image := range images {
delete(values.(map[string]interface{}), image)
}

err = s.setArray(configFile, name, finalImages)
if err != nil {
if err = s.setMap(configFile, name, values.(map[string]interface{})); err != nil {
return err
}

// Write the values
return WriteConfig(configFile)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/minikube/cmd/config/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func SetString(m config.MinikubeConfig, name string, val string) error {
return nil
}

func SetStringArray(m config.MinikubeConfig, name string, val []string) error {
func SetMap(m config.MinikubeConfig, name string, val map[string]interface{}) error {
m[name] = val
return nil
}
Expand Down
1 change: 0 additions & 1 deletion cmd/minikube/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_
if err != nil {
fmt.Println("Unable to load cached images from config file.")
}

}

func validateK8sVersion(version string) {
Expand Down
3 changes: 3 additions & 0 deletions pkg/minikube/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ const DefaultMachineName = "minikube"
// The name of the default storage class provisioner
const DefaultStorageClassProvisioner = "standard"

// Used to modify the cache field in the config file
const Cache = "cache"

// MakeMiniPath is a utility to calculate a relative path to our directory.
func MakeMiniPath(fileName ...string) string {
args := []string{GetMinipath()}
Expand Down
78 changes: 61 additions & 17 deletions pkg/minikube/machine/cache_images.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import (

"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/sshutil"

"github.com/containers/image/copy"
"github.com/containers/image/docker"
Expand Down Expand Up @@ -97,25 +99,30 @@ func LoadImages(cmd bootstrapper.CommandRunner, images []string, cacheDir string
return nil
}

// DeleteImages deletes images from local daemon
func DeleteImages(cmd bootstrapper.CommandRunner, images []string) error {
var g errgroup.Group
for _, image := range images {
image := image
g.Go(func() error {
dockerDeleteCmd := "docker rmi " + image
if err := cmd.Run(dockerDeleteCmd); err != nil {
return errors.Wrapf(err, "deleting docker image: %s", image)
}
return nil
})
func CacheAndLoadImages(images []string) error {
if err := CacheImages(images, constants.ImageCacheDir); err != nil {
return err
}
if err := g.Wait(); err != nil {
return errors.Wrap(err, "deleting cached images")
api, err := NewAPIClient()
if err != nil {
return err
}
defer api.Close()
h, err := api.Load(config.GetMachineName())
if err != nil {
return err
}

client, err := sshutil.NewSSHClient(h.Driver)
if err != nil {
return err
}
cmdRunner, err := bootstrapper.NewSSHRunner(client), nil
if err != nil {
return err
}
glog.Infoln("Successfully deleted cached images.")
return nil

return LoadImages(cmdRunner, images, constants.ImageCacheDir)
}

// # ParseReference cannot have a : in the directory path
Expand Down Expand Up @@ -205,14 +212,51 @@ func LoadFromCacheBlocking(cmd bootstrapper.CommandRunner, src string) error {
return errors.Wrapf(err, "loading docker image: %s", dst)
}

if err := cmd.Run("sudo rm -rf " + dst); err != nil {
if err := cmd.Run("rm -rf " + dst); err != nil {
return errors.Wrap(err, "deleting temp docker image location")
}

glog.Infof("Successfully loaded image %s from cache", src)
return nil
}

func DeleteFromImageCacheDir(images []string) error {
for _, image := range images {
path := filepath.Join(constants.ImageCacheDir, image)
glog.Infoln("Deleting image in cache at ", path)
if err := os.Remove(path); err != nil {
return err
}
}
return cleanImageCacheDir()
}

func cleanImageCacheDir() error {
err := filepath.Walk(constants.ImageCacheDir, func(path string, info os.FileInfo, err error) error {
// If error is not nil, it's because the path was already deleted and doesn't exist
// Move on to next path
if err != nil {
return nil
}
// Check if path is directory
if !info.IsDir() {
return nil
}
// If directory is empty, delete it
entries, err := ioutil.ReadDir(path)
if err != nil {
return err
}
if len(entries) == 0 {
if err = os.Remove(path); err != nil {
return err
}
}
return nil
})
return err
}

func getSrcRef(image string) (types.ImageReference, error) {
srcRef, err := docker.ParseReference("//" + image)
if err != nil {
Expand Down

0 comments on commit 6652e7a

Please sign in to comment.