Exemple #1
0
//return a registrySession associated with the repository contained in imageName
func newRegistrySession(userName, password string) (*registrySession, error) {
	//IndexInfo
	indexInfo := &registry.IndexInfo{
		Name:     registry.INDEXNAME,
		Mirrors:  []string{},
		Secure:   true,
		Official: true,
	}

	endpoint, err := registry.NewEndpoint(indexInfo)
	if err != nil {
		return nil, err
	}
	fmt.Printf("Index endpoint: %s\n", endpoint)

	authConfig := &registry.AuthConfig{Username: userName, Password: password}

	var metaHeaders map[string][]string

	session, err := registry.NewSession(authConfig, registry.HTTPRequestFactory(metaHeaders), endpoint, true)
	if err != nil {
		return nil, fmt.Errorf("failed to create registry session: %v", err)
	}

	return &registrySession{*session, indexInfo}, nil
}
Exemple #2
0
// FIXME: Allow to interrupt current push when new push of same image is done.
func (s *TagStore) CmdPush(job *engine.Job) engine.Status {
	if n := len(job.Args); n != 1 {
		return job.Errorf("Usage: %s IMAGE", job.Name)
	}
	var (
		localName   = job.Args[0]
		sf          = utils.NewStreamFormatter(job.GetenvBool("json"))
		authConfig  = &registry.AuthConfig{}
		metaHeaders map[string][]string
	)

	tag := job.Getenv("tag")
	job.GetenvJson("authConfig", authConfig)
	job.GetenvJson("metaHeaders", &metaHeaders)
	if _, err := s.poolAdd("push", localName); err != nil {
		return job.Error(err)
	}
	defer s.poolRemove("push", localName)

	// Resolve the Repository name from fqn to endpoint + name
	hostname, remoteName, err := registry.ResolveRepositoryName(localName)
	if err != nil {
		return job.Error(err)
	}

	endpoint, err := registry.NewEndpoint(hostname, s.insecureRegistries)
	if err != nil {
		return job.Error(err)
	}

	img, err := s.graph.Get(localName)
	r, err2 := registry.NewSession(authConfig, registry.HTTPRequestFactory(metaHeaders), endpoint, false)
	if err2 != nil {
		return job.Error(err2)
	}

	if err != nil {
		reposLen := 1
		if tag == "" {
			reposLen = len(s.Repositories[localName])
		}
		job.Stdout.Write(sf.FormatStatus("", "The push refers to a repository [%s] (len: %d)", localName, reposLen))
		// If it fails, try to get the repository
		if localRepo, exists := s.Repositories[localName]; exists {
			if err := s.pushRepository(r, job.Stdout, localName, remoteName, localRepo, tag, sf); err != nil {
				return job.Error(err)
			}
			return engine.StatusOK
		}
		return job.Error(err)
	}

	var token []string
	job.Stdout.Write(sf.FormatStatus("", "The push refers to an image: [%s]", localName))
	if _, err := s.pushImage(r, job.Stdout, remoteName, img.ID, endpoint.String(), token, sf); err != nil {
		return job.Error(err)
	}
	return engine.StatusOK
}
Exemple #3
0
func configureV2Mirror(repoInfo *registry.RepositoryInfo, s *registry.Service) (*registry.Endpoint, *registry.RepositoryInfo, error) {
	mirrors := repoInfo.Index.Mirrors

	if len(mirrors) == 0 {
		// no mirrors configured
		return nil, nil, nil
	}

	v1MirrorCount := 0
	var v2MirrorEndpoint *registry.Endpoint
	var v2MirrorRepoInfo *registry.RepositoryInfo
	var lastErr error
	for _, mirror := range mirrors {
		mirrorRepoInfo := makeMirrorRepoInfo(repoInfo, mirror)
		endpoint, err := registry.NewEndpoint(mirrorRepoInfo.Index, nil)
		if err != nil {
			logrus.Errorf("Unable to create endpoint for %s: %s", mirror, err)
			lastErr = err
			continue
		}
		if endpoint.Version == 2 {
			if v2MirrorEndpoint == nil {
				v2MirrorEndpoint = endpoint
				v2MirrorRepoInfo = mirrorRepoInfo
			} else {
				// > 1 v2 mirrors given
				return nil, nil, fmt.Errorf("multiple v2 mirrors configured")
			}
		} else {
			v1MirrorCount++
		}
	}

	if v1MirrorCount == len(mirrors) {
		// OK, but mirrors are v1
		return nil, nil, nil
	}
	if v2MirrorEndpoint != nil && v1MirrorCount == 0 {
		// OK, 1 v2 mirror specified
		return v2MirrorEndpoint, v2MirrorRepoInfo, nil
	}
	if v2MirrorEndpoint != nil && v1MirrorCount > 0 {
		lastErr = fmt.Errorf("v1 and v2 mirrors configured")
	}
	return nil, nil, lastErr
}
func (factory *dockerSessionFactory) MakeSession(reposName string, allowInsecure bool) (DockerSession, error) {
	repositoryInfo, err := registry.ParseRepositoryInfo(reposName)
	if err != nil {
		return nil, fmt.Errorf("Error resolving Docker repository name:\n" + err.Error())
	}

	if allowInsecure {
		repositoryInfo.Index.Secure = false
	}
	endpoint, err := registry.NewEndpoint(repositoryInfo.Index, nil, registry.APIVersionUnknown)
	if err != nil {
		return nil, fmt.Errorf("Error Connecting to Docker registry:\n" + err.Error())
	}
	authConfig := &cliconfig.AuthConfig{}
	session, error := registry.NewSession(http.DefaultClient, authConfig, endpoint)
	return session, error
}
Exemple #5
0
func configureV2Mirror(repoInfo *registry.RepositoryInfo, s *registry.Service) (*registry.Endpoint, *registry.RepositoryInfo, error) {
	mirrors := repoInfo.Index.Mirrors
	if len(mirrors) == 0 {
		// no mirrors configured
		return nil, nil, nil
	}

	v1MirrorCount := 0
	var v2MirrorEndpoint *registry.Endpoint
	var v2MirrorRepoInfo *registry.RepositoryInfo
	for _, mirror := range mirrors {
		mirrorRepoInfo := makeMirrorRepoInfo(repoInfo, mirror)
		endpoint, err := registry.NewEndpoint(mirrorRepoInfo.Index, nil)
		if err != nil {
			logrus.Errorf("Unable to create endpoint for %s: %s", mirror, err)
			continue
		}
		if endpoint.Version == 2 {
			if v2MirrorEndpoint == nil {
				v2MirrorEndpoint = endpoint
				v2MirrorRepoInfo = mirrorRepoInfo
			} else {
				// > 1 v2 mirrors given
				return nil, nil, fmt.Errorf("multiple v2 mirrors configured")
			}
		} else {
			v1MirrorCount++
		}
	}

	if v1MirrorCount == len(mirrors) {
		// OK, but mirrors are v1
		return nil, nil, nil
	}
	if v2MirrorEndpoint != nil && v1MirrorCount == 0 {
		// OK, 1 v2 mirror specified
		return v2MirrorEndpoint, v2MirrorRepoInfo, nil
	}
	if v2MirrorEndpoint != nil && v1MirrorCount > 0 {
		return nil, nil, fmt.Errorf("v1 and v2 mirrors configured")
	}
	// No endpoint could be established with the given mirror configurations
	// Fallback to pulling from the hub as per v1 behavior.
	return nil, nil, nil
}
Exemple #6
0
func (s *TagStore) CmdPull(job *engine.Job) engine.Status {
	if n := len(job.Args); n != 1 && n != 2 {
		return job.Errorf("Usage: %s IMAGE [TAG]", job.Name)
	}

	var (
		localName   = job.Args[0]
		tag         string
		sf          = utils.NewStreamFormatter(job.GetenvBool("json"))
		authConfig  = &registry.AuthConfig{}
		metaHeaders map[string][]string
		mirrors     []string
	)

	if len(job.Args) > 1 {
		tag = job.Args[1]
	}

	job.GetenvJson("authConfig", authConfig)
	job.GetenvJson("metaHeaders", &metaHeaders)

	c, err := s.poolAdd("pull", localName+":"+tag)
	if err != nil {
		if c != nil {
			// Another pull of the same repository is already taking place; just wait for it to finish
			job.Stdout.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName))
			<-c
			return engine.StatusOK
		}
		return job.Error(err)
	}
	defer s.poolRemove("pull", localName+":"+tag)

	// Resolve the Repository name from fqn to endpoint + name
	hostname, remoteName, err := registry.ResolveRepositoryName(localName)
	if err != nil {
		return job.Error(err)
	}

	endpoint, err := registry.NewEndpoint(hostname, s.insecureRegistries)
	if err != nil {
		return job.Error(err)
	}

	r, err := registry.NewSession(authConfig, registry.HTTPRequestFactory(metaHeaders), endpoint, true)
	if err != nil {
		return job.Error(err)
	}

	var isOfficial bool
	if endpoint.VersionString(1) == registry.IndexServerAddress() {
		// If pull "index.docker.io/foo/bar", it's stored locally under "foo/bar"
		localName = remoteName

		isOfficial = isOfficialName(remoteName)
		if isOfficial && strings.IndexRune(remoteName, '/') == -1 {
			remoteName = "library/" + remoteName
		}
	}
	// Use provided mirrors, if any
	mirrors = s.mirrors

	if len(mirrors) == 0 && (isOfficial || endpoint.Version == registry.APIVersion2) {
		j := job.Eng.Job("trust_update_base")
		if err = j.Run(); err != nil {
			return job.Errorf("error updating trust base graph: %s", err)
		}

		if err := s.pullV2Repository(job.Eng, r, job.Stdout, localName, remoteName, tag, sf, job.GetenvBool("parallel")); err == nil {
			return engine.StatusOK
		} else if err != registry.ErrDoesNotExist {
			log.Errorf("Error from V2 registry: %s", err)
		}
	}

	if err = s.pullRepository(r, job.Stdout, localName, remoteName, tag, sf, job.GetenvBool("parallel"), mirrors); err != nil {
		return job.Error(err)
	}

	return engine.StatusOK
}
Exemple #7
0
func (s *TagStore) CmdPullAndApply(job *engine.Job) engine.Status {
	if n := len(job.Args); n != 4 {
		return job.Errorf("Usage: %s CONTAINERID CONTAINERIMAGE IMAGE TAG", job.Name)
	}

	var (
		containerID    = job.Args[0]
		containerImage = job.Args[1]
		localName      = job.Args[2]
		tag            = job.Args[3]
		sf             = utils.NewStreamFormatter(job.GetenvBool("json"))
		authConfig     = &registry.AuthConfig{}
		metaHeaders    map[string][]string
		mirrors        []string
	)

	job.GetenvJson("authConfig", authConfig)
	job.GetenvJson("metaHeaders", &metaHeaders)

	for {
		c, err := s.poolAdd("pull", localName+":"+tag)
		if err != nil {
			if c != nil {
				// Another pull of the same repository is already taking place; just wait for it to finish
				job.Stdout.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName))
				<-c
				continue
			} else {
				return job.Error(err)
			}
		}
		break
	}
	defer s.poolRemove("pull", localName+":"+tag)

	// Resolve the Repository name from fqn to endpoint + name
	hostname, remoteName, err := registry.ResolveRepositoryName(localName)
	if err != nil {
		return job.Error(err)
	}

	endpoint, err := registry.NewEndpoint(hostname, s.insecureRegistries)
	if err != nil {
		return job.Error(err)
	}

	r, err := registry.NewSession(authConfig, registry.HTTPRequestFactory(metaHeaders), endpoint, true)
	if err != nil {
		return job.Error(err)
	}

	if endpoint.VersionString(1) == registry.IndexServerAddress() {
		// If pull "index.docker.io/foo/bar", it's stored locally under "foo/bar"
		localName = remoteName
		isOfficial := isOfficialName(remoteName)
		if isOfficial && strings.IndexRune(remoteName, '/') == -1 {
			remoteName = "library/" + remoteName
		}
	}
	// Use provided mirrors, if any
	mirrors = s.mirrors

	if err = s.pullMRepository(r, job.Stdout, containerID, containerImage, localName, remoteName, tag, sf, job.GetenvBool("parallel"), mirrors); err != nil {
		return job.Error(err)
	}

	return engine.StatusOK
}
			"GET", "/v2/",
			http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
				w.Header().Set("Docker-Distribution-API-Version", "registry/2.0")
				w.Write([]byte(`{}`))
			}),
		)
		server.RouteToHandler(
			"GET", "/v1/_ping",
			http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
				w.WriteHeader(404)
			}),
		)

		registryAddr = server.HTTPTestServer.Listener.Addr().String()
		endpoint, err := registry.NewEndpoint(&registry.IndexInfo{
			Name:   registryAddr,
			Secure: false,
		}, nil)
		Expect(err).ToNot(HaveOccurred())

		tr := transport.NewTransport(
			registry.NewTransport(registry.ReceiveTimeout, endpoint.IsSecure),
		)
		session, err := registry.NewSession(registry.HTTPClient(tr), &cliconfig.AuthConfig{}, endpoint)
		Expect(err).ToNot(HaveOccurred())

		fetchRequest = &FetchRequest{
			Session:    session,
			Endpoint:   endpoint,
			Logger:     logger,
			Path:       "some-repo",
			RemotePath: "some-repo",