Skip to content

Commit

Permalink
Use the dockerImageReference tag when pushed
Browse files Browse the repository at this point in the history
Short term solution to allow the registry to indicate an image is
pullable via another tag, while allowing initial repo population
to work based only on existing tags.
  • Loading branch information
smarterclayton committed Mar 13, 2015
1 parent 17289d4 commit 0f24309
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 17 deletions.
31 changes: 26 additions & 5 deletions pkg/image/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ func (c *ImportController) Next(repo *api.ImageRepository) error {
switch {
case len(repo.Tags) == 0:
// copy all tags
for tag, _ := range tags {
// TODO: once pull by image is implemented, use tag = imageid
for tag := range tags {
// TODO: switch to image when pull by ID is automatic
newTags[tag] = tag
}
for tag, image := range tags {
Expand All @@ -80,7 +80,7 @@ func (c *ImportController) Next(repo *api.ImageRepository) error {
continue
}
imageToTag[image] = append(imageToTag[image], tag)
// TODO: once pull by image is implemented, use tag = imageid
// TODO: switch to image when pull by ID is automatic
newTags[tag] = tag
}
}
Expand Down Expand Up @@ -112,14 +112,26 @@ func (c *ImportController) Next(repo *api.ImageRepository) error {
util.HandleError(err)
return c.done(repo, err.Error())
}

// if there is a tag for the image by its id (tag=tag), we can pull by id
tag := tags[0]
if hasTag(tags, id) {
tag = id
}
ref := api.JoinDockerPullSpec(registry, namespace, name, tag)

mapping := &api.ImageRepositoryMapping{
ObjectMeta: kapi.ObjectMeta{
Name: repo.Name,
Namespace: repo.Namespace,
},
Tag: tags[0],
Tag: tag,
Image: api.Image{
DockerImageMetadata: image,
ObjectMeta: kapi.ObjectMeta{
Name: id,
},
DockerImageReference: ref,
DockerImageMetadata: image,
},
}
if err := c.mappings.ImageRepositoryMappings(repo.Namespace).Create(mapping); err != nil {
Expand All @@ -145,3 +157,12 @@ func (c *ImportController) done(repo *api.ImageRepository, reason string) error
}
return nil
}

func hasTag(tags []string, tag string) bool {
for _, s := range tags {
if s == tag {
return true
}
}
return false
}
11 changes: 10 additions & 1 deletion pkg/image/registry/imagerepositorymapping/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,19 @@ func (s *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, err

image := mapping.Image

pullTag := mapping.Tag
if len(image.DockerImageReference) > 0 {
if _, _, name, tag, err := api.SplitDockerPullSpec(image.DockerImageReference); err == nil {
if name == repo.Name && tag != mapping.Tag {
pullTag = tag
}
}
}

if repo.Tags == nil {
repo.Tags = make(map[string]string)
}
repo.Tags[mapping.Tag] = image.Name
repo.Tags[mapping.Tag] = pullTag

if err := s.imageRegistry.CreateImage(ctx, &image); err != nil && !errors.IsAlreadyExists(err) {
return nil, err
Expand Down
78 changes: 67 additions & 11 deletions pkg/image/registry/imagerepositorymapping/rest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,61 @@ func TestCreateImageRepositoryNotFound(t *testing.T) {
func TestCreateSuccessWithDockerImageRepository(t *testing.T) {
fakeEtcdClient, helper, storage := setup(t)

initialRepo := &api.ImageRepository{
ObjectMeta: kapi.ObjectMeta{Namespace: "default", Name: "somerepo"},
DockerImageRepository: "localhost:5000/someproject/somerepo",
}

fakeEtcdClient.Data["/imageRepositories/default"] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Nodes: []*etcd.Node{
{
Value: runtime.EncodeOrDie(latest.Codec, initialRepo),
ModifiedIndex: 1,
},
},
},
},
}
fakeEtcdClient.Data["/imageRepositories/default/somerepo"] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, initialRepo),
ModifiedIndex: 1,
},
},
}

mapping := validNewMappingWithDockerImageRepository()
_, err := storage.Create(kapi.NewDefaultContext(), mapping)
if err != nil {
t.Fatalf("Unexpected error creating mapping: %#v", err)
}

image := &api.Image{}
if err := helper.ExtractObj("/images/imageID1", image, false); err != nil {
t.Errorf("Unexpected error retrieving image: %#v", err)
}
if e, a := mapping.Image.DockerImageReference, image.DockerImageReference; e != a {
t.Errorf("Expected %s, got %s", e, a)
}
if !reflect.DeepEqual(mapping.Image.DockerImageMetadata, image.DockerImageMetadata) {
t.Errorf("Expected %#v, got %#v", mapping.Image, image)
}

repo := &api.ImageRepository{}
if err := helper.ExtractObj("/imageRepositories/default/somerepo", repo, false); err != nil {
t.Errorf("Unexpected non-nil err: %#v", err)
}
if e, a := "imageID1", repo.Tags["latest"]; e != a {
t.Errorf("unexpected repo: %#v\n%#v", repo, image)
}
}

func TestCreateSuccessWithMismatchedNames(t *testing.T) {
fakeEtcdClient, helper, storage := setup(t)

initialRepo := &api.ImageRepository{
ObjectMeta: kapi.ObjectMeta{Namespace: "default", Name: "repo1"},
DockerImageRepository: "localhost:5000/someproject/somerepo",
Expand Down Expand Up @@ -205,8 +260,9 @@ func TestCreateSuccessWithDockerImageRepository(t *testing.T) {
if err := helper.ExtractObj("/imageRepositories/default/repo1", repo, false); err != nil {
t.Errorf("Unexpected non-nil err: %#v", err)
}
if e, a := "imageID1", repo.Tags["latest"]; e != a {
t.Errorf("Expected %s, got %s", e, a)
// the latest tag is used because the repo name and the posted docker repo name differ
if e, a := "latest", repo.Tags["latest"]; e != a {
t.Errorf("unexpected repo: %#v\n%#v", repo, image)
}
}

Expand Down Expand Up @@ -256,7 +312,7 @@ func TestAddExistingImageWithNewTag(t *testing.T) {
imageID := "8d812da98d6dd61620343f1a5bf6585b34ad6ed16e5c5f7c7216a525d6aeb772"
existingRepo := &api.ImageRepository{
ObjectMeta: kapi.ObjectMeta{
Name: "repo1",
Name: "somerepo",
Namespace: "default",
},
DockerImageRepository: "localhost:5000/someproject/somerepo",
Expand Down Expand Up @@ -301,7 +357,7 @@ func TestAddExistingImageWithNewTag(t *testing.T) {
},
},
}
fakeEtcdClient.Data["/imageRepositories/default/repo1"] = tools.EtcdResponseWithError{
fakeEtcdClient.Data["/imageRepositories/default/somerepo"] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, existingRepo),
Expand Down Expand Up @@ -340,7 +396,7 @@ func TestAddExistingImageWithNewTag(t *testing.T) {
}

repo := &api.ImageRepository{}
if err := helper.ExtractObj("/imageRepositories/default/repo1", repo, false); err != nil {
if err := helper.ExtractObj("/imageRepositories/default/somerepo", repo, false); err != nil {
t.Errorf("Unexpected non-nil err: %#v", err)
}
if e, a := imageID, repo.Tags["latest"]; e != a {
Expand All @@ -366,7 +422,7 @@ func TestAddExistingImageWithNewTag(t *testing.T) {
func TestAddExistingImageAndTag(t *testing.T) {
existingRepo := &api.ImageRepository{
ObjectMeta: kapi.ObjectMeta{
Name: "repo1",
Name: "somerepo",
Namespace: "default",
},
DockerImageRepository: "localhost:5000/someproject/somerepo",
Expand Down Expand Up @@ -411,7 +467,7 @@ func TestAddExistingImageAndTag(t *testing.T) {
},
},
}
fakeEtcdClient.Data["/imageRepositories/default/repo1"] = tools.EtcdResponseWithError{
fakeEtcdClient.Data["/imageRepositories/default/somerepo"] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, existingRepo),
Expand Down Expand Up @@ -450,16 +506,16 @@ func TestAddExistingImageAndTag(t *testing.T) {
}

repo := &api.ImageRepository{}
if err := helper.ExtractObj("/imageRepositories/default/repo1", repo, false); err != nil {
if err := helper.ExtractObj("/imageRepositories/default/somerepo", repo, false); err != nil {
t.Errorf("Unexpected non-nil err: %#v", err)
}
if e, a := "existingImage", repo.Tags["existingTag"]; e != a {
if e, a := "imageID1", repo.Tags["existingTag"]; e != a {
t.Errorf("Expected %s, got %s", e, a)
}
if e, a := 1, len(repo.Status.Tags); e != a {
t.Errorf("repo.Status.Tags length: expected %d, got %d", e, a)
}
if e, a := mapping.DockerImageRepository+":existingImage", repo.Status.Tags["existingTag"].Items[0].DockerImageReference; e != a {
t.Errorf("tag history: expected image %s, got %s", e, a)
if e, a := mapping.DockerImageRepository+":imageID1", repo.Status.Tags["existingTag"].Items[0].DockerImageReference; e != a {
t.Errorf("unexpected repo: %#v", repo)
}
}

0 comments on commit 0f24309

Please sign in to comment.