Skip loading image if already cached based on sha

pull/5987/head
Medya Gh 2019-12-09 14:30:55 -08:00
parent d7b6e66038
commit 2895971182
5 changed files with 72 additions and 11 deletions

View File

@ -221,6 +221,15 @@ func (r *Containerd) Disable() error {
return nil
}
// ImageExists checks if an image exists, expected input format
func (r *Containerd) ImageExists(name string, sha string) bool {
c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ctr -n=k8s.io images check | grep %s | grep %s", name, sha))
if _, err := r.Runner.RunCmd(c); err != nil {
return false
}
return true
}
// LoadImage loads an image into this runtime
func (r *Containerd) LoadImage(path string) error {
glog.Infof("Loading image: %s", path)

View File

@ -119,6 +119,20 @@ func (r *CRIO) Disable() error {
return nil
}
// ImageExists checks if an image exists
func (r *CRIO) ImageExists(name string, sha string) bool {
// expected output looks like [NAME@sha256:SHA]
c := exec.Command("sudo", "podman", "inspect", "--format='{{.Id}}'", name)
rr, err := r.Runner.RunCmd(c)
if err != nil {
return false
}
if !strings.Contains(rr.Output(), sha) {
return false
}
return true
}
// LoadImage loads an image into this runtime
func (r *CRIO) LoadImage(path string) error {
glog.Infof("Loading image: %s", path)

View File

@ -59,6 +59,9 @@ type Manager interface {
// Load an image idempotently into the runtime on a host
LoadImage(string) error
// ImageExists takes image name and image sha checks if an it exists
ImageExists(string, string) bool
// ListContainers returns a list of managed by this container runtime
ListContainers(string) ([]string, error)
// KillContainers removes containers based on ID

View File

@ -102,6 +102,20 @@ func (r *Docker) Disable() error {
return nil
}
// ImageExists checks if an image exists
func (r *Docker) ImageExists(name string, sha string) bool {
// expected output looks like [SHA_ALGO:SHA]
c := exec.Command("docker", "inspect", "--format='{{.Id}}'", name)
rr, err := r.Runner.RunCmd(c)
if err != nil {
return false
}
if !strings.Contains(rr.Output(), sha) {
return false
}
return true
}
// LoadImage loads an image into this runtime
func (r *Docker) LoadImage(path string) error {
glog.Infof("Loading image: %s", path)

View File

@ -94,18 +94,16 @@ func CacheImages(images []string, cacheDir string) error {
}
// LoadImages loads previously cached images into the container runtime
func LoadImages(cc *config.MachineConfig, cmd command.Runner, images []string, cacheDir string) error {
func LoadImages(cc *config.MachineConfig, runner command.Runner, images []string, cacheDir string) error {
glog.Infof("LoadImages start: %s", images)
defer glog.Infof("LoadImages end")
var g errgroup.Group
for _, image := range images {
image := image
g.Go(func() error {
src := filepath.Join(cacheDir, image)
src = sanitizeCacheDir(src)
if err := transferAndLoadImage(cmd, cc.KubernetesConfig, src); err != nil {
glog.Warningf("Failed to load %s: %v", src, err)
return errors.Wrapf(err, "loading image %s", src)
if err := transferAndLoadImage(runner, cc.KubernetesConfig, image, cacheDir); err != nil {
glog.Warningf("Failed to load %s: %v", image, err)
return errors.Wrapf(err, "loading image %s", image)
}
return nil
})
@ -225,7 +223,34 @@ func getWindowsVolumeNameCmd(d string) (string, error) {
}
// transferAndLoadImage transfers and loads a single image from the cache
func transferAndLoadImage(cr command.Runner, k8s config.KubernetesConfig, src string) error {
func transferAndLoadImage(cr command.Runner, k8s config.KubernetesConfig, imgName string, cacheDir string) error {
r, err := cruntime.New(cruntime.Config{Type: k8s.ContainerRuntime, Runner: cr})
if err != nil {
return errors.Wrap(err, "runtime")
}
ref, err := name.ParseReference(imgName, name.WeakValidation)
if err != nil {
return errors.Wrap(err, "image name reference")
}
img, err := retrieveImage(ref)
if err != nil {
return errors.Wrap(err, "fetching image")
}
m, err := img.Manifest() //image hash
if err != nil {
glog.Infof("error retrieving image manifest for %s to check if it already exists: %v", imgName, err)
} else {
hash := m.Config.Digest.Hex
if r.ImageExists(imgName, hash) {
glog.Infof("skipping re-loading image %q because sha %q already exists ", imgName, hash)
return nil
}
}
src := filepath.Join(cacheDir, imgName)
src = sanitizeCacheDir(src)
glog.Infof("Loading image from cache: %s", src)
filename := filepath.Base(src)
if _, err := os.Stat(src); err != nil {
@ -240,10 +265,6 @@ func transferAndLoadImage(cr command.Runner, k8s config.KubernetesConfig, src st
return errors.Wrap(err, "transferring cached image")
}
r, err := cruntime.New(cruntime.Config{Type: k8s.ContainerRuntime, Runner: cr})
if err != nil {
return errors.Wrap(err, "runtime")
}
loadImageLock.Lock()
defer loadImageLock.Unlock()