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) }
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 } }
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 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 }
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 }