func (c *Cluster) PullImage(opts docker.PullImageOptions, auth docker.AuthConfiguration, nodes ...string) error {
	var w safe.Buffer
	if opts.OutputStream != nil {
		mw := io.MultiWriter(&w, opts.OutputStream)
		opts.OutputStream = mw
	} else {
		opts.OutputStream = &w
	}
	key := imageKey(opts.Repository, opts.Tag)
	_, err := c.runOnNodes(func(n node) (interface{}, error) {
		n.setPersistentClient()
		err := n.PullImage(opts, auth)
		if err != nil {
			return nil, err
		}
		img, err := n.InspectImage(key)
		if err != nil {
			return nil, err
		}
		return nil, c.storage().StoreImage(key, img.ID, n.addr)
	}, docker.ErrNoSuchImage, true, nodes...)
	if err != nil {
		return err
	}
	digest, _ := fix.GetImageDigest(w.String())
	return c.storage().SetImageDigest(key, digest)
}
PullImage pulls an image from a remote registry server, returning an error
in case of failure.

It will pull all images in parallel, so users need to make sure that the
given buffer is safe.
package cluster
import (
	"errors"
	"fmt"
	"io"
	"math/rand"
	"net"
	"strings"
	"sync"
	"github.com/fsouza/go-dockerclient"
	"github.com/tsuru/tsuru/provision/docker/fix"
	"github.com/tsuru/tsuru/safe"
)
type ImageHistory struct {
	Node    string
	ImageId string
}
type Image struct {
	Repository string `bson:"_id"`
	LastNode   string
	LastId     string
	LastDigest string
	History    []ImageHistory
}
func (c *Cluster) RemoveImage(name string) error {
	stor := c.storage()
	image, err := stor.RetrieveImage(name)
	if err != nil {
		return err
	}
	hosts := []string{}
	idMap := map[string][]string{}
	for _, entry := range image.History {
		_, isOld := idMap[entry.Node]
		idMap[entry.Node] = append(idMap[entry.Node], entry.ImageId)
		if !isOld {
			hosts = append(hosts, entry.Node)
		}
	}
	_, err = c.runOnNodes(func(n node) (interface{}, error) {
		imgIds, _ := idMap[n.addr]
		err = n.RemoveImage(name)
		_, isNetErr := err.(net.Error)
		if err == docker.ErrConnectionRefused {
			isNetErr = true
		}
		if err != nil && err != docker.ErrNoSuchImage && !isNetErr {
			return nil, err
		}
		for _, imgId := range imgIds {
			n.RemoveImage(imgId)
			stor.RemoveImage(name, imgId, n.addr)
		}
		return nil, nil
	}, docker.ErrNoSuchImage, true, hosts...)
	return err
}
func parseImageRegistry(imageId string) (string, string) {
	parts := strings.SplitN(imageId, "/", 3)
	if len(parts) < 3 {
		if len(parts) == 2 && (strings.ContainsAny(parts[0], ":.") || parts[0] == "localhost") {
			return parts[0], parts[1]
		}
		return "", strings.Join(parts, "/")
	}
	return parts[0], strings.Join(parts[1:], "/")
}