func newContentAddressableImage(v1Compatibility []byte, blobSum digest.Digest, parent digest.Digest) (contentAddressableDescriptor, error) { img := contentAddressableDescriptor{ v1Compatibility: v1Compatibility, } var err error img.config, err = image.MakeImageConfig(v1Compatibility, blobSum, parent) if err != nil { return img, err } img.strongID, err = image.StrongID(img.config) if err != nil { return img, err } unmarshalledConfig, err := image.NewImgJSON(v1Compatibility) if err != nil { return img, err } img.compatibilityID = unmarshalledConfig.ID img.id = img.strongID.Hex() return img, nil }
// validateImageInGraph checks that an image in the graph has the expected // strongID. id is the entry in the graph to check, imgs is the slice of // images being processed (for access to the parent), and i is the index // into this slice which the graph entry should be checked against. func (p *v2Puller) validateImageInGraph(id string, imgs []contentAddressableDescriptor, i int) error { img, err := p.graph.Get(id) if err != nil { return fmt.Errorf("missing: %v", err) } layerID, err := p.graph.getLayerDigest(id) if err != nil { return fmt.Errorf("digest: %v", err) } var parentID digest.Digest if i != len(imgs)-1 { if img.Parent != imgs[i+1].id { // comparing that graph points to validated ID return fmt.Errorf("parent: %v %v", img.Parent, imgs[i+1].id) } parentID = imgs[i+1].strongID } else if img.Parent != "" { return fmt.Errorf("unexpected parent: %v", img.Parent) } v1Config, err := p.graph.getV1CompatibilityConfig(img.ID) if err != nil { return fmt.Errorf("v1Compatibility: %v %v", img.ID, err) } json, err := image.MakeImageConfig(v1Config, layerID, parentID) if err != nil { return fmt.Errorf("make config: %v", err) } if dgst, err := image.StrongID(json); err == nil && dgst == imgs[i].strongID { logrus.Debugf("Validated %v as %v", dgst, id) } else { return fmt.Errorf("digest mismatch: %v %v, error: %v", dgst, imgs[i].strongID, err) } // All clear return nil }