func autoConvert_v1_DockerImageReference_To_api_DockerImageReference(in *DockerImageReference, out *api.DockerImageReference, s conversion.Scope) error { out.Registry = in.Registry out.Namespace = in.Namespace out.Name = in.Name out.Tag = in.Tag out.ID = in.ID return nil }
// 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 autoConvert_v1_DockerImageReference_To_api_DockerImageReference(in *DockerImageReference, out *image_api.DockerImageReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*DockerImageReference))(in) } out.Registry = in.Registry out.Namespace = in.Namespace out.Name = in.Name out.Tag = in.Tag out.ID = in.ID return nil }
// Next processes the given image stream, looking for streams that have DockerImageRepository // set but have not yet been marked as "ready". If transient errors occur, err is returned but // the image stream is not modified (so it will be tried again later). If a permanent // failure occurs the image is marked with an annotation. The tags of the original spec image // are left as is (those are updated through status). func (c *ImportController) Next(stream *api.ImageStream) error { if !needsImport(stream) { return nil } name := stream.Spec.DockerImageRepository ref, err := api.ParseDockerImageReference(name) if err != nil { err = fmt.Errorf("invalid docker image repository, cannot import data: %v", err) util.HandleError(err) return c.done(stream, err.Error(), retryCount) } insecure := stream.Annotations != nil && stream.Annotations[api.InsecureRepositoryAnnotation] == "true" client := c.client if client == nil { client = dockerregistry.NewClient() } conn, err := client.Connect(ref.Registry, insecure, false) if err != nil { return err } tags, err := conn.ImageTags(ref.Namespace, ref.Name) switch { case dockerregistry.IsRepositoryNotFound(err), dockerregistry.IsRegistryNotFound(err): return c.done(stream, err.Error(), retryCount) case err != nil: return err } imageToTag := make(map[string][]string) for tag, image := range tags { if specTag, ok := stream.Spec.Tags[tag]; ok && specTag.From != nil { // spec tag is set to track another tag - do not import continue } imageToTag[image] = append(imageToTag[image], tag) } // no tags to import if len(imageToTag) == 0 { return c.done(stream, "", retryCount) } for id, tags := range imageToTag { dockerImage, err := conn.ImageByID(ref.Namespace, ref.Name, id) switch { case dockerregistry.IsRepositoryNotFound(err), dockerregistry.IsRegistryNotFound(err): return c.done(stream, err.Error(), retryCount) case dockerregistry.IsImageNotFound(err): continue case err != nil: return err } var image api.DockerImage if err := kapi.Scheme.Convert(&dockerImage.Image, &image); err != nil { err = fmt.Errorf("could not convert image: %#v", err) util.HandleError(err) return c.done(stream, err.Error(), retryCount) } idTagPresent := false if len(tags) > 1 && hasTag(tags, id) { // only set to true if we have at least 1 tag that isn't the image id idTagPresent = true } for _, tag := range tags { if idTagPresent && id == tag { continue } pullRef := api.DockerImageReference{ Registry: ref.Registry, Namespace: ref.Namespace, Name: ref.Name, Tag: tag, } // prefer to pull by ID always if dockerImage.PullByID { // if the registry indicates the image is pullable by ID, clear the tag pullRef.Tag = "" pullRef.ID = dockerImage.ID } else if idTagPresent { // if there is a tag for the image by its id (tag=tag), we can pull by id pullRef.Tag = 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: pullRef.String(), DockerImageMetadata: image, }, } if err := c.mappings.ImageStreamMappings(stream.Namespace).Create(mapping); err != nil { if errors.IsNotFound(err) { return c.done(stream, err.Error(), retryCount) } return err } } } // we've completed our updates return c.done(stream, "", retryCount) }
// Search searches all images in local docker server for images that match terms func (r DockerClientSearcher) Search(precise bool, terms ...string) (ComponentMatches, []error) { componentMatches := ComponentMatches{} errs := []error{} for _, term := range terms { var ( ref imageapi.DockerImageReference err error ) switch term { case "__dockerimage_fail": errs = append(errs, fmt.Errorf("unable to find the specified docker image: %s", term)) continue case "scratch": componentMatches = append(componentMatches, &ComponentMatch{ Value: term, Score: 0.0, // we don't want to create an imagestream for "scratch", so treat // it as a local only image. LocalOnly: true, Virtual: true, }) return componentMatches, errs case "*": ref = imageapi.DockerImageReference{Name: term} default: ref, err = imageapi.ParseDockerImageReference(term) if err != nil { continue } } termMatches := ScoredComponentMatches{} // first look for the image in the remote docker registry if r.RegistrySearcher != nil { glog.V(4).Infof("checking remote registry for %q", ref.String()) matches, err := r.RegistrySearcher.Search(precise, term) errs = append(errs, err...) for i := range matches { matches[i].LocalOnly = false glog.V(5).Infof("Found remote match %v", matches[i].Value) } termMatches = append(termMatches, matches...) } if r.Client == nil || reflect.ValueOf(r.Client).IsNil() { componentMatches = append(componentMatches, termMatches...) continue } // if we didn't find it exactly in a remote registry, // try to find it as a local-only image. if len(termMatches.Exact()) == 0 { glog.V(4).Infof("checking local Docker daemon for %q", ref.String()) images, err := r.Client.ListImages(docker.ListImagesOptions{}) if err != nil { errs = append(errs, err) continue } if len(ref.Tag) == 0 { ref.Tag = imageapi.DefaultImageTag term = fmt.Sprintf("%s:%s", term, imageapi.DefaultImageTag) } for _, image := range images { if tags := matchTag(image, term, ref.Registry, ref.Namespace, ref.Name, ref.Tag); len(tags) > 0 { for i := range tags { tags[i].LocalOnly = true glog.V(5).Infof("Found local docker image match %q with score %f", tags[i].Value, tags[i].Score) } termMatches = append(termMatches, tags...) } } } sort.Sort(termMatches) for i, match := range termMatches { if match.Image != nil { continue } image, err := r.Client.InspectImage(match.Value) if err != nil { if err != docker.ErrNoSuchImage { errs = append(errs, err) } continue } dockerImage := &imageapi.DockerImage{} if err := kapi.Scheme.Convert(image, dockerImage, nil); err != nil { errs = append(errs, err) continue } updated := &ComponentMatch{ Value: match.Value, Argument: fmt.Sprintf("--docker-image=%q", match.Value), Name: match.Value, Description: descriptionFor(dockerImage, match.Value, ref.Registry, ""), Score: match.Score, Image: dockerImage, ImageTag: ref.Tag, Insecure: r.Insecure, Meta: map[string]string{"registry": ref.Registry}, LocalOnly: match.LocalOnly, } termMatches[i] = updated } componentMatches = append(componentMatches, termMatches...) } return componentMatches, errs }
// Search searches in the Docker registry for images that match terms func (r DockerRegistrySearcher) Search(precise bool, terms ...string) (ComponentMatches, []error) { componentMatches := ComponentMatches{} var errs []error for _, term := range terms { var ( ref imageapi.DockerImageReference err error ) if term != "*" { ref, err = imageapi.ParseDockerImageReference(term) if err != nil { continue } } else { ref = imageapi.DockerImageReference{Name: term} } 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) { errs = append(errs, err) continue } errs = append(errs, fmt.Errorf("can't connect to %q: %v", ref.Registry, err)) continue } 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 } errs = append(errs, fmt.Errorf("can't connect to %q: %v", ref.Registry, err)) continue } 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, nil); err != nil { errs = append(errs, err) continue } 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, errs }