Exemplo n.º 1
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)

}
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)
}
Exemplo n.º 3
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 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
}
Exemplo n.º 5
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
}