Beispiel #1
1
// GetImageID returns an image ID corresponding to the image referred to by
// refOrID.
func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
	id, ref, err := reference.ParseIDOrReference(refOrID)
	if err != nil {
		return "", err
	}
	if id != "" {
		if _, err := daemon.imageStore.Get(image.ID(id)); err != nil {
			return "", ErrImageDoesNotExist{refOrID}
		}
		return image.ID(id), nil
	}

	if id, err := daemon.referenceStore.Get(ref); err == nil {
		return 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) {
				if namedRef.Name() == ref.Name() {
					return id, nil
				}
			}
		}
	}

	// Search based on ID
	if id, err := daemon.imageStore.Search(refOrID); err == nil {
		return id, nil
	}

	return "", ErrImageDoesNotExist{refOrID}
}
Beispiel #2
0
// GetImage parses input to retrieve a cached image
func (ic *ICache) GetImage(idOrRef string) (*metadata.ImageConfig, error) {
	ic.m.RLock()
	defer ic.m.RUnlock()

	// get the full image ID if supplied a prefix
	if id, err := ic.idIndex.Get(idOrRef); err == nil {
		idOrRef = id
	}

	digest, named, err := reference.ParseIDOrReference(idOrRef)
	if err != nil {
		return nil, err
	}

	var config *metadata.ImageConfig
	if digest != "" {
		config, err = ic.getImageByDigest(digest)
		if err != nil {
			return nil, err
		}
	} else {
		config, err = ic.getImageByNamed(named)
		if err != nil {
			return nil, err
		}
	}

	if config == nil {
		return nil, derr.NewRequestNotFoundError(fmt.Errorf("No such image: %s", idOrRef))
	}

	return copyImageConfig(config), nil
}
Beispiel #3
0
// Retrieve the image metadata from the image cache.
func getImageConfigFromCache(image string) (*metadata.ImageConfig, error) {
	// Use docker reference code to validate the id's format
	digest, named, err := reference.ParseIDOrReference(image)
	if err != nil {
		return nil, err
	}

	// Try to get the image config from our image cache
	imageCache := ImageCache()

	if digest != "" {
		config, err := imageCache.GetImageByDigest(digest)
		if err != nil {
			log.Errorf("Inspect lookup failed for image %s: %s.  Returning no such image.", image, err)
			return nil, derr.NewRequestNotFoundError(fmt.Errorf("No such image: %s", image))
		}
		if config != nil {
			return config, nil
		}
	} else {
		config, err := imageCache.GetImageByNamed(named)
		if err != nil {
			log.Errorf("Inspect lookup failed for image %s: %s.  Returning no such image.", image, err)
			return nil, derr.NewRequestNotFoundError(fmt.Errorf("No such image: %s", image))
		}
		if config != nil {
			return config, nil
		}
	}

	return nil, derr.NewRequestNotFoundError(fmt.Errorf("No such image: %s", image))
}
Beispiel #4
0
func (cli *DockerCli) createContainer(config *container.Config, hostConfig *container.HostConfig, networkingConfig *networktypes.NetworkingConfig, cidfile, name string) (*types.ContainerCreateResponse, error) {
	var containerIDFile *cidFile
	if cidfile != "" {
		var err error
		if containerIDFile, err = newCIDFile(cidfile); err != nil {
			return nil, err
		}
		defer containerIDFile.Close()
	}

	_, ref, err := reference.ParseIDOrReference(config.Image)
	if err != nil {
		return nil, err
	}
	if ref != nil {
		ref = reference.WithDefaultTag(ref)
	}

	//create the container
	response, err := cli.client.ContainerCreate(context.Background(), config, hostConfig, networkingConfig, name)

	//if image not found try to pull it
	if err != nil {
		if client.IsErrImageNotFound(err) && ref != nil {
			fmt.Fprintf(cli.err, "Unable to find image '%s' locally\n", ref.String())

			// we don't want to write to stdout anything apart from container.ID
			if err = cli.pullImageCustomOut(config.Image, cli.err); err != nil {
				return nil, err
			}
			// Retry
			var retryErr error
			response, retryErr = cli.client.ContainerCreate(context.Background(), config, hostConfig, networkingConfig, name)
			if retryErr != nil {
				return nil, retryErr
			}
		} else {
			return nil, err
		}
	}

	for _, warning := range response.Warnings {
		fmt.Fprintf(cli.err, "WARNING: %s\n", warning)
	}
	if containerIDFile != nil {
		if err = containerIDFile.Write(response.ID); err != nil {
			return nil, err
		}
	}
	return &response, nil
}
Beispiel #5
0
// Get parses input to retrieve a cached image
func (ic *ICache) Get(idOrRef string) (*metadata.ImageConfig, error) {
	defer trace.End(trace.Begin(""))
	ic.m.RLock()
	defer ic.m.RUnlock()

	// cover the case of creating by a full reference
	if config, ok := ic.cacheByName[idOrRef]; ok {
		return config, nil
	}

	// get the full image ID if supplied a prefix
	if id, err := ic.iDIndex.Get(idOrRef); err == nil {
		idOrRef = id
	}

	imgDigest, named, err := reference.ParseIDOrReference(idOrRef)
	if err != nil {
		return nil, err
	}

	var config *metadata.ImageConfig
	if imgDigest != "" {
		config = ic.getImageByDigest(imgDigest)
	} else {
		config = ic.getImageByNamed(named)
	}

	if config == nil {
		// docker automatically prints out ":latest" tag if not specified in case if image is not found.
		postfixLatest := ""
		if !strings.Contains(idOrRef, ":") {
			postfixLatest += ":" + reference.DefaultTag
		}
		return nil, derr.NewRequestNotFoundError(fmt.Errorf(
			"No such image: %s%s", idOrRef, postfixLatest))
	}

	return copyImageConfig(config), nil
}
Beispiel #6
0
// GetImageID returns an image ID corresponding to the image referred to by
// refOrID.
func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
	id, ref, err := reference.ParseIDOrReference(refOrID)
	if err != nil {
		return "", err
	}
	if id != "" {
		if _, err := daemon.imageStore.Get(image.IDFromDigest(id)); err != nil {
			return "", ErrImageDoesNotExist{refOrID}
		}
		return image.IDFromDigest(id), nil
	}

	if id, err := daemon.referenceStore.Get(ref); err == nil {
		return image.IDFromDigest(id), nil
	}

	// deprecated: repo:shortid https://github.com/docker/docker/pull/799
	if tagged, ok := ref.(reference.NamedTagged); ok {
		if tag := tagged.Tag(); stringid.IsShortID(stringid.TruncateID(tag)) {
			if id, err := daemon.imageStore.Search(tag); err == nil {
				for _, namedRef := range daemon.referenceStore.References(id.Digest()) {
					if namedRef.Name() == ref.Name() {
						return id, nil
					}
				}
			}
		}
	}

	// Search based on ID
	if id, err := daemon.imageStore.Search(refOrID); err == nil {
		return id, nil
	}

	return "", ErrImageDoesNotExist{refOrID}
}
Beispiel #7
0
func (l *tarexporter) parseNames(names []string) (map[image.ID]*imageDescriptor, error) {
	imgDescr := make(map[image.ID]*imageDescriptor)

	addAssoc := func(id image.ID, ref reference.Named) {
		if _, ok := imgDescr[id]; !ok {
			imgDescr[id] = &imageDescriptor{}
		}

		if ref != nil {
			var tagged reference.NamedTagged
			if _, ok := ref.(reference.Canonical); ok {
				return
			}
			var ok bool
			if tagged, ok = ref.(reference.NamedTagged); !ok {
				var err error
				if tagged, err = reference.WithTag(ref, reference.DefaultTag); err != nil {
					return
				}
			}

			for _, t := range imgDescr[id].refs {
				if tagged.String() == t.String() {
					return
				}
			}
			imgDescr[id].refs = append(imgDescr[id].refs, tagged)
		}
	}

	for _, name := range names {
		id, ref, err := reference.ParseIDOrReference(name)
		if err != nil {
			return nil, err
		}
		if id != "" {
			_, err := l.is.Get(image.ID(id))
			if err != nil {
				return nil, err
			}
			addAssoc(image.ID(id), nil)
			continue
		}
		if ref.Name() == string(digest.Canonical) {
			imgID, err := l.is.Search(name)
			if err != nil {
				return nil, err
			}
			addAssoc(imgID, nil)
			continue
		}
		if reference.IsNameOnly(ref) {
			assocs := l.rs.ReferencesByName(ref)
			for _, assoc := range assocs {
				addAssoc(assoc.ImageID, assoc.Ref)
			}
			if len(assocs) == 0 {
				imgID, err := l.is.Search(name)
				if err != nil {
					return nil, err
				}
				addAssoc(imgID, nil)
			}
			continue
		}
		var imgID image.ID
		if imgID, err = l.rs.Get(ref); err != nil {
			return nil, err
		}
		addAssoc(imgID, ref)

	}
	return imgDescr, nil
}
Beispiel #8
0
func createContainer(ctx context.Context, dockerCli *command.DockerCli, config *container.Config, hostConfig *container.HostConfig, networkingConfig *networktypes.NetworkingConfig, cidfile, name string) (*types.ContainerCreateResponse, error) {
	stderr := dockerCli.Err()

	var containerIDFile *cidFile
	if cidfile != "" {
		var err error
		if containerIDFile, err = newCIDFile(cidfile); err != nil {
			return nil, err
		}
		defer containerIDFile.Close()
	}

	var trustedRef reference.Canonical
	_, ref, err := reference.ParseIDOrReference(config.Image)
	if err != nil {
		return nil, err
	}
	if ref != nil {
		ref = reference.WithDefaultTag(ref)

		if ref, ok := ref.(reference.NamedTagged); ok && command.IsTrusted() {
			var err error
			trustedRef, err = image.TrustedReference(ctx, dockerCli, ref)
			if err != nil {
				return nil, err
			}
			config.Image = trustedRef.String()
		}
	}

	//create the container
	response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, name)

	//if image not found try to pull it
	if err != nil {
		if apiclient.IsErrImageNotFound(err) && ref != nil {
			fmt.Fprintf(stderr, "Unable to find image '%s' locally\n", ref.String())

			// we don't want to write to stdout anything apart from container.ID
			if err = pullImage(ctx, dockerCli, config.Image, stderr); err != nil {
				return nil, err
			}
			if ref, ok := ref.(reference.NamedTagged); ok && trustedRef != nil {
				if err := image.TagTrusted(ctx, dockerCli, trustedRef, ref); err != nil {
					return nil, err
				}
			}
			// Retry
			var retryErr error
			response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, name)
			if retryErr != nil {
				return nil, retryErr
			}
		} else {
			return nil, err
		}
	}

	for _, warning := range response.Warnings {
		fmt.Fprintf(stderr, "WARNING: %s\n", warning)
	}
	if containerIDFile != nil {
		if err = containerIDFile.Write(response.ID); err != nil {
			return nil, err
		}
	}
	return &response, nil
}