func (cli *HyperClient) requestWithLogin(index *registrytypes.IndexInfo, op AuthRequest, opTag string) (io.ReadCloser, string, int, error) { authConfig := registry.ResolveAuthConfig(cli.configFile.AuthConfigs, index) body, ctype, statusCode, err := op(authConfig) if statusCode == http.StatusUnauthorized { fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", opTag) if err = cli.HyperCmdLogin(registry.GetAuthConfigKey(index)); err != nil { return nil, "", -1, err } authConfig = registry.ResolveAuthConfig(cli.configFile.AuthConfigs, index) return op(authConfig) } return body, ctype, statusCode, err }
func (cli *DockerCli) clientRequestAttemptLogin(method, path string, in io.Reader, out io.Writer, index *registry.IndexInfo, cmdName string) (io.ReadCloser, int, error) { // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile, index) body, statusCode, err := cli.cmdAttempt(authConfig, method, path, in, out) if statusCode == http.StatusUnauthorized { fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName) if err = cli.CmdLogin(index.GetAuthConfigKey()); err != nil { return nil, -1, err } authConfig = registry.ResolveAuthConfig(cli.configFile, index) return cli.cmdAttempt(authConfig, method, path, in, out) } return body, statusCode, err }
// CmdPush pushes an image or repository to the registry. // // Usage: docker push NAME[:TAG] func (cli *DockerCli) CmdPush(args ...string) error { cmd := Cli.Subcmd("push", []string{"NAME[:TAG]"}, Cli.DockerCommands["push"].Description, true) addTrustedFlags(cmd, false) cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) ref, err := reference.ParseNamed(cmd.Arg(0)) if err != nil { return err } var tag string switch x := ref.(type) { case reference.Canonical: return errors.New("cannot push a digest reference") case reference.NamedTagged: tag = x.Tag() } // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile.AuthConfigs, repoInfo.Index) requestPrivilege := cli.registryAuthenticationPrivilegedFunc(repoInfo.Index, "push") if isTrusted() { return cli.trustedPush(repoInfo, tag, authConfig, requestPrivilege) } return cli.imagePushPrivileged(authConfig, ref.Name(), tag, cli.out, requestPrivilege) }
func (cli *DockerCli) trustedReference(ref reference.NamedTagged) (reference.Canonical, error) { repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return nil, err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile.AuthConfigs, repoInfo.Index) notaryRepo, err := cli.getNotaryRepository(repoInfo, authConfig) if err != nil { fmt.Fprintf(cli.out, "Error establishing connection to trust repository: %s\n", err) return nil, err } t, err := notaryRepo.GetTargetByName(ref.Tag(), releasesRole, data.CanonicalTargetsRole) if err != nil { return nil, err } r, err := convertTarget(t.Target) if err != nil { return nil, err } return reference.WithDigest(ref, r.digest) }
func (cli *DockerCli) trustedReference(repo string, ref registry.Reference) (registry.Reference, error) { repoInfo, err := registry.ParseRepositoryInfo(repo) if err != nil { return nil, err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index) notaryRepo, err := cli.getNotaryRepository(repoInfo, authConfig) if err != nil { fmt.Fprintf(cli.out, "Error establishing connection to trust repository: %s\n", err) return nil, err } t, err := notaryRepo.GetTargetByName(ref.String()) if err != nil { return nil, err } r, err := convertTarget(*t) if err != nil { return nil, err } return registry.DigestReference(r.digest), nil }
// Pull tells Docker to pull image referenced by `name`. func (d Docker) Pull(name string) (*image.Image, error) { remote, tag := parsers.ParseRepositoryTag(name) if tag == "" { tag = "latest" } pullRegistryAuth := &cliconfig.AuthConfig{} if len(d.AuthConfigs) > 0 { // The request came with a full auth config file, we prefer to use that repoInfo, err := d.Daemon.RegistryService.ResolveRepository(remote) if err != nil { return nil, err } resolvedConfig := registry.ResolveAuthConfig( &cliconfig.ConfigFile{AuthConfigs: d.AuthConfigs}, repoInfo.Index, ) pullRegistryAuth = &resolvedConfig } imagePullConfig := &graph.ImagePullConfig{ AuthConfig: pullRegistryAuth, OutStream: ioutils.NopWriteCloser(d.OutOld), } if err := d.Daemon.PullImage(remote, tag, imagePullConfig); err != nil { return nil, err } return d.Daemon.GetImage(name) }
func (c *Container) pull(image string) error { taglessRemote, tag := parsers.ParseRepositoryTag(image) if tag == "" { image = utils.ImageReference(taglessRemote, DefaultTag) } repoInfo, err := registry.ParseRepositoryInfo(taglessRemote) if err != nil { return err } authConfig := cliconfig.AuthConfig{} if c.service.context.ConfigFile != nil && repoInfo != nil && repoInfo.Index != nil { authConfig = registry.ResolveAuthConfig(c.service.context.ConfigFile, repoInfo.Index) } err = c.client.PullImage( dockerclient.PullImageOptions{ Repository: image, OutputStream: os.Stderr, // TODO maybe get the stream from some configured place }, dockerclient.AuthConfiguration{ Username: authConfig.Username, Password: authConfig.Password, Email: authConfig.Email, }, ) if err != nil { logrus.Errorf("Failed to pull image %s: %v", image, err) } return err }
func (b *Builder) pullImage(name string) (*imagepkg.Image, error) { remote, tag := parsers.ParseRepositoryTag(name) if tag == "" { tag = "latest" } pullRegistryAuth := b.AuthConfig if len(b.ConfigFile.AuthConfigs) > 0 { // The request came with a full auth config file, we prefer to use that repoInfo, err := b.Daemon.RegistryService.ResolveRepository(remote) if err != nil { return nil, err } resolvedAuth := registry.ResolveAuthConfig(b.ConfigFile, repoInfo.Index) pullRegistryAuth = &resolvedAuth } imagePullConfig := &graph.ImagePullConfig{ AuthConfig: pullRegistryAuth, OutStream: ioutils.NopWriteCloser(b.OutOld), } if err := b.Daemon.Repositories().Pull(remote, tag, imagePullConfig); err != nil { return nil, err } image, err := b.Daemon.Repositories().LookupImage(name) if err != nil { return nil, err } return image, nil }
func (c *Container) pull(image string) error { taglessRemote, tag := parsers.ParseRepositoryTag(image) if tag == "" { image = utils.ImageReference(taglessRemote, tags.DEFAULTTAG) } repoInfo, err := registry.ParseRepositoryInfo(taglessRemote) if err != nil { return err } authConfig := cliconfig.AuthConfig{} if c.service.context.ConfigFile != nil && repoInfo != nil && repoInfo.Index != nil { authConfig = registry.ResolveAuthConfig(c.service.context.ConfigFile, repoInfo.Index) } err = c.client.PullImage(image, &dockerclient.AuthConfig{ Username: authConfig.Username, Password: authConfig.Password, Email: authConfig.Email, }) if err != nil { logrus.Errorf("Failed to pull image %s: %v", image, err) } return err }
// Pull tells Docker to pull image referenced by `name`. func (d Docker) Pull(name string) (builder.Image, error) { ref, err := reference.ParseNamed(name) if err != nil { return nil, err } ref = reference.WithDefaultTag(ref) pullRegistryAuth := &types.AuthConfig{} if len(d.AuthConfigs) > 0 { // The request came with a full auth config file, we prefer to use that repoInfo, err := d.Daemon.RegistryService.ResolveRepository(ref) if err != nil { return nil, err } resolvedConfig := registry.ResolveAuthConfig( d.AuthConfigs, repoInfo.Index, ) pullRegistryAuth = &resolvedConfig } if err := d.Daemon.PullImage(ref, nil, pullRegistryAuth, ioutils.NopWriteCloser(d.OutOld)); err != nil { return nil, err } return d.GetImage(name) }
// PullOnBuild tells Docker to pull image referenced by `name`. func (daemon *Daemon) PullOnBuild(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer) (builder.Image, error) { ref, err := reference.ParseNamed(name) if err != nil { return nil, err } ref = reference.WithDefaultTag(ref) pullRegistryAuth := &types.AuthConfig{} if len(authConfigs) > 0 { // The request came with a full auth config file, we prefer to use that repoInfo, err := daemon.RegistryService.ResolveRepository(ref) if err != nil { return nil, err } resolvedConfig := registry.ResolveAuthConfig( authConfigs, repoInfo.Index, ) pullRegistryAuth = &resolvedConfig } if err := daemon.pullImageWithReference(ctx, ref, nil, pullRegistryAuth, output); err != nil { return nil, err } return daemon.GetImage(name) }
func getAuthConfig(c *cli.Context, index *registryTypes.IndexInfo) (engineTypes.AuthConfig, error) { var ( username = c.GlobalString("username") password = c.GlobalString("password") cfg = c.GlobalString("docker-cfg") defAuthConfig = engineTypes.AuthConfig{ Username: c.GlobalString("username"), Password: c.GlobalString("password"), Email: "*****@*****.**", } ) // // FINAL TODO(runcom): avoid returning empty config! just fallthrough and return // the first useful authconfig // // TODO(runcom): ??? atomic needs this // TODO(runcom): implement this to opt-in for docker-cfg, no need to make this // work by default with docker's conf //useDockerConf := c.GlobalString("use-docker-cfg") if username != "" && password != "" { return defAuthConfig, nil } confFile, err := cliconfig.Load(cfg) if err != nil { return engineTypes.AuthConfig{}, err } authConfig := registry.ResolveAuthConfig(confFile.AuthConfigs, index) logrus.Debugf("authConfig for %s: %v", index.Name, authConfig) return authConfig, nil }
// CmdPush pushes an image or repository to the registry. // // Usage: docker push NAME[:TAG] func (cli *DockerCli) CmdPush(args ...string) error { cmd := cli.Subcmd("push", []string{"NAME[:TAG]"}, "Push an image or a repository to a registry", true) cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) name := cmd.Arg(0) remote, tag := parsers.ParseRepositoryTag(name) // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(remote) if err != nil { return err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index) // If we're not using a custom registry, we know the restrictions // applied to repository names and can warn the user in advance. // Custom repositories can have different rules, and we must also // allow pushing by image ID. if repoInfo.Official { username := authConfig.Username if username == "" { username = "******" } return fmt.Errorf("You cannot push a \"root\" repository. Please rename your repository to <user>/<repo> (ex: %s/%s)", username, repoInfo.LocalName) } v := url.Values{} v.Set("tag", tag) _, _, err = cli.clientRequestAttemptLogin("POST", "/images/"+remote+"/push?"+v.Encode(), nil, cli.out, repoInfo.Index, "push") return err }
// CmdPush pushes an image or repository to the registry. // // Usage: hyperctl push NAME[:TAG] func (cli *HyperClient) HyperCmdPush(args ...string) error { var parser = gflag.NewParser(nil, gflag.Default) parser.Usage = "push NAME[:TAG]\n\nPush an image to a Docker registry server" args, err := parser.ParseArgs(args) if err != nil { if !strings.Contains(err.Error(), "Usage") { return err } else { return nil } } // we need to get the image name which will be used to create a container if len(args) == 0 { return fmt.Errorf("\"push\" requires a minimum of 1 argument, please provide the image name.") } name := args[0] ref, err := reference.ParseNamed(name) if err != nil { return err } var tag string switch x := ref.(type) { case reference.Canonical: return fmt.Errorf("cannot push a digest reference") case reference.NamedTagged: tag = x.Tag() } // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile.AuthConfigs, repoInfo.Index) // If we're not using a custom registry, we know the restrictions // applied to repository names and can warn the user in advance. // Custom repositories can have different rules, and we must also // allow pushing by image ID. if repoInfo.Official { username := authConfig.Username if username == "" { username = "******" } return fmt.Errorf("You cannot push a \"root\" repository. Please rename your repository to <user>/<repo> (ex: %s/%s)", username, ref.Name()) } push := func(auth types.AuthConfig) (io.ReadCloser, string, int, error) { return cli.client.Push(tag, repoInfo.String(), auth) } body, ctype, _, err := cli.requestWithLogin(repoInfo.Index, push, "push") if err != nil { return err } return cli.readStreamOutput(body, ctype, cli.isTerminalOut, cli.out, cli.err) }
func pullImage(client client.APIClient, service *Service, image string) error { distributionRef, err := reference.ParseNamed(image) if err != nil { return err } switch distributionRef.(type) { case reference.Canonical: case reference.NamedTagged: default: distributionRef, err = reference.WithTag(distributionRef, "latest") if err != nil { return err } } repoInfo, err := registry.ParseRepositoryInfo(distributionRef) if err != nil { return err } authConfig := types.AuthConfig{} if service.context.ConfigFile != nil && repoInfo != nil && repoInfo.Index != nil { authConfig = registry.ResolveAuthConfig(service.context.ConfigFile.AuthConfigs, repoInfo.Index) } encodedAuth, err := encodeAuthToBase64(authConfig) if err != nil { return err } options := types.ImagePullOptions{ RegistryAuth: encodedAuth, } responseBody, err := client.ImagePull(context.Background(), distributionRef.String(), options) if err != nil { logrus.Errorf("Failed to pull image %s: %v", image, err) return err } defer responseBody.Close() var writeBuff io.Writer = os.Stdout outFd, isTerminalOut := term.GetFdInfo(os.Stdout) err = jsonmessage.DisplayJSONMessagesStream(responseBody, writeBuff, outFd, isTerminalOut, nil) if err != nil { if jerr, ok := err.(*jsonmessage.JSONError); ok { // If no error code is set, default to 1 if jerr.Code == 0 { jerr.Code = 1 } fmt.Fprintf(os.Stderr, "%s", writeBuff) return fmt.Errorf("Status: %s, Code: %d", jerr.Message, jerr.Code) } } return err }
func (cli *DockerCli) clientRequestAttemptLogin(method, path string, in io.Reader, out io.Writer, index *registry.IndexInfo, cmdName string) (io.ReadCloser, int, error) { cmdAttempt := func(authConfig cliconfig.AuthConfig) (io.ReadCloser, int, error) { buf, err := json.Marshal(authConfig) if err != nil { return nil, -1, err } registryAuthHeader := []string{ base64.URLEncoding.EncodeToString(buf), } // begin the request serverResp, err := cli.clientRequest(method, path, in, map[string][]string{ "X-Registry-Auth": registryAuthHeader, }) if err == nil && out != nil { // If we are streaming output, complete the stream since // errors may not appear until later. err = cli.streamBody(serverResp.body, serverResp.header.Get("Content-Type"), true, out, nil) } if err != nil { // Since errors in a stream appear after status 200 has been written, // we may need to change the status code. if strings.Contains(err.Error(), "Authentication is required") || strings.Contains(err.Error(), "Status 401") || strings.Contains(err.Error(), "401 Unauthorized") || strings.Contains(err.Error(), "status code 401") { serverResp.statusCode = http.StatusUnauthorized } } return serverResp.body, serverResp.statusCode, err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile, index) body, statusCode, err := cmdAttempt(authConfig) if statusCode == http.StatusUnauthorized { fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName) if err = cli.CmdLogin(index.GetAuthConfigKey()); err != nil { return nil, -1, err } authConfig = registry.ResolveAuthConfig(cli.configFile, index) return cmdAttempt(authConfig) } return body, statusCode, err }
// CmdPull pulls an image or a repository from the registry. // // Usage: docker pull [OPTIONS] IMAGENAME[:TAG|@DIGEST] func (cli *DockerCli) CmdPull(args ...string) error { cmd := Cli.Subcmd("pull", []string{"NAME[:TAG|@DIGEST]"}, Cli.DockerCommands["pull"].Description, true) allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository") addTrustedFlags(cmd, true) cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) remote := cmd.Arg(0) distributionRef, err := reference.ParseNamed(remote) if err != nil { return err } var tag string switch x := distributionRef.(type) { case reference.Digested: if *allTags { return errTagCantBeUsed } tag = x.Digest().String() case reference.Tagged: if *allTags { return errTagCantBeUsed } tag = x.Tag() default: if !*allTags { tag = tagpkg.DefaultTag distributionRef, err = reference.WithTag(distributionRef, tag) if err != nil { return err } fmt.Fprintf(cli.out, "Using default tag: %s\n", tag) } } ref := registry.ParseReference(tag) // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(distributionRef) if err != nil { return err } if isTrusted() && !ref.HasDigest() { // Check if tag is digest authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index) return cli.trustedPull(repoInfo, ref, authConfig) } v := url.Values{} v.Set("fromImage", distributionRef.String()) _, _, err = cli.clientRequestAttemptLogin("POST", "/images/create?"+v.Encode(), nil, cli.out, repoInfo.Index, "pull") return err }
// CmdPush pushes an image or repository to the registry. // // Usage: docker push NAME[:TAG] func (cli *DockerCli) CmdPush(args ...string) error { cmd := Cli.Subcmd("push", []string{"NAME[:TAG]"}, Cli.DockerCommands["push"].Description, true) addTrustedFlags(cmd, false) cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) ref, err := reference.ParseNamed(cmd.Arg(0)) if err != nil { return err } var tag string switch x := ref.(type) { case reference.Digested: return errors.New("cannot push a digest reference") case reference.Tagged: tag = x.Tag() } // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index) // If we're not using a custom registry, we know the restrictions // applied to repository names and can warn the user in advance. // Custom repositories can have different rules, and we must also // allow pushing by image ID. if repoInfo.Official { username := authConfig.Username if username == "" { username = "******" } return fmt.Errorf("You cannot push a \"root\" repository. Please rename your repository to <user>/<repo> (ex: %s/%s)", username, repoInfo.LocalName) } if isTrusted() { return cli.trustedPush(repoInfo, tag, authConfig) } v := url.Values{} v.Set("tag", tag) _, _, err = cli.clientRequestAttemptLogin("POST", "/images/"+ref.Name()+"/push?"+v.Encode(), nil, cli.out, repoInfo.Index, "push") return err }
// CmdPull pulls an image or a repository from the registry. // // Usage: docker pull [OPTIONS] IMAGENAME[:TAG|@DIGEST] func (cli *DockerCli) CmdPull(args ...string) error { cmd := Cli.Subcmd("pull", []string{"NAME[:TAG|@DIGEST]"}, Cli.DockerCommands["pull"].Description, true) allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository") addTrustedFlags(cmd, true) cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) remote := cmd.Arg(0) distributionRef, err := reference.ParseNamed(remote) if err != nil { return err } if *allTags && !reference.IsNameOnly(distributionRef) { return errors.New("tag can't be used with --all-tags/-a") } if !*allTags && reference.IsNameOnly(distributionRef) { distributionRef = reference.WithDefaultTag(distributionRef) fmt.Fprintf(cli.out, "Using default tag: %s\n", reference.DefaultTag) } var tag string switch x := distributionRef.(type) { case reference.Canonical: tag = x.Digest().String() case reference.NamedTagged: tag = x.Tag() } ref := registry.ParseReference(tag) // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(distributionRef) if err != nil { return err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile.AuthConfigs, repoInfo.Index) requestPrivilege := cli.registryAuthenticationPrivilegedFunc(repoInfo.Index, "pull") if isTrusted() && !ref.HasDigest() { // Check if tag is digest return cli.trustedPull(repoInfo, ref, authConfig, requestPrivilege) } return cli.imagePullPrivileged(authConfig, distributionRef.String(), "", requestPrivilege) }
func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error { v := url.Values{} ref, err := reference.ParseNamed(image) if err != nil { return err } var tag string switch x := ref.(type) { case reference.Digested: tag = x.Digest().String() case reference.Tagged: tag = x.Tag() default: // pull only the image tagged 'latest' if no tag was specified tag = tagpkg.DefaultTag } v.Set("fromImage", ref.Name()) v.Set("tag", tag) // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index) buf, err := json.Marshal(authConfig) if err != nil { return err } registryAuthHeader := []string{ base64.URLEncoding.EncodeToString(buf), } sopts := &streamOpts{ rawTerminal: true, out: out, headers: map[string][]string{"X-Registry-Auth": registryAuthHeader}, } if _, err := cli.stream("POST", "/images/create?"+v.Encode(), sopts); err != nil { return err } return nil }
// CmdPush pushes an image or repository to the registry. // // Usage: hyper push NAME[:TAG] func (cli *HyperClient) HyperCmdPush(args ...string) error { // we need to get the image name which will be used to create a container if len(args) == 0 { return fmt.Errorf("\"push\" requires a minimum of 1 argument, please provide the image name.") } var parser = gflag.NewParser(nil, gflag.Default) parser.Usage = "push NAME[:TAG]\n\nPush an image to a Docker registry server" args, err := parser.Parse() if err != nil { if !strings.Contains(err.Error(), "Usage") { return err } else { return nil } } name := args[1] remote, tag := parsers.ParseRepositoryTag(name) // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(remote) if err != nil { return err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index) // If we're not using a custom registry, we know the restrictions // applied to repository names and can warn the user in advance. // Custom repositories can have different rules, and we must also // allow pushing by image ID. if repoInfo.Official { username := authConfig.Username if username == "" { username = "******" } return fmt.Errorf("You cannot push a \"root\" repository. Please rename your repository to <user>/<repo> (ex: %s/%s)", username, repoInfo.LocalName) } v := url.Values{} v.Set("tag", tag) v.Set("remote", remote) _, _, err = cli.clientRequestAttemptLogin("POST", "/image/push?"+v.Encode(), nil, cli.out, repoInfo.Index, "push") return err }
// CmdPull pulls an image or a repository from the registry. // // Usage: docker pull [OPTIONS] IMAGENAME[:TAG|@DIGEST] func (cli *DockerCli) CmdPull(args ...string) error { cmd := Cli.Subcmd("pull", []string{"NAME[:TAG|@DIGEST]"}, "Pull an image or a repository from a registry", true) allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository") dryRun := cmd.Bool([]string{"d", "-dry-run"}, false, "Dry run mode - only displays the download size") addTrustedFlags(cmd, true) cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) remote := cmd.Arg(0) taglessRemote, tag := parsers.ParseRepositoryTag(remote) if tag == "" && !*allTags { tag = tags.DefaultTag fmt.Fprintf(cli.out, "Using default tag: %s\n", tag) } else if tag != "" && *allTags { return fmt.Errorf("tag can't be used with --all-tags/-a") } ref := registry.ParseReference(tag) // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(taglessRemote) if err != nil { return err } if isTrusted() && !ref.HasDigest() { // Check if tag is digest authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index) return cli.trustedPull(repoInfo, ref, authConfig) } v := url.Values{} v.Set("fromImage", ref.ImageName(taglessRemote)) if *dryRun { fmt.Fprintf(cli.out, "**** Dry Run - nothing will be downloaded ****\n") v.Set("dryRun", "true") } _, _, err = cli.clientRequestAttemptLogin("POST", "/images/create?"+v.Encode(), nil, cli.out, repoInfo.Index, "pull") return err }
func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error { ref, err := reference.ParseNamed(image) if err != nil { return err } var tag string switch x := reference.WithDefaultTag(ref).(type) { case reference.Canonical: tag = x.Digest().String() case reference.NamedTagged: tag = x.Tag() } // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return err } authConfig := registry.ResolveAuthConfig(cli.configFile.AuthConfigs, repoInfo.Index) encodedAuth, err := encodeAuthToBase64(authConfig) if err != nil { return err } options := types.ImageCreateOptions{ Parent: ref.Name(), Tag: tag, RegistryAuth: encodedAuth, } responseBody, err := cli.client.ImageCreate(options) if err != nil { return err } defer responseBody.Close() return jsonmessage.DisplayJSONMessagesStream(responseBody, out, cli.outFd, cli.isTerminalOut, nil) }
func getAuthConfig(c *cli.Context, index *registryTypes.IndexInfo) (types.AuthConfig, error) { var ( username = c.GlobalString("username") password = c.GlobalString("password") cfg = c.GlobalString("docker-cfg") ) if _, err := os.Stat(cfg); err != nil { logrus.Infof("Docker cli config file %q not found: %v, falling back to --username and --password if needed", cfg, err) return types.AuthConfig{ Username: username, Password: password, Email: "*****@*****.**", }, nil } confFile, err := cliconfig.Load(cfg) if err != nil { return types.AuthConfig{}, err } authConfig := registry.ResolveAuthConfig(confFile.AuthConfigs, index) logrus.Debugf("authConfig for %s: %v", index.Name, authConfig) return authConfig, nil }
func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error { v := url.Values{} repos, tag := parsers.ParseRepositoryTag(image) // pull only the image tagged 'latest' if no tag was specified if tag == "" { tag = tags.DEFAULTTAG } v.Set("fromImage", repos) v.Set("tag", tag) // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(repos) if err != nil { return err } // Resolve the Auth config relevant for this server authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index) buf, err := json.Marshal(authConfig) if err != nil { return err } registryAuthHeader := []string{ base64.URLEncoding.EncodeToString(buf), } sopts := &streamOpts{ rawTerminal: true, out: out, headers: map[string][]string{"X-Registry-Auth": registryAuthHeader}, } if _, err := cli.stream("POST", "/images/create?"+v.Encode(), sopts); err != nil { return err } return nil }
// Pull tells Docker to pull image referenced by `name`. func (d Docker) Pull(name string) (*image.Image, error) { ref, err := reference.ParseNamed(name) if err != nil { return nil, err } switch ref.(type) { case reference.Tagged: case reference.Digested: default: ref, err = reference.WithTag(ref, "latest") if err != nil { return nil, err } } pullRegistryAuth := &cliconfig.AuthConfig{} if len(d.AuthConfigs) > 0 { // The request came with a full auth config file, we prefer to use that repoInfo, err := d.Daemon.RegistryService.ResolveRepository(ref) if err != nil { return nil, err } resolvedConfig := registry.ResolveAuthConfig( &cliconfig.ConfigFile{AuthConfigs: d.AuthConfigs}, repoInfo.Index, ) pullRegistryAuth = &resolvedConfig } if err := d.Daemon.PullImage(ref, nil, pullRegistryAuth, ioutils.NopWriteCloser(d.OutOld)); err != nil { return nil, err } return d.Daemon.GetImage(name) }
// CmdSearch searches the Docker Hub for images. // // Usage: docker search [OPTIONS] TERM func (cli *DockerCli) CmdSearch(args ...string) error { cmd := Cli.Subcmd("search", []string{"TERM"}, Cli.DockerCommands["search"].Description, true) noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output") automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds") stars := cmd.Uint([]string{"s", "-stars"}, 0, "Only displays with at least x stars") cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) name := cmd.Arg(0) v := url.Values{} v.Set("term", name) indexInfo, err := registry.ParseSearchIndexInfo(name) if err != nil { return err } authConfig := registry.ResolveAuthConfig(cli.configFile.AuthConfigs, indexInfo) requestPrivilege := cli.registryAuthenticationPrivilegedFunc(indexInfo, "search") encodedAuth, err := encodeAuthToBase64(authConfig) if err != nil { return err } options := types.ImageSearchOptions{ Term: name, RegistryAuth: encodedAuth, } unorderedResults, err := cli.client.ImageSearch(options, requestPrivilege) if err != nil { return err } results := searchResultsByStars(unorderedResults) sort.Sort(results) w := tabwriter.NewWriter(cli.out, 10, 1, 3, ' ', 0) fmt.Fprintf(w, "NAME\tDESCRIPTION\tSTARS\tOFFICIAL\tAUTOMATED\n") for _, res := range results { if (*automated && !res.IsAutomated) || (int(*stars) > res.StarCount) { continue } desc := strings.Replace(res.Description, "\n", " ", -1) desc = strings.Replace(desc, "\r", " ", -1) if !*noTrunc && len(desc) > 45 { desc = stringutils.Truncate(desc, 42) + "..." } fmt.Fprintf(w, "%s\t%s\t%d\t", res.Name, desc, res.StarCount) if res.IsOfficial { fmt.Fprint(w, "[OK]") } fmt.Fprint(w, "\t") if res.IsAutomated || res.IsTrusted { fmt.Fprint(w, "[OK]") } fmt.Fprint(w, "\n") } w.Flush() return nil }
func (cli *DockerCli) encodeRegistryAuth(index *registrytypes.IndexInfo) (string, error) { authConfig := registry.ResolveAuthConfig(cli.configFile.AuthConfigs, index) return encodeAuthToBase64(authConfig) }
// Lookup uses a Docker config file to lookup authentication information func (c *ConfigAuthLookup) Lookup(repoInfo *registry.RepositoryInfo) types.AuthConfig { if c.context.ConfigFile == nil || repoInfo == nil || repoInfo.Index == nil { return types.AuthConfig{} } return registry.ResolveAuthConfig(c.context.ConfigFile.AuthConfigs, repoInfo.Index) }
func (cli *DockerCli) encodeRegistryAuth(index *registry.IndexInfo) (string, error) { authConfig := registry.ResolveAuthConfig(cli.configFile, index) return authConfig.EncodeToBase64() }