func (daemon *Daemon) ImageGetCached(imgID string, config *runconfig.Config) (*image.Image, error) { // Retrieve all images images := daemon.Graph().Map() // Store the tree in a map of map (map[parentId][childId]) imageMap := make(map[string]map[string]struct{}) for _, img := range images { if _, exists := imageMap[img.Parent]; !exists { imageMap[img.Parent] = make(map[string]struct{}) } imageMap[img.Parent][img.ID] = struct{}{} } // Loop on the children of the given image and check the config var match *image.Image for elem := range imageMap[imgID] { img, ok := images[elem] if !ok { return nil, fmt.Errorf("unable to find image %q", elem) } if runconfig.Compare(&img.ContainerConfig, config) { if match == nil || match.Created.Before(img.Created) { match = img } } } return match, nil }
// ImageGetCached returns the earliest created image that is a child // of the image with imgID, that had the same config when it was // created. nil is returned if a child cannot be found. An error is // returned if the parent image cannot be found. func (daemon *Daemon) ImageGetCached(imgID image.ID, config *runconfig.Config) (*image.Image, error) { // Retrieve all images imgs := daemon.Map() var siblings []image.ID for id, img := range imgs { if img.Parent == imgID { siblings = append(siblings, id) } } // Loop on the children of the given image and check the config var match *image.Image for _, id := range siblings { img, ok := imgs[id] if !ok { return nil, fmt.Errorf("unable to find image %q", id) } if runconfig.Compare(&img.ContainerConfig, config) { if match == nil || match.Created.Before(img.Created) { match = img } } } return match, nil }
// GetCachedImage returns the most recent created image that is a child // of the image with imgID, that had the same config when it was // created. nil is returned if a child cannot be found. An error is // returned if the parent image cannot be found. func (daemon *Daemon) GetCachedImage(imgID image.ID, config *containertypes.Config) (*image.Image, error) { // Loop on the children of the given image and check the config getMatch := func(siblings []image.ID) (*image.Image, error) { var match *image.Image for _, id := range siblings { img, err := daemon.imageStore.Get(id) if err != nil { return nil, fmt.Errorf("unable to find image %q", id) } if runconfig.Compare(&img.ContainerConfig, config) { // check for the most up to date match if match == nil || match.Created.Before(img.Created) { match = img } } } return match, nil } // In this case, this is `FROM scratch`, which isn't an actual image. if imgID == "" { images := daemon.imageStore.Map() var siblings []image.ID for id, img := range images { if img.Parent == imgID { siblings = append(siblings, id) } } return getMatch(siblings) } // find match from child images siblings := daemon.imageStore.Children(imgID) return getMatch(siblings) }
// ImageGetCached returns the earliest created image that is a child // of the image with imgID, that had the same config when it was // created. nil is returned if a child cannot be found. An error is // returned if the parent image cannot be found. func (daemon *Daemon) ImageGetCached(imgID string, config *runconfig.Config) (*image.Image, error) { // for now just exit if imgID has no children. // maybe parentRefs in graph could be used to store // the Image obj children for faster lookup below but this can // be quite memory hungry. if !daemon.Graph().HasChildren(imgID) { return nil, nil } // Retrieve all images images := daemon.Graph().Map() // Store the tree in a map of map (map[parentId][childId]) imageMap := make(map[string]map[string]struct{}) for _, img := range images { if _, exists := imageMap[img.Parent]; !exists { imageMap[img.Parent] = make(map[string]struct{}) } imageMap[img.Parent][img.ID] = struct{}{} } // Loop on the children of the given image and check the config var match *image.Image for elem := range imageMap[imgID] { img, ok := images[elem] if !ok { return nil, fmt.Errorf("unable to find image %q", elem) } if runconfig.Compare(&img.ContainerConfig, config) { if match == nil || match.Created.Before(img.Created) { match = img } } } return match, nil }