Skip to content

Commit

Permalink
Generalize content addressable and reference storage
Browse files Browse the repository at this point in the history
Signed-off-by: Tonis Tiigi <[email protected]>
  • Loading branch information
tonistiigi committed Sep 16, 2016
1 parent a7c25f9 commit 8052239
Show file tree
Hide file tree
Showing 21 changed files with 184 additions and 174 deletions.
8 changes: 4 additions & 4 deletions daemon/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,18 @@ func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
return "", err
}
if id != "" {
if _, err := daemon.imageStore.Get(image.ID(id)); err != nil {
if _, err := daemon.imageStore.Get(image.IDFromDigest(id)); err != nil {
return "", ErrImageDoesNotExist{refOrID}
}
return image.ID(id), nil
return image.IDFromDigest(id), nil
}

if id, err := daemon.referenceStore.Get(ref); err == nil {
return id, nil
return image.IDFromDigest(id), nil
}
if tagged, ok := ref.(reference.NamedTagged); ok {
if id, err := daemon.imageStore.Search(tagged.Tag()); err == nil {
for _, namedRef := range daemon.referenceStore.References(id) {
for _, namedRef := range daemon.referenceStore.References(id.Digest()) {
if namedRef.Name() == ref.Name() {
return id, nil
}
Expand Down
10 changes: 5 additions & 5 deletions daemon/image_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
return nil, daemon.imageNotExistToErrcode(err)
}

repoRefs := daemon.referenceStore.References(imgID)
repoRefs := daemon.referenceStore.References(imgID.Digest())

var removedRepositoryRef bool
if !isImageIDPrefix(imgID.String(), imageRef) {
Expand Down Expand Up @@ -102,7 +102,7 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
daemon.LogImageEvent(imgID.String(), imgID.String(), "untag")
records = append(records, untaggedRecord)

repoRefs = daemon.referenceStore.References(imgID)
repoRefs = daemon.referenceStore.References(imgID.Digest())

// If a tag reference was removed and the only remaining
// references to the same repository are digest references,
Expand Down Expand Up @@ -239,7 +239,7 @@ func (daemon *Daemon) removeImageRef(ref reference.Named) (reference.Named, erro
// daemon's event service. An "Untagged" types.ImageDelete is added to the
// given list of records.
func (daemon *Daemon) removeAllReferencesToImageID(imgID image.ID, records *[]types.ImageDelete) error {
imageRefs := daemon.referenceStore.References(imgID)
imageRefs := daemon.referenceStore.References(imgID.Digest())

for _, imageRef := range imageRefs {
parsedRef, err := daemon.removeImageRef(imageRef)
Expand Down Expand Up @@ -372,7 +372,7 @@ func (daemon *Daemon) checkImageDeleteConflict(imgID image.ID, mask conflictType
}

// Check if any repository tags/digest reference this image.
if mask&conflictActiveReference != 0 && len(daemon.referenceStore.References(imgID)) > 0 {
if mask&conflictActiveReference != 0 && len(daemon.referenceStore.References(imgID.Digest())) > 0 {
return &imageDeleteConflict{
imgID: imgID,
message: "image is referenced in multiple repositories",
Expand Down Expand Up @@ -400,5 +400,5 @@ func (daemon *Daemon) checkImageDeleteConflict(imgID image.ID, mask conflictType
// that there are no repository references to the given image and it has no
// child images.
func (daemon *Daemon) imageIsDangling(imgID image.ID) bool {
return !(len(daemon.referenceStore.References(imgID)) > 0 || len(daemon.imageStore.Children(imgID)) > 0)
return !(len(daemon.referenceStore.References(imgID.Digest())) > 0 || len(daemon.imageStore.Children(imgID)) > 0)
}
2 changes: 1 addition & 1 deletion daemon/image_history.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
h.ID = id.String()

var tags []string
for _, r := range daemon.referenceStore.References(id) {
for _, r := range daemon.referenceStore.References(id.Digest()) {
if _, ok := r.(reference.NamedTagged); ok {
tags = append(tags, r.String())
}
Expand Down
2 changes: 1 addition & 1 deletion daemon/image_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (daemon *Daemon) LookupImage(name string) (*types.ImageInspect, error) {
return nil, fmt.Errorf("No such image: %s", name)
}

refs := daemon.referenceStore.References(img.ID())
refs := daemon.referenceStore.References(img.ID().Digest())
repoTags := []string{}
repoDigests := []string{}
for _, ref := range refs {
Expand Down
2 changes: 1 addition & 1 deletion daemon/image_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (daemon *Daemon) TagImage(imageName, repository, tag string) error {

// TagImageWithReference adds the given reference to the image ID provided.
func (daemon *Daemon) TagImageWithReference(imageID image.ID, newTag reference.Named) error {
if err := daemon.referenceStore.AddTag(newTag, imageID, true); err != nil {
if err := daemon.referenceStore.AddTag(newTag, imageID.Digest(), true); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion daemon/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func (daemon *Daemon) Images(filterArgs, filter string, all bool) ([]*types.Imag

newImage := newImage(img, size)

for _, ref := range daemon.referenceStore.References(id) {
for _, ref := range daemon.referenceStore.References(id.Digest()) {
if filter != "" { // filter by tag/repo name
if filterTagged { // filter by tag, require full ref match
if ref.String() != filter {
Expand Down
10 changes: 5 additions & 5 deletions distribution/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,21 +205,21 @@ func ValidateRepoName(name string) error {
return nil
}

func addDigestReference(store reference.Store, ref reference.Named, dgst digest.Digest, imageID image.ID) error {
func addDigestReference(store reference.Store, ref reference.Named, dgst digest.Digest, id digest.Digest) error {
dgstRef, err := reference.WithDigest(ref, dgst)
if err != nil {
return err
}

if oldTagImageID, err := store.Get(dgstRef); err == nil {
if oldTagImageID != imageID {
if oldTagID, err := store.Get(dgstRef); err == nil {
if oldTagID != id {
// Updating digests not supported by reference store
logrus.Errorf("Image ID for digest %s changed from %s to %s, cannot update", dgst.String(), oldTagImageID, imageID)
logrus.Errorf("Image ID for digest %s changed from %s to %s, cannot update", dgst.String(), oldTagID, id)
}
return nil
} else if err != reference.ErrDoesNotExist {
return err
}

return store.AddDigest(dgstRef, imageID, true)
return store.AddDigest(dgstRef, id, true)
}
2 changes: 1 addition & 1 deletion distribution/pull_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func (p *v1Puller) pullImage(ctx context.Context, v1ID, endpoint string, localNa
return err
}

if err := p.config.ReferenceStore.AddTag(localNameRef, imageID, true); err != nil {
if err := p.config.ReferenceStore.AddTag(localNameRef, imageID.Digest(), true); err != nil {
return err
}

Expand Down
49 changes: 24 additions & 25 deletions distribution/pull_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,23 +374,23 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named) (tagUpdat
progress.Message(p.config.ProgressOutput, tagOrDigest, "Pulling from "+p.repo.Named().Name())

var (
imageID image.ID
id digest.Digest
manifestDigest digest.Digest
)

switch v := manifest.(type) {
case *schema1.SignedManifest:
imageID, manifestDigest, err = p.pullSchema1(ctx, ref, v)
id, manifestDigest, err = p.pullSchema1(ctx, ref, v)
if err != nil {
return false, err
}
case *schema2.DeserializedManifest:
imageID, manifestDigest, err = p.pullSchema2(ctx, ref, v)
id, manifestDigest, err = p.pullSchema2(ctx, ref, v)
if err != nil {
return false, err
}
case *manifestlist.DeserializedManifestList:
imageID, manifestDigest, err = p.pullManifestList(ctx, ref, v)
id, manifestDigest, err = p.pullManifestList(ctx, ref, v)
if err != nil {
return false, err
}
Expand All @@ -400,31 +400,31 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named) (tagUpdat

progress.Message(p.config.ProgressOutput, "", "Digest: "+manifestDigest.String())

oldTagImageID, err := p.config.ReferenceStore.Get(ref)
oldTagID, err := p.config.ReferenceStore.Get(ref)
if err == nil {
if oldTagImageID == imageID {
return false, addDigestReference(p.config.ReferenceStore, ref, manifestDigest, imageID)
if oldTagID == id {
return false, addDigestReference(p.config.ReferenceStore, ref, manifestDigest, id)
}
} else if err != reference.ErrDoesNotExist {
return false, err
}

if canonical, ok := ref.(reference.Canonical); ok {
if err = p.config.ReferenceStore.AddDigest(canonical, imageID, true); err != nil {
if err = p.config.ReferenceStore.AddDigest(canonical, id, true); err != nil {
return false, err
}
} else {
if err = addDigestReference(p.config.ReferenceStore, ref, manifestDigest, imageID); err != nil {
if err = addDigestReference(p.config.ReferenceStore, ref, manifestDigest, id); err != nil {
return false, err
}
if err = p.config.ReferenceStore.AddTag(ref, imageID, true); err != nil {
if err = p.config.ReferenceStore.AddTag(ref, id, true); err != nil {
return false, err
}
}
return true, nil
}

func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Named, unverifiedManifest *schema1.SignedManifest) (imageID image.ID, manifestDigest digest.Digest, err error) {
func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Named, unverifiedManifest *schema1.SignedManifest) (id digest.Digest, manifestDigest digest.Digest, err error) {
var verifiedManifest *schema1.Manifest
verifiedManifest, err = verifySchema1Manifest(unverifiedManifest, ref)
if err != nil {
Expand Down Expand Up @@ -487,28 +487,27 @@ func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Named, unverif
return "", "", err
}

imageID, err = p.config.ImageStore.Create(config)
imageID, err := p.config.ImageStore.Create(config)
if err != nil {
return "", "", err
}

manifestDigest = digest.FromBytes(unverifiedManifest.Canonical)

return imageID, manifestDigest, nil
return imageID.Digest(), manifestDigest, nil
}

func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *schema2.DeserializedManifest) (imageID image.ID, manifestDigest digest.Digest, err error) {
func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *schema2.DeserializedManifest) (id digest.Digest, manifestDigest digest.Digest, err error) {
manifestDigest, err = schema2ManifestDigest(ref, mfst)
if err != nil {
return "", "", err
}

target := mfst.Target()
imageID = image.ID(target.Digest)
if _, err := p.config.ImageStore.Get(imageID); err == nil {
if _, err := p.config.ImageStore.Get(image.IDFromDigest(target.Digest)); err == nil {
// If the image already exists locally, no need to pull
// anything.
return imageID, manifestDigest, nil
return target.Digest, manifestDigest, nil
}

var descriptors []xfer.DownloadDescriptor
Expand All @@ -534,7 +533,7 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s

// Pull the image config
go func() {
configJSON, err := p.pullSchema2ImageConfig(ctx, target.Digest)
configJSON, err := p.pullSchema2Config(ctx, target.Digest)
if err != nil {
errChan <- ImageConfigPullError{Err: err}
cancel()
Expand Down Expand Up @@ -618,12 +617,12 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
}
}

imageID, err = p.config.ImageStore.Create(configJSON)
imageID, err := p.config.ImageStore.Create(configJSON)
if err != nil {
return "", "", err
}

return imageID, manifestDigest, nil
return imageID.Digest(), manifestDigest, nil
}

func receiveConfig(configChan <-chan []byte, errChan <-chan error) ([]byte, image.Image, error) {
Expand All @@ -643,7 +642,7 @@ func receiveConfig(configChan <-chan []byte, errChan <-chan error) ([]byte, imag

// pullManifestList handles "manifest lists" which point to various
// platform-specifc manifests.
func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList) (imageID image.ID, manifestListDigest digest.Digest, err error) {
func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList) (id digest.Digest, manifestListDigest digest.Digest, err error) {
manifestListDigest, err = schema2ManifestDigest(ref, mfstList)
if err != nil {
return "", "", err
Expand Down Expand Up @@ -681,23 +680,23 @@ func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mf

switch v := manifest.(type) {
case *schema1.SignedManifest:
imageID, _, err = p.pullSchema1(ctx, manifestRef, v)
id, _, err = p.pullSchema1(ctx, manifestRef, v)
if err != nil {
return "", "", err
}
case *schema2.DeserializedManifest:
imageID, _, err = p.pullSchema2(ctx, manifestRef, v)
id, _, err = p.pullSchema2(ctx, manifestRef, v)
if err != nil {
return "", "", err
}
default:
return "", "", errors.New("unsupported manifest format")
}

return imageID, manifestListDigest, err
return id, manifestListDigest, err
}

func (p *v2Puller) pullSchema2ImageConfig(ctx context.Context, dgst digest.Digest) (configJSON []byte, err error) {
func (p *v2Puller) pullSchema2Config(ctx context.Context, dgst digest.Digest) (configJSON []byte, err error) {
blobs := p.repo.Blobs(ctx)
configJSON, err = blobs.Get(ctx, dgst)
if err != nil {
Expand Down
17 changes: 10 additions & 7 deletions distribution/push_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ type v1TopImage struct {
}

func newV1TopImage(imageID image.ID, img *image.Image, l layer.Layer, parent *v1DependencyImage) (*v1TopImage, error) {
v1ID := digest.Digest(imageID).Hex()
v1ID := imageID.Digest().Hex()
parentV1ID := ""
if parent != nil {
parentV1ID = parent.V1ID()
Expand Down Expand Up @@ -149,10 +149,12 @@ func (p *v1Pusher) getImageList() (imageList []v1Image, tagsByImage map[image.ID
if isTagged {
// Push a specific tag
var imgID image.ID
imgID, err = p.config.ReferenceStore.Get(p.ref)
var dgst digest.Digest
dgst, err = p.config.ReferenceStore.Get(p.ref)
if err != nil {
return
}
imgID = image.IDFromDigest(dgst)

imageList, err = p.imageListForTag(imgID, nil, &referencedLayers)
if err != nil {
Expand All @@ -164,7 +166,7 @@ func (p *v1Pusher) getImageList() (imageList []v1Image, tagsByImage map[image.ID
return
}

imagesSeen := make(map[image.ID]struct{})
imagesSeen := make(map[digest.Digest]struct{})
dependenciesSeen := make(map[layer.ChainID]*v1DependencyImage)

associations := p.config.ReferenceStore.ReferencesByName(p.ref)
Expand All @@ -174,15 +176,16 @@ func (p *v1Pusher) getImageList() (imageList []v1Image, tagsByImage map[image.ID
continue
}

tagsByImage[association.ImageID] = append(tagsByImage[association.ImageID], tagged.Tag())
imgID := image.IDFromDigest(association.ID)
tagsByImage[imgID] = append(tagsByImage[imgID], tagged.Tag())

if _, present := imagesSeen[association.ImageID]; present {
if _, present := imagesSeen[association.ID]; present {
// Skip generating image list for already-seen image
continue
}
imagesSeen[association.ImageID] = struct{}{}
imagesSeen[association.ID] = struct{}{}

imageListForThisTag, err := p.imageListForTag(association.ImageID, dependenciesSeen, &referencedLayers)
imageListForThisTag, err := p.imageListForTag(imgID, dependenciesSeen, &referencedLayers)
if err != nil {
return nil, nil, nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions distribution/push_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (p *v2Pusher) pushV2Repository(ctx context.Context) (err error) {
for _, association := range p.config.ReferenceStore.ReferencesByName(p.ref) {
if namedTagged, isNamedTagged := association.Ref.(reference.NamedTagged); isNamedTagged {
pushed++
if err := p.pushV2Tag(ctx, namedTagged, association.ImageID); err != nil {
if err := p.pushV2Tag(ctx, namedTagged, association.ID); err != nil {
return err
}
}
Expand All @@ -112,10 +112,10 @@ func (p *v2Pusher) pushV2Repository(ctx context.Context) (err error) {
return nil
}

func (p *v2Pusher) pushV2Tag(ctx context.Context, ref reference.NamedTagged, imageID image.ID) error {
func (p *v2Pusher) pushV2Tag(ctx context.Context, ref reference.NamedTagged, id digest.Digest) error {
logrus.Debugf("Pushing repository: %s", ref.String())

img, err := p.config.ImageStore.Get(imageID)
img, err := p.config.ImageStore.Get(image.IDFromDigest(id))
if err != nil {
return fmt.Errorf("could not find image from tag %s: %v", ref.String(), err)
}
Expand Down Expand Up @@ -207,7 +207,7 @@ func (p *v2Pusher) pushV2Tag(ctx context.Context, ref reference.NamedTagged, ima
manifestDigest := digest.FromBytes(canonicalManifest)
progress.Messagef(p.config.ProgressOutput, "", "%s: digest: %s size: %d", ref.Tag(), manifestDigest, len(canonicalManifest))

if err := addDigestReference(p.config.ReferenceStore, ref, manifestDigest, imageID); err != nil {
if err := addDigestReference(p.config.ReferenceStore, ref, manifestDigest, id); err != nil {
return err
}

Expand Down
Loading

0 comments on commit 8052239

Please sign in to comment.