Merge branch 'cache-images' of github.com:priyawadhwa/minikube into cache-images
commit
9f8ca7481c
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue