Merge branch 'cache-images' of github.com:priyawadhwa/minikube into cache-images

pull/2203/head
Priya Wadhwa 2017-11-16 14:11:56 -08:00
commit 9f8ca7481c
No known key found for this signature in database
GPG Key ID: 0D0DAFD8F7AA73AE
5 changed files with 262 additions and 3 deletions

149
cmd/minikube/cmd/cache.go Normal file
View File

@ -0,0 +1,149 @@
/*
Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
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"
)
// cacheCmd represents the cache command
var cacheCmd = &cobra.Command{
Use: "cache",
Short: "Add or delete an image from the local cache.",
Long: "Add or delete an image from the local cache.",
}
// addCacheCmd represents the cache add command
var addCacheCmd = &cobra.Command{
Use: "add",
Short: "Add an image to local cache.",
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 {
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 {
fmt.Fprintf(os.Stderr, "Error adding cached images to config file: %s\n", err)
os.Exit(1)
}
},
}
// deleteCacheCmd represents the cache delete command
var deleteCacheCmd = &cobra.Command{
Use: "delete",
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)
os.Exit(1)
}
// Delete images from docker daemon
err = machine.DeleteImages(cmdRunner, args)
if 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)
}
},
}
// LoadCachedImagesInConfigFile loads the images currently in the config file (minikube start)
func LoadCachedImagesInConfigFile() error {
configFile, err := config.ReadConfig()
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
}
return bootstrapper.NewSSHRunner(client), nil
}
func init() {
cacheCmd.AddCommand(addCacheCmd)
cacheCmd.AddCommand(deleteCacheCmd)
RootCmd.AddCommand(cacheCmd)
}

View File

@ -36,6 +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
validations []setFn
callbacks []setFn
}
@ -193,6 +194,10 @@ var settings = []Setting{
name: "disable-driver-mounts",
set: SetBool,
},
{
name: "cache",
setArray: SetStringArray,
},
}
var ConfigCmd = &cobra.Command{
@ -213,6 +218,79 @@ 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 {
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))
}
}
err = s.setArray(configFile, name, images)
if 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 {
s, err := findSetting(name)
if err != nil {
return err
}
// Set the values
configFile, err := config.ReadConfig()
if err != nil {
return err
}
values := configFile[name]
if values == nil {
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))
}
}
}
err = s.setArray(configFile, name, finalImages)
if err != nil {
return err
}
// Write the values
return WriteConfig(configFile)
}
// WriteConfig writes a minikube config to the JSON file
func WriteConfig(m config.MinikubeConfig) error {
f, err := os.Create(constants.ConfigFile)

View File

@ -60,6 +60,11 @@ func SetString(m config.MinikubeConfig, name string, val string) error {
return nil
}
func SetStringArray(m config.MinikubeConfig, name string, val []string) error {
m[name] = val
return nil
}
func SetInt(m config.MinikubeConfig, name string, val string) error {
i, err := strconv.Atoi(val)
if err != nil {

View File

@ -332,6 +332,13 @@ This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_
cmdutil.MaybeReportErrorAndExit(err)
}
}
fmt.Println("Loading cached images from config file.")
err = LoadCachedImagesInConfigFile()
if err != nil {
fmt.Println("Unable to load cached images from config file.")
}
}
func validateK8sVersion(version string) {

View File

@ -17,6 +17,7 @@ limitations under the License.
package machine
import (
"golang.org/x/sync/errgroup"
"io/ioutil"
"os"
"os/exec"
@ -24,8 +25,6 @@ import (
"runtime"
"strings"
"golang.org/x/sync/errgroup"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/constants"
@ -98,6 +97,27 @@ 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
})
}
if err := g.Wait(); err != nil {
return errors.Wrap(err, "deleting cached images")
}
glog.Infoln("Successfully deleted cached images.")
return nil
}
// # ParseReference cannot have a : in the directory path
func sanitizeCacheDir(image string) string {
if runtime.GOOS == "windows" && hasWindowsDriveLetter(image) {
@ -185,7 +205,7 @@ func LoadFromCacheBlocking(cmd bootstrapper.CommandRunner, src string) error {
return errors.Wrapf(err, "loading docker image: %s", dst)
}
if err := cmd.Run("rm -rf " + dst); err != nil {
if err := cmd.Run("sudo rm -rf " + dst); err != nil {
return errors.Wrap(err, "deleting temp docker image location")
}