// ListImages lists the images from given image store func ListImages(storename string, images []*ImageWithMeta) (map[string]*models.Image, error) { defer trace.End(trace.Begin(storename)) transport := httptransport.New(options.host, "/", []string{"http"}) client := apiclient.New(transport, nil) ids := make([]string, len(images)) for i := range images { ids = append(ids, images[i].ID) } imageList, err := client.Storage.ListImages( storage.NewListImagesParams().WithStoreName(storename).WithIds(ids), ) if err != nil { return nil, err } existingImages := make(map[string]*models.Image) for i := range imageList.Payload { v := imageList.Payload[i] existingImages[v.ID] = v } return existingImages, nil }
// Update adds new images to the cache func (c *ImageCache) Update(client *client.PortLayer) error { c.m.Lock() defer c.m.Unlock() CacheNotUpdated = true log.Debugf("Updating image cache...") host, err := guest.UUID() if host == "" { host, err = os.Hostname() } if err != nil { return fmt.Errorf("Unexpected error getting hostname: %s", err) } // attempt to create the image store if it doesn't exist store := &models.ImageStore{Name: host} _, err = client.Storage.CreateImageStore( storage.NewCreateImageStoreParams().WithBody(store), ) if err != nil { if _, ok := err.(*storage.CreateImageStoreConflict); ok { log.Debugf("Store already exists") } else { log.Debugf("Creating a store failed: %#v", err) return err } } params := storage.NewListImagesParams().WithStoreName(host) layers, err := client.Storage.ListImages(params) if err != nil { return fmt.Errorf("Failed to retrieve image list from portlayer: %s", err) } for _, layer := range layers.Payload { imageConfig := &metadata.ImageConfig{} if err := json.Unmarshal([]byte(layer.Metadata["metaData"]), imageConfig); err != nil { derr.NewErrorWithStatusCode(fmt.Errorf("Failed to unmarshal image config: %s", err), http.StatusInternalServerError) } if imageConfig.ImageID != "" { var imageID string // Don't assume the image id in image has "sha256:<id> as format. We store it in // this fomat to make it easier to lookup by digest if strings.HasPrefix(imageConfig.ImageID, "sha") { imageID = imageConfig.ImageID } else { imageID = "sha256:" + imageConfig.ImageID } c.cacheByID[imageID] = imageConfig // Normalize the name stored in imageConfig using Docker's reference code ref, err := reference.WithName(imageConfig.Name) if err != nil { log.Errorf("Tried to create reference from %s: %s", imageConfig.Name, err.Error()) continue } for id := range imageConfig.Tags { tag := imageConfig.Tags[id] ref, err = reference.WithTag(ref, tag) if err != nil { log.Errorf("Tried to create tagged reference from %s and tag %s: %s", imageConfig.Name, tag, err.Error()) continue } if tagged, ok := ref.(reference.NamedTagged); ok { taggedName := fmt.Sprintf("%s:%s", tagged.Name(), tagged.Tag()) c.cacheByName[taggedName] = imageConfig } else { c.cacheByName[ref.Name()] = imageConfig } } } } CacheNotUpdated = false return nil }