Skip loading image if already cached based on sha
parent
d7b6e66038
commit
2895971182
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in New Issue