Implement minikube image load command
parent
0509fd8413
commit
0a0f39a112
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"k8s.io/minikube/pkg/minikube/config"
|
||||||
|
"k8s.io/minikube/pkg/minikube/exit"
|
||||||
|
"k8s.io/minikube/pkg/minikube/machine"
|
||||||
|
"k8s.io/minikube/pkg/minikube/reason"
|
||||||
|
)
|
||||||
|
|
||||||
|
// imageCmd represents the image command
|
||||||
|
var imageCmd = &cobra.Command{
|
||||||
|
Use: "image",
|
||||||
|
Short: "Load a local image into minikube",
|
||||||
|
Long: "Load a local image into minikube",
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadImageCmd represents the image load command
|
||||||
|
var loadImageCmd = &cobra.Command{
|
||||||
|
Use: "load",
|
||||||
|
Short: "Load a local image into minikube",
|
||||||
|
Long: "Load a local image into minikube",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
exit.Message(reason.Usage, "Please provide an image in your local daemon or a path to an image tarball to load into minikube via <minikube image load IMAGE_NAME>")
|
||||||
|
}
|
||||||
|
// Cache and load images into docker daemon
|
||||||
|
profile := viper.GetString(config.ProfileName)
|
||||||
|
img := args[0]
|
||||||
|
if err := machine.LoadImage(profile, img); err != nil {
|
||||||
|
exit.Error(reason.InternalCacheLoad, "Failed to cache and load images", err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
imageCmd.AddCommand(loadImageCmd)
|
||||||
|
}
|
|
@ -201,6 +201,7 @@ func init() {
|
||||||
dockerEnvCmd,
|
dockerEnvCmd,
|
||||||
podmanEnvCmd,
|
podmanEnvCmd,
|
||||||
cacheCmd,
|
cacheCmd,
|
||||||
|
imageCmd,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,6 +123,27 @@ func LoadFromTarball(binary, img string) error {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SaveToTarball saves img as a tarball at the given path
|
||||||
|
func SaveToTarball(img, path string) error {
|
||||||
|
if !ExistsImageInDaemon(img) {
|
||||||
|
return fmt.Errorf("%s does not exist in local daemon, can't save to tarball", img)
|
||||||
|
}
|
||||||
|
ref, err := name.ParseReference(img)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "parsing reference")
|
||||||
|
}
|
||||||
|
i, err := daemon.Image(ref)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "getting image")
|
||||||
|
}
|
||||||
|
f, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "creating tmp path")
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
return tarball.Write(ref, i, f)
|
||||||
|
}
|
||||||
|
|
||||||
// Tag returns just the image with the tag
|
// Tag returns just the image with the tag
|
||||||
// eg image:tag@sha256:digest -> image:tag if there is an associated tag
|
// eg image:tag@sha256:digest -> image:tag if there is an associated tag
|
||||||
// if not possible, just return the initial img
|
// if not possible, just return the initial img
|
||||||
|
|
|
@ -18,7 +18,9 @@ package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -61,6 +63,74 @@ func CacheImagesForBootstrapper(imageRepository string, version string, clusterB
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadImage loads the local image into the container runtime
|
||||||
|
func LoadImage(profile, img string) error {
|
||||||
|
cc, err := config.Load(profile)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "loading profile")
|
||||||
|
}
|
||||||
|
// if the image exists in the local daemon, save it as a tarball
|
||||||
|
if image.ExistsImageInDaemon(img) {
|
||||||
|
tmpFile, err := ioutil.TempFile("", "")
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "temp file")
|
||||||
|
}
|
||||||
|
tmpFile.Close()
|
||||||
|
defer os.Remove(tmpFile.Name())
|
||||||
|
img = tmpFile.Name()
|
||||||
|
}
|
||||||
|
dst := "/tmp/img.tar"
|
||||||
|
if err := copyAndLoadTarballIntoHost(cc, img, dst, profile); err != nil {
|
||||||
|
return errors.Wrap(err, "copying tarball into host")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyAndLoadTarballIntoHost(cc *config.ClusterConfig, srcPath, dstPath, profile string) error {
|
||||||
|
c, err := config.Load(profile)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "loading profile config")
|
||||||
|
}
|
||||||
|
api, err := NewAPIClient()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "api")
|
||||||
|
}
|
||||||
|
defer api.Close()
|
||||||
|
for _, n := range c.Nodes {
|
||||||
|
m := config.MachineName(*c, n)
|
||||||
|
h, err := api.Load(m)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "loading api")
|
||||||
|
}
|
||||||
|
cr, err := CommandRunner(h)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "command runner")
|
||||||
|
}
|
||||||
|
tarballImg, err := assets.NewFileAsset(srcPath, filepath.Dir(dstPath), filepath.Base(dstPath), "0644")
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "new file asset")
|
||||||
|
}
|
||||||
|
// copy tarball into minikube
|
||||||
|
|
||||||
|
if err := cr.Copy(tarballImg); err != nil {
|
||||||
|
return errors.Wrap(err, "copying tarball")
|
||||||
|
}
|
||||||
|
// load image into container runtime
|
||||||
|
containerRuntime, err := cruntime.New(cruntime.Config{Type: cc.KubernetesConfig.ContainerRuntime, Runner: cr})
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "runtime")
|
||||||
|
}
|
||||||
|
if err := containerRuntime.LoadImage(dstPath); err != nil {
|
||||||
|
return errors.Wrap(err, "loading image into container runtime")
|
||||||
|
}
|
||||||
|
// delete destination image tarball on host
|
||||||
|
if _, err := cr.RunCmd(exec.Command("rm", dstPath)); err != nil {
|
||||||
|
return errors.Wrap(err, "removing destination tarball")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// LoadImages loads previously cached images into the container runtime
|
// LoadImages loads previously cached images into the container runtime
|
||||||
func LoadImages(cc *config.ClusterConfig, runner command.Runner, images []string, cacheDir string) error {
|
func LoadImages(cc *config.ClusterConfig, runner command.Runner, images []string, cacheDir string) error {
|
||||||
cr, err := cruntime.New(cruntime.Config{Type: cc.KubernetesConfig.ContainerRuntime, Runner: runner})
|
cr, err := cruntime.New(cruntime.Config{Type: cc.KubernetesConfig.ContainerRuntime, Runner: runner})
|
||||||
|
|
Loading…
Reference in New Issue