func TestRegistryClientV2DockerHub(t *testing.T) {
	c := dockerregistry.NewClient()
	conn, err := c.Connect("index.docker.io", false)
	if err != nil {
		t.Fatal(err)
	}
	image, err := conn.ImageByTag("kubernetes", "guestbook", "latest")
	// The V2 docker hub registry seems to have a bug for this repo, should eventually get fixed
	if !dockerregistry.IsTagNotFound(err) {
		t.Fatalf("unexpected error: %v", err)
	}

	// a v1 only path
	conn, err = c.Connect("registry.hub.docker.com", false)
	if err != nil {
		t.Fatal(err)
	}
	image, err = conn.ImageByTag("kubernetes", "guestbook", "latest")
	if err != nil {
		t.Fatalf("unable to retrieve image info: %v", err)
	}
	if len(image.ID) == 0 {
		t.Fatalf("image had no ID: %#v", image)
	}
}
// Search searches in the Docker registry for images that match terms
func (r DockerRegistrySearcher) Search(terms ...string) (ComponentMatches, error) {
	componentMatches := ComponentMatches{}
	for _, term := range terms {
		ref, err := imageapi.ParseDockerImageReference(term)
		if err != nil {
			return nil, err
		}

		glog.V(4).Infof("checking Docker registry for %q, allow-insecure=%v", ref.String(), r.AllowInsecure)
		connection, err := r.Client.Connect(ref.Registry, r.AllowInsecure)
		if err != nil {
			if dockerregistry.IsRegistryNotFound(err) {
				return nil, ErrNoMatch{value: term}
			}
			return nil, fmt.Errorf("can't connect to %q: %v", ref.Registry, err)
		}

		image, err := connection.ImageByTag(ref.Namespace, ref.Name, ref.Tag)
		if err != nil {
			if dockerregistry.IsNotFound(err) {
				if dockerregistry.IsTagNotFound(err) {
					glog.V(4).Infof("tag not found: %v", err)
				}
				continue
			}
			return nil, fmt.Errorf("can't connect to %q: %v", ref.Registry, err)
		}

		if len(ref.Tag) == 0 {
			ref.Tag = imageapi.DefaultImageTag
		}
		if len(ref.Registry) == 0 {
			ref.Registry = "Docker Hub"
		}
		glog.V(4).Infof("found image: %#v", image)

		dockerImage := &imageapi.DockerImage{}
		if err = kapi.Scheme.Convert(&image.Image, dockerImage); err != nil {
			return nil, err
		}

		match := &ComponentMatch{
			Value:       term,
			Argument:    fmt.Sprintf("--docker-image=%q", term),
			Name:        term,
			Description: descriptionFor(dockerImage, term, ref.Registry, ref.Tag),
			Score:       0,
			Image:       dockerImage,
			ImageTag:    ref.Tag,
			Insecure:    r.AllowInsecure,
			Meta:        map[string]string{"registry": ref.Registry},
		}
		glog.V(2).Infof("Adding %s as component match for %q with score %v", match.Description, term, match.Score)
		componentMatches = append(componentMatches, match)
	}

	return componentMatches, nil
}
func doTestRegistryClientImage(t *testing.T, registry, reponame, version string) {
	conn, err := dockerregistry.NewClient(10*time.Second, version == "v2").Connect(registry, false)
	if err != nil {
		t.Fatal(err)
	}

	err = retryWhenUnreachable(t, func() error {
		_, err := conn.ImageByTag("openshift", "origin-not-found", "latest")
		return err
	})
	if err == nil || (!dockerregistry.IsRepositoryNotFound(err) && !dockerregistry.IsTagNotFound(err)) {
		t.Errorf("%s: unexpected error: %v", version, err)
	}

	var image *dockerregistry.Image
	err = retryWhenUnreachable(t, func() error {
		image, err = conn.ImageByTag("openshift", reponame, "latest")
		return err
	})
	if err != nil {
		t.Fatal(err)
	}

	if image.Comment != "Imported from -" {
		t.Errorf("%s: unexpected image comment", version)
	}

	if image.Architecture != "amd64" {
		t.Errorf("%s: unexpected image architecture", version)
	}

	if version == "v2" && !image.PullByID {
		t.Errorf("%s: should be able to pull by ID %s", version, image.ID)
	}

	var other *dockerregistry.Image
	err = retryWhenUnreachable(t, func() error {
		other, err = conn.ImageByID("openshift", reponame, image.ID)
		return err
	})
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(other.ContainerConfig.Entrypoint, image.ContainerConfig.Entrypoint) {
		t.Errorf("%s: unexpected image: %#v", version, other)
	}
}
Example #4
0
// importTag import single tag from given ImageStream. Returns retrieved image (for later reuse),
// a flag saying if we should retry imports and an error if one occurs.
func (c *ImportController) importTag(stream *api.ImageStream, tag string, ref api.DockerImageReference, dockerImage *dockerregistry.Image, client dockerregistry.Client, insecure bool) (*dockerregistry.Image, bool, error) {
	glog.V(5).Infof("Importing tag %s from %s/%s...", tag, stream.Namespace, stream.Name)
	if dockerImage == nil {
		// TODO insecure applies to the stream's spec.dockerImageRepository, not necessarily to an external one!
		conn, err := client.Connect(ref.Registry, insecure)
		if err != nil {
			// retry-able error no. 3
			return nil, true, err
		}
		if len(ref.ID) > 0 {
			dockerImage, err = conn.ImageByID(ref.Namespace, ref.Name, ref.ID)
		} else {
			dockerImage, err = conn.ImageByTag(ref.Namespace, ref.Name, ref.Tag)
		}
		switch {
		case dockerregistry.IsRepositoryNotFound(err), dockerregistry.IsRegistryNotFound(err), dockerregistry.IsImageNotFound(err), dockerregistry.IsTagNotFound(err):
			return nil, false, err
		case err != nil:
			// retry-able error no. 4
			return nil, true, err
		}
	}
	var image api.DockerImage
	if err := kapi.Scheme.Convert(&dockerImage.Image, &image); err != nil {
		return nil, false, fmt.Errorf("could not convert image: %#v", err)
	}

	// prefer to pull by ID always
	if dockerImage.PullByID {
		// if the registry indicates the image is pullable by ID, clear the tag
		ref.Tag = ""
		ref.ID = dockerImage.ID
	}

	mapping := &api.ImageStreamMapping{
		ObjectMeta: kapi.ObjectMeta{
			Name:      stream.Name,
			Namespace: stream.Namespace,
		},
		Tag: tag,
		Image: api.Image{
			ObjectMeta: kapi.ObjectMeta{
				Name: dockerImage.ID,
			},
			DockerImageReference: ref.String(),
			DockerImageMetadata:  image,
		},
	}
	if err := c.mappings.ImageStreamMappings(stream.Namespace).Create(mapping); err != nil {
		// retry-able no. 5
		return nil, true, err
	}
	return dockerImage, false, nil
}
func TestRegistryClientImage(t *testing.T) {
	for _, v2 := range []bool{true, false} {
		host := "index.docker.io"
		if !v2 {
			host = "registry.hub.docker.com"
		}
		conn, err := dockerregistry.NewClient().Connect(host, false)
		if err != nil {
			t.Fatal(err)
		}

		if _, err := conn.ImageByTag("openshift", "origin-not-found", "latest"); !dockerregistry.IsRepositoryNotFound(err) && !dockerregistry.IsTagNotFound(err) {
			t.Errorf("V2=%t: unexpected error: %v", v2, err)
		}

		image, err := conn.ImageByTag("openshift", "origin", "latest")
		if err != nil {
			t.Fatalf("V2=%t: %v", v2, err)
		}
		if len(image.ContainerConfig.Entrypoint) == 0 {
			t.Errorf("V2=%t: unexpected image: %#v", v2, image)
		}
		if v2 && !image.PullByID {
			t.Errorf("V2=%t: should be able to pull by ID %s", v2, image.ID)
		}

		other, err := conn.ImageByID("openshift", "origin", image.ID)
		if err != nil {
			t.Fatal(err)
		}
		if !reflect.DeepEqual(other.ContainerConfig.Entrypoint, image.ContainerConfig.Entrypoint) {
			t.Errorf("V2=%t: unexpected image: %#v", v2, other)
		}
	}
}