示例#1
0
// ListImageTags returns the list of images instances obtained from all tags existing in the registry
func (c *DockerClient) ListImageTags(name string) (images []*imagename.ImageName, err error) {
	img := imagename.NewFromString(name)
	if img.Storage == imagename.StorageS3 {
		return c.s3storage.ListTags(name)
	}
	return dockerclient.RegistryListTags(imagename.NewFromString(name), c.auth)
}
示例#2
0
// resolveVersions walks through the list of images and resolves their tags in case they are not strict
func (client *DockerClient) resolveVersions(local, hub bool, vars template.Vars, containers []*Container) (err error) {

	// Provide function getter of all images to fetch only once
	var available []*imagename.ImageName
	getImages := func() ([]*imagename.ImageName, error) {
		if available == nil {
			available = []*imagename.ImageName{}

			if !local {
				return available, nil
			}

			// retrieving images currently available in docker
			var dockerImages []docker.APIImages
			if dockerImages, err = client.Docker.ListImages(docker.ListImagesOptions{}); err != nil {
				return nil, err
			}

			for _, image := range dockerImages {
				for _, repoTag := range image.RepoTags {
					available = append(available, imagename.NewFromString(repoTag))
				}
			}
		}
		return available, nil
	}

	resolved := map[string]*imagename.ImageName{}

	// check images for each container
	for _, container := range containers {
		// error in configuration, fail fast
		if container.Image == nil {
			err = fmt.Errorf("Image is not specified for the container: %s", container.Name)
			return
		}

		// Version specified in variables
		var k string
		k = fmt.Sprintf("v_image_%s", container.Image.NameWithRegistry())
		if tag, ok := vars[k]; ok {
			log.Infof("Resolve %s --> %s (derived by variable %s)", container.Image, tag, k)
			container.Image.SetTag(tag.(string))
		}
		k = fmt.Sprintf("v_container_%s", container.Name.Name)
		if tag, ok := vars[k]; ok {
			log.Infof("Resolve %s --> %s (derived by variable %s)", container.Image, tag, k)
			container.Image.SetTag(tag.(string))
		}

		// Do not resolve anything if the image is strict, e.g. "redis:2.8.11" or "redis:latest"
		if container.Image.IsStrict() {
			continue
		}

		// already resolved it for other container
		if _, ok := resolved[container.Image.String()]; ok {
			container.Image = resolved[container.Image.String()]
			continue
		}

		// Override to not change the common images slice
		var images []*imagename.ImageName
		if images, err = getImages(); err != nil {
			return err
		}

		// looking locally first
		candidate := container.Image.ResolveVersion(images, true)

		// in case we want to include external images as well, pulling list of available
		// images from repository or central docker hub
		if hub || candidate == nil {
			log.Debugf("Getting list of tags for %s from the registry", container.Image)

			var remote []*imagename.ImageName

			if container.Image.Storage == imagename.StorageS3 {
				s3storage := s3.New(client.Docker, os.TempDir())
				remote, err = s3storage.ListTags(container.Image.String())
			} else {
				remote, err = dockerclient.RegistryListTags(container.Image, client.Auth)
			}

			if err != nil {
				return fmt.Errorf("Failed to list tags of image %s for container %s from the remote registry, error: %s",
					container.Image, container.Name, err)
			}

			log.Debugf("remote: %v", remote)

			// Re-Resolve having hub tags
			candidate = container.Image.ResolveVersion(append(images, remote...), false)
		}

		if candidate == nil {
			err = fmt.Errorf("Image not found: %s", container.Image)
			return
		}
		candidate.IsOldS3Name = container.Image.IsOldS3Name

		log.Infof("Resolve %s --> %s", container.Image, candidate.GetTag())

		container.Image = candidate
		resolved[container.Image.String()] = candidate
	}

	return
}