Example #1
0
// CheckAndPull checks whether a Docker image exists. If not, it pulls it.
func (h *Helper) CheckAndPull(image string, out io.Writer) error {
	glog.V(5).Infof("Inspecting Docker image %q", image)
	imageMeta, err := h.client.InspectImage(image)
	if err == nil {
		glog.V(5).Infof("Image %q found: %#v", image, imageMeta)
		return nil
	}
	if err != docker.ErrNoSuchImage {
		return starterrors.NewError("unexpected error inspecting image %s", image).WithCause(err)
	}
	glog.V(5).Infof("Image %q not found. Pulling", image)
	fmt.Fprintf(out, "Pulling image %s\n", image)
	logProgress := func(s string) {
		fmt.Fprintf(out, "%s\n", s)
	}
	outputStream := imageprogress.NewPullWriter(logProgress)
	if glog.V(5) {
		outputStream = out
	}
	err = h.client.PullImage(docker.PullImageOptions{
		Repository:    image,
		RawJSONStream: bool(!glog.V(5)),
		OutputStream:  outputStream,
	}, docker.AuthConfiguration{})
	if err != nil {
		return starterrors.NewError("error pulling Docker image %s", image).WithCause(err)
	}
	fmt.Fprintf(out, "Image pull complete\n")
	return nil
}
Example #2
0
// LoadImage checks the client for an image matching from. If not found,
// attempts to pull the image and then tries to inspect again.
func (e *ClientExecutor) LoadImage(from string) (*docker.Image, error) {
	image, err := e.Client.InspectImage(from)
	if err == nil {
		return image, nil
	}
	if err != docker.ErrNoSuchImage {
		return nil, err
	}

	if !e.AllowPull {
		glog.V(4).Infof("image %s did not exist", from)
		return nil, docker.ErrNoSuchImage
	}

	repository, tag := docker.ParseRepositoryTag(from)
	if len(tag) == 0 {
		tag = "latest"
	}

	glog.V(4).Infof("attempting to pull %s with auth from repository %s:%s", from, repository, tag)

	// TODO: we may want to abstract looping over multiple credentials
	auth, _ := e.AuthFn(repository)
	if len(auth) == 0 {
		auth = append(auth, dockertypes.AuthConfig{})
	}

	if e.LogFn != nil {
		e.LogFn("Image %s was not found, pulling ...", from)
	}

	var lastErr error
	outputProgress := func(s string) {
		e.LogFn("%s", s)
	}
	for _, config := range auth {
		// TODO: handle IDs?
		pullImageOptions := docker.PullImageOptions{
			Repository:    repository,
			Tag:           tag,
			OutputStream:  imageprogress.NewPullWriter(outputProgress),
			RawJSONStream: true,
		}
		if glog.V(5) {
			pullImageOptions.OutputStream = os.Stderr
			pullImageOptions.RawJSONStream = false
		}
		authConfig := docker.AuthConfiguration{Username: config.Username, ServerAddress: config.ServerAddress, Password: config.Password}
		if err = e.Client.PullImage(pullImageOptions, authConfig); err == nil {
			break
		}
		lastErr = err
		continue
	}
	if lastErr != nil {
		return nil, fmt.Errorf("unable to pull image (from: %s, tag: %s): %v", repository, tag, lastErr)
	}

	return e.Client.InspectImage(from)
}
Example #3
0
func pullImage(client DockerClient, name string, authConfig docker.AuthConfiguration) error {
	logProgress := func(s string) {
		glog.V(0).Infof("%s", s)
	}
	opts := docker.PullImageOptions{
		Repository:    name,
		OutputStream:  imageprogress.NewPullWriter(logProgress),
		RawJSONStream: true,
	}
	if glog.Is(5) {
		opts.OutputStream = os.Stderr
		opts.RawJSONStream = false
	}
	err := client.PullImage(opts, authConfig)
	if err == nil {
		return nil
	}
	return err
}