Example #1
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, credentialprovider.LazyAuthConfiguration{})
	}

	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 #2
0
func (client *FSouza_NodeClient) Pull(logger log.Log, force bool) bool {
	image, tag := client.GetImageName()
	actionCacheTag := "pull:" + image + ":" + tag

	if _, ok := actionCache[actionCacheTag]; ok {
		logger.Message("Node image [" + image + ":" + tag + "] was just pulled, so not pulling it again.")
		return true
	}

	if !force && client.HasImage() {
		logger.Info("Node already has an image [" + image + ":" + tag + "], so not pulling it again.  You can force this operation if you want to pull this image.")
		return false
	}

	options := docker.PullImageOptions{
		Repository:    image,
		OutputStream:  logger,
		RawJSONStream: false,
	}

	if tag != "" {
		options.Tag = tag
	}

	var auth docker.AuthConfiguration
	// 		var ok bool
	//options.Registry = "https://index.docker.io/v1/"

	// 		auths, _ := docker.NewAuthConfigurationsFromDockerCfg()
	// 		if auth, ok = auths.Configs[registry]; ok {
	// 			options.Registry = registry
	// 		} else {
	// 			node.log.Warning("You have no local login credentials for any repo. Defaulting to no login.")
	auth = docker.AuthConfiguration{}
	options.Registry = "https://index.docker.io/v1/"
	// 		}

	logger.Message("Pulling node image [" + image + ":" + tag + "] from server [" + options.Registry + "] using auth [" + auth.Username + "] : " + image + ":" + tag)
	logger.Debug(log.VERBOSITY_DEBUG_LOTS, "AUTH USED: ", map[string]string{"Username": auth.Username, "Password": auth.Password, "Email": auth.Email, "ServerAdddress": auth.ServerAddress})

	// ask the docker client to build the image
	err := client.backend.PullImage(options, auth)

	if err != nil {
		logger.Error("Node image not pulled : " + image + " => " + err.Error())
		actionCache[actionCacheTag] = false
		return false
	} else {
		client.backend.Refresh(true, false)
		logger.Message("Node image pulled: " + image + ":" + tag)
		actionCache[actionCacheTag] = false
		return true
	}
}
Example #3
0
func (s *ServiceRuntime) PullImage(version, id string) (*docker.Image, error) {
	image, err := s.InspectImage(version)

	if err != nil && err != docker.ErrNoSuchImage {
		return nil, err
	}

	if image != nil && image.ID == id {
		return image, nil
	}

	registry, repository, tag := utils.SplitDockerImage(version)

	// No, pull it down locally
	pullOpts := docker.PullImageOptions{
		Repository:   repository,
		Tag:          tag,
		OutputStream: log.DefaultLogger}

	dockerAuth := findAuth(registry)

	if registry != "" {
		pullOpts.Repository = registry + "/" + repository
	} else {
		pullOpts.Repository = repository
	}
	pullOpts.Registry = registry
	pullOpts.Tag = tag

	retries := 0
	for {
		retries += 1
		err = s.dockerClient.PullImage(pullOpts, dockerAuth)
		if err != nil {

			// Don't retry 404, they'll never succeed
			if err.Error() == "HTTP code: 404" {
				return image, nil
			}

			if retries > 3 {
				return image, err
			}
			log.Errorf("ERROR: error pulling image %s. Attempt %d: %s", version, retries, err)
			continue
		}
		break
	}

	return s.InspectImage(version)

}
Example #4
0
func TestDliang(t *testing.T) {
	di := ConnectToDockerOrDie("")
	cl, err := di.ListContainers(docker.ListContainersOptions{})
	fmt.Println(cl, err)

	var opts docker.PullImageOptions
	opts.Repository = "nginx"
	opts.Registry = "gcr.io/google_containers"
	opts.Tag = "lastest"

	di.PullImage(opts, docker.AuthConfiguration{})

}
func pullImage(data *Data, client *dc.Client, image string) error {
	// TODO: Test local registry handling. It should be working
	// based on the code that was ported over

	pullOpts := dc.PullImageOptions{}

	splitImageName := strings.Split(image, ":")
	switch len(splitImageName) {

	// It's in registry:port/username/repo:tag or registry:port/repo:tag format
	case 3:
		splitPortRepo := strings.Split(splitImageName[1], "/")
		pullOpts.Registry = splitImageName[0] + ":" + splitPortRepo[0]
		pullOpts.Tag = splitImageName[2]
		pullOpts.Repository = pullOpts.Registry + "/" + strings.Join(splitPortRepo[1:], "/")

	// It's either registry:port/username/repo, registry:port/repo,
	// or repo:tag with default registry
	case 2:
		splitPortRepo := strings.Split(splitImageName[1], "/")
		switch len(splitPortRepo) {
		// repo:tag
		case 1:
			pullOpts.Repository = splitImageName[0]
			pullOpts.Tag = splitImageName[1]

		// registry:port/username/repo or registry:port/repo
		default:
			pullOpts.Registry = splitImageName[0] + ":" + splitPortRepo[0]
			pullOpts.Repository = pullOpts.Registry + "/" + strings.Join(splitPortRepo[1:], "/")
			pullOpts.Tag = "latest"
		}

	// Plain username/repo or repo
	default:
		pullOpts.Repository = image
	}

	if err := client.PullImage(pullOpts, dc.AuthConfiguration{}); err != nil {
		return fmt.Errorf("Error pulling image %s: %s\n", image, err)
	}

	return fetchLocalImages(data, client)
}
Example #6
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
}
Example #7
0
// PullImage will pull the localkube image on the connected Docker daemon
func (d *Controller) PullImage(imageTag string, silent bool) error {
	pullOpts := docker.PullImageOptions{
		Repository: LocalkubeImageName,
		Tag:        imageTag,
	}

	in, out := io.Pipe()
	// print pull progress if not silent
	if !silent {
		pullOpts.RawJSONStream = true
		pullOpts.OutputStream = out
		outFd, isTerminal := term.GetFdInfo(d.out)
		go jsonmessage.DisplayJSONMessagesStream(in, d.out, outFd, isTerminal)
	}

	err := d.Client.PullImage(pullOpts, docker.AuthConfiguration{})
	if err != nil {
		return fmt.Errorf("failed to pull localkube image: %v", err)
	}
	return nil
}
func parseImageOptions(image string) dc.PullImageOptions {
	pullOpts := dc.PullImageOptions{}

	splitImageName := strings.Split(image, ":")
	switch len(splitImageName) {

	// It's in registry:port/username/repo:tag or registry:port/repo:tag format
	case 3:
		splitPortRepo := strings.Split(splitImageName[1], "/")
		pullOpts.Registry = splitImageName[0] + ":" + splitPortRepo[0]
		pullOpts.Tag = splitImageName[2]
		pullOpts.Repository = pullOpts.Registry + "/" + strings.Join(splitPortRepo[1:], "/")

	// It's either registry:port/username/repo, registry:port/repo,
	// or repo:tag with default registry
	case 2:
		splitPortRepo := strings.Split(splitImageName[1], "/")
		switch len(splitPortRepo) {
		// repo:tag
		case 1:
			pullOpts.Repository = splitImageName[0]
			pullOpts.Tag = splitImageName[1]

		// registry:port/username/repo or registry:port/repo
		default:
			pullOpts.Registry = splitImageName[0] + ":" + splitPortRepo[0]
			pullOpts.Repository = pullOpts.Registry + "/" + strings.Join(splitPortRepo[1:], "/")
			pullOpts.Tag = "latest"
		}

	// Plain username/repo or repo
	default:
		pullOpts.Repository = image
	}

	return pullOpts
}
Example #9
0
func (this *DockerClientEng1) Run(unit *core.Unit, callbackFunc func(*core.Dockerd, int, ...interface{})) error {

	hostConfig := &docker.HostConfig{}
	config := &docker.Config{
		Image: unit.Image,
	}
	createContainerOptions := &docker.CreateContainerOptions{
		Name:       unit.Name,
		Config:     config,
		HostConfig: hostConfig,
	}
	containerCreateResponse := &types.ContainerCreateResponse{}

	/*
		解析Unit参数
		Config 是 create 所需的参数
		HostConfig 是 run 所需的参数
		这是 go-dockerclient 所定义的
		参考:https://github.com/Tonnu/go-dockerclient/blob/master/container.go

		当前用单线程来和所有的dockerd交互,到时候要改成携程。
	*/
	for _, p := range unit.Parameteres {
		switch p.Type {
		case "v": //-v Volume
			hostConfig.Binds = append(hostConfig.Binds, p.Value)
		case "p": //-p EXPOSE
			rePort := regexp.MustCompile(".+/.+")
			// 127.0.0.1:80:8080
			re3 := regexp.MustCompile("(.+):(.+):(.+)")
			if re3.MatchString(p.Value) {
				t := re3.FindStringSubmatch(p.Value)
				portBinding := &docker.PortBinding{
					HostIP:   t[1],
					HostPort: t[2],
				}
				var containerPort string
				if rePort.MatchString(t[3]) {
					containerPort = t[3]
				} else {
					containerPort = fmt.Sprintf("%s/tcp", t[3])
				}
				hostConfig.PortBindings = make(map[docker.Port][]docker.PortBinding)
				hostConfig.PortBindings[docker.Port(containerPort)] = append(hostConfig.PortBindings[docker.Port(containerPort)], *portBinding)
				break
			}
			//80:8080
			re2 := regexp.MustCompile("(.+):(.+)")
			if re2.MatchString(p.Value) {
				t := re2.FindStringSubmatch(p.Value)
				portBinding := &docker.PortBinding{
					HostPort: t[1],
				}
				hostConfig.PortBindings = make(map[docker.Port][]docker.PortBinding)
				hostConfig.PortBindings[docker.Port(t[2])] = append(hostConfig.PortBindings[docker.Port(t[2])], *portBinding)
				break
			}
			re1 := regexp.MustCompile("(.+)")
			if re1.MatchString(p.Value) {
				t := re2.FindStringSubmatch(p.Value)
				portBinding := &docker.PortBinding{}
				hostConfig.PortBindings = make(map[docker.Port][]docker.PortBinding)
				hostConfig.PortBindings[docker.Port(t[1])] = append(hostConfig.PortBindings[docker.Port(t[1])], *portBinding)
				break
			}
		}
	}

	//强行从registry pull最新版本的image
	pullImageOptions := docker.PullImageOptions{}
	// registry.ws.com/cst05001/nginx:latest
	reImage3 := regexp.MustCompile("^(.*\\.\\w+)(/.*):(.*)")
	// /cst05001/nginx:latest
	reImage2 := regexp.MustCompile("^(/.*):(.*)")
	if reImage3.MatchString(unit.Image) {
		result := reImage3.FindStringSubmatch(unit.Image)
		pullImageOptions.Registry = result[1]
		pullImageOptions.Repository = result[2]
		pullImageOptions.Tag = result[3]
	} else if reImage2.MatchString(unit.Image) {
		result := reImage2.FindStringSubmatch(unit.Image)
		pullImageOptions.Registry = "http://docker.io"
		pullImageOptions.Repository = result[1]
		pullImageOptions.Tag = result[2]
	} else {
		pullImageOptions.Registry = "http://docker.io"
		pullImageOptions.Repository = unit.Image
		pullImageOptions.Tag = "latest"
	}

	for ptrDockerd, ptrClient := range this.ClientMap {
		dockerd := &(*ptrDockerd)
		client := &(*ptrClient)
		go func() {
			//第二个参数支持registry身份认证,还没处理。
			err := client.PullImage(pullImageOptions, docker.AuthConfiguration{})
			if err != nil {
				beego.Error("Pull image ", pullImageOptions.Registry, pullImageOptions.Repository,
					pullImageOptions.Tag, " at ", dockerd.GetIP(), " failed: ", err)
				return
			}
			beego.Debug("Pull image ", pullImageOptions.Registry,
				pullImageOptions.Repository, pullImageOptions.Tag, " at ", dockerd.GetIP(), " successed.")

			container, err := client.CreateContainer(*createContainerOptions)
			if err != nil {
				beego.Error("Create container at ", dockerd.GetIP(), " failed: ", err)
				containerCreateResponse.Warnings = append(containerCreateResponse.Warnings, err.Error())
				callbackFunc(dockerd, dockerdengine.STATUS_ON_CREATE_FAILED, unit)
				return
			}
			containerCreateResponse.ID = container.ID
			callbackFunc(dockerd, dockerdengine.STATUS_ON_CREATE_SUCCESSED, unit)

			// start container
			err = client.StartContainer(containerCreateResponse.ID, hostConfig)
			if err != nil {
				beego.Error("Start container at ", dockerd.GetIP(), " failed: ", err)
				callbackFunc(dockerd, dockerdengine.STATUS_ON_RUN_FAILED, unit)
				return
			}
			beego.Debug("StartContainer at ", dockerd.GetIP(), " successed")
			callbackFunc(dockerd, dockerdengine.STATUS_ON_RUN_SUCCESSED, unit)
		}()
	}
	return nil
}