func pullImage( ctx context.Context, l *LocalCluster, ref string, options types.ImagePullOptions, ) error { // HACK: on CircleCI, docker pulls the image on the first access from an // acceptance test even though that image is already present. So we first // check to see if our image is present in order to avoid this slowness. if hasImage(ctx, l, ref) { log.Infof(ctx, "ImagePull %s already exists", ref) return nil } log.Infof(ctx, "ImagePull %s starting", ref) defer log.Infof(ctx, "ImagePull %s complete", ref) rc, err := l.client.ImagePull(ctx, ref, options) if err != nil { return err } defer rc.Close() out := os.Stderr outFd := out.Fd() isTerminal := isatty.IsTerminal(outFd) return jsonmessage.DisplayJSONMessagesStream(rc, out, outFd, isTerminal, nil) }
func runLoad(dockerCli *client.DockerCli, opts loadOptions) error { var input io.Reader = dockerCli.In() if opts.input != "" { file, err := os.Open(opts.input) if err != nil { return err } defer file.Close() input = file } if !dockerCli.IsTerminalOut() { opts.quiet = true } response, err := dockerCli.Client().ImageLoad(context.Background(), input, opts.quiet) if err != nil { return err } defer response.Body.Close() if response.Body != nil && response.JSON { return jsonmessage.DisplayJSONMessagesStream(response.Body, dockerCli.Out(), dockerCli.OutFd(), dockerCli.IsTerminalOut(), nil) } _, err = io.Copy(dockerCli.Out(), response.Body) return err }
// PullImage pulls docker image func (c *DockerClient) PullImage(name string) error { var ( image = imagename.NewFromString(name) pipeReader, pipeWriter = io.Pipe() fdOut, isTerminalOut = term.GetFdInfo(c.log.Out) out = c.log.Out errch = make(chan error, 1) ) if !isTerminalOut { out = c.log.Writer() } opts := docker.PullImageOptions{ Repository: image.NameWithRegistry(), Registry: image.Registry, Tag: image.GetTag(), OutputStream: pipeWriter, RawJSONStream: true, } c.log.Infof("| Pull image %s", image) c.log.Debugf("Pull image %s with options: %# v", image, opts) go func() { errch <- jsonmessage.DisplayJSONMessagesStream(pipeReader, out, fdOut, isTerminalOut) }() if err := c.client.PullImage(opts, c.auth); err != nil { return err } return <-errch }
func pullImage(ctx context.Context, dockerCli *command.DockerCli, image string, out io.Writer) error { ref, err := reference.ParseNamed(image) if err != nil { return err } // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return err } authConfig := dockerCli.ResolveAuthConfig(ctx, repoInfo.Index) encodedAuth, err := command.EncodeAuthToBase64(authConfig) if err != nil { return err } options := types.ImageCreateOptions{ RegistryAuth: encodedAuth, } responseBody, err := dockerCli.Client().ImageCreate(ctx, image, options) if err != nil { return err } defer responseBody.Close() return jsonmessage.DisplayJSONMessagesStream( responseBody, out, dockerCli.Out().FD(), dockerCli.Out().IsTerminal(), nil) }
func handleStreamResponse(resp *http.Response, streamOptions *streamOptions) error { var err error if !streamOptions.useJSONDecoder && resp.Header.Get("Content-Type") != "application/json" { if streamOptions.setRawTerminal { _, err = io.Copy(streamOptions.stdout, resp.Body) } else { _, err = stdcopy.StdCopy(streamOptions.stdout, streamOptions.stderr, resp.Body) } return err } // if we want to get raw json stream, just copy it back to output // without decoding it if streamOptions.rawJSONStream { _, err = io.Copy(streamOptions.stdout, resp.Body) return err } if st, ok := streamOptions.stdout.(interface { io.Writer FD() uintptr IsTerminal() bool }); ok { err = jsonmessage.DisplayJSONMessagesToStream(resp.Body, st, nil) } else { err = jsonmessage.DisplayJSONMessagesStream(resp.Body, streamOptions.stdout, 0, false, nil) } return err }
func runDeploy(cmd *Command, args []string) { r, w := io.Pipe() if len(args) < 1 { printFatal("You must specify an image to deploy") } image := args[0] message := getMessage() form := &PostDeployForm{Image: image} var endpoint string appName, _ := app() if appName != "" { endpoint = fmt.Sprintf("/apps/%s/deploys", appName) } else { endpoint = "/deploys" } rh := heroku.RequestHeaders{CommitMessage: message} go func() { must(client.PostWithHeaders(w, endpoint, form, rh.Headers())) must(w.Close()) }() outFd, isTerminalOut := term.GetFdInfo(os.Stdout) must(jsonmessage.DisplayJSONMessagesStream(r, os.Stdout, outFd, isTerminalOut)) }
// CmdLoad loads an image from a tar archive. // // The tar archive is read from STDIN by default, or from a tar archive file. // // Usage: docker load [OPTIONS] func (cli *DockerCli) CmdLoad(args ...string) error { cmd := Cli.Subcmd("load", nil, Cli.DockerCommands["load"].Description, true) infile := cmd.String([]string{"i", "-input"}, "", "Read from a tar archive file, instead of STDIN") quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Suppress the load output") cmd.Require(flag.Exact, 0) cmd.ParseFlags(args, true) var input io.Reader = cli.in if *infile != "" { file, err := os.Open(*infile) if err != nil { return err } defer file.Close() input = file } if !cli.isTerminalOut { *quiet = true } response, err := cli.client.ImageLoad(context.Background(), input, *quiet) if err != nil { return err } defer response.Body.Close() if response.JSON { return jsonmessage.DisplayJSONMessagesStream(response.Body, cli.out, cli.outFd, cli.isTerminalOut, nil) } _, err = io.Copy(cli.out, response.Body) 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 } // 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 := cli.resolveAuthConfig(repoInfo.Index) requestPrivilege := cli.registryAuthenticationPrivilegedFunc(repoInfo.Index, "push") if isTrusted() { return cli.trustedPush(repoInfo, ref, authConfig, requestPrivilege) } responseBody, err := cli.imagePushPrivileged(authConfig, ref.String(), requestPrivilege) if err != nil { return err } defer responseBody.Close() return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil) }
func (cli *DockerCli) pullImage(image string, out io.Writer) error { ref, err := reference.ParseNamed(image) if err != nil { return err } // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return err } authConfig := cli.resolveAuthConfig(repoInfo.Index) encodedAuth, err := encodeAuthToBase64(authConfig) if err != nil { return err } options := types.ImageCreateOptions{ RegistryAuth: encodedAuth, } responseBody, err := cli.client.ImageCreate(context.Background(), image, options) if err != nil { return err } defer responseBody.Close() return jsonmessage.DisplayJSONMessagesStream(responseBody, out, cli.outFd, cli.isTerminalOut, nil) }
func runPush(dockerCli *client.DockerCli, remote string) error { ref, err := reference.ParseNamed(remote) if err != nil { return err } // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return err } ctx := context.Background() // Resolve the Auth config relevant for this server authConfig := dockerCli.ResolveAuthConfig(ctx, repoInfo.Index) requestPrivilege := dockerCli.RegistryAuthenticationPrivilegedFunc(repoInfo.Index, "push") if client.IsTrusted() { return dockerCli.TrustedPush(ctx, repoInfo, ref, authConfig, requestPrivilege) } responseBody, err := dockerCli.ImagePushPrivileged(ctx, authConfig, ref.String(), requestPrivilege) if err != nil { return err } defer responseBody.Close() return jsonmessage.DisplayJSONMessagesStream(responseBody, dockerCli.Out(), dockerCli.OutFd(), dockerCli.IsTerminalOut(), nil) }
// CmdImport creates an empty filesystem image, imports the contents of the tarball into the image, and optionally tags the image. // // The URL argument is the address of a tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) file or a path to local file relative to docker client. If the URL is '-', then the tar file is read from STDIN. // // Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]] func (cli *DockerCli) CmdImport(args ...string) error { cmd := Cli.Subcmd("import", []string{"file|URL|- [REPOSITORY[:TAG]]"}, Cli.DockerCommands["import"].Description, true) flChanges := opts.NewListOpts(nil) cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image") message := cmd.String([]string{"m", "-message"}, "", "Set commit message for imported image") cmd.Require(flag.Min, 1) cmd.ParseFlags(args, true) var ( in io.Reader tag string src = cmd.Arg(0) srcName = src repository = cmd.Arg(1) changes = flChanges.GetAll() ) if cmd.NArg() == 3 { fmt.Fprintf(cli.err, "[DEPRECATED] The format 'file|URL|- [REPOSITORY [TAG]]' has been deprecated. Please use file|URL|- [REPOSITORY[:TAG]]\n") tag = cmd.Arg(2) } if repository != "" { //Check if the given image name can be resolved if _, err := reference.ParseNamed(repository); err != nil { return err } } if src == "-" { in = cli.in } else if !urlutil.IsURL(src) { srcName = "-" file, err := os.Open(src) if err != nil { return err } defer file.Close() in = file } options := types.ImageImportOptions{ Source: in, SourceName: srcName, RepositoryName: repository, Message: *message, Tag: tag, Changes: changes, } responseBody, err := cli.client.ImageImport(options) if err != nil { return err } defer responseBody.Close() return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut) }
func NewDockerJsonWriter(under io.Writer) *DockerJsonWriter { r, w := io.Pipe() go func() { err := jsonmessage.DisplayJSONMessagesStream(r, under, 1, true, nil) log.Fatal(err) }() return &DockerJsonWriter{under, w} }
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 }
// PullDockerImage pulls an image and streams to a logger respecting terminal features func PullDockerImage(client *docker.Client, image *imagename.ImageName, auth *docker.AuthConfigurations) (*docker.Image, error) { if image.Storage == imagename.StorageS3 { s3storage := s3.New(client, os.TempDir()) if err := s3storage.Pull(image.String()); err != nil { return nil, err } } else { pipeReader, pipeWriter := io.Pipe() pullOpts := docker.PullImageOptions{ Repository: image.NameWithRegistry(), Registry: image.Registry, Tag: image.Tag, OutputStream: pipeWriter, RawJSONStream: true, } repoAuth, err := dockerclient.GetAuthForRegistry(auth, image) if err != nil { return nil, fmt.Errorf("Failed to authenticate registry %s, error: %s", image.Registry, err) } errch := make(chan error, 1) go func() { err := client.PullImage(pullOpts, repoAuth) if err := pipeWriter.Close(); err != nil { log.Errorf("Failed to close pull image stream for %s, error: %s", image, err) } errch <- err }() def := log.StandardLogger() fd, isTerminal := term.GetFdInfo(def.Out) out := def.Out if !isTerminal { out = def.Writer() } if err := jsonmessage.DisplayJSONMessagesStream(pipeReader, out, fd, isTerminal); err != nil { return nil, fmt.Errorf("Failed to process json stream for image: %s, error: %s", image, err) } if err := <-errch; err != nil { return nil, fmt.Errorf("Failed to pull image %s, error: %s", image, err) } } img, err := client.InspectImage(image.String()) if err != nil { return nil, fmt.Errorf("Failed to inspect image %s after pull, error: %s", image, err) } return img, nil }
func ensureImage(cli DockerClient, image string) (string, error) { ctx := context.Background() info, _, err := cli.ImageInspectWithRaw(ctx, image, false) if err == nil { logrus.Debugf("Image found locally %s", image) return info.ID, nil } if !client.IsErrImageNotFound(err) { logrus.Errorf("Error inspecting image %q: %v", image, err) return "", err } // Image must be tagged reference if it does not exist ref, err := reference.Parse(image) if err != nil { logrus.Errorf("Image is not valid reference %q: %v", image, err) return "", err } tagged, ok := ref.(reference.NamedTagged) if !ok { logrus.Errorf("Tagged reference required %q", image) return "", errors.New("invalid reference, tag needed") } pullStart := time.Now() pullOptions := types.ImagePullOptions{ PrivilegeFunc: registryAuthNotSupported, } resp, err := cli.ImagePull(ctx, tagged.String(), pullOptions) if err != nil { logrus.Errorf("Error pulling image %q: %v", tagged.String(), err) return "", err } defer resp.Close() outFd, isTerminalOut := term.GetFdInfo(os.Stdout) if err = jsonmessage.DisplayJSONMessagesStream(resp, os.Stdout, outFd, isTerminalOut, nil); err != nil { logrus.Errorf("Error copying pull output: %v", err) return "", err } // TODO: Get pulled digest logFields := logrus.Fields{ timerKey: time.Since(pullStart), "image": tagged.String(), } logrus.WithFields(logFields).Info("image pulled") info, _, err = cli.ImageInspectWithRaw(ctx, tagged.String(), false) if err != nil { return "", nil } return info.ID, nil }
// Write decodes the jsonmessage stream in the bytes, and writes the decoded // plain text to the underlying io.Writer. func (w *DecodedJSONMessageWriter) Write(b []byte) (int, error) { err := jsonmessage.DisplayJSONMessagesStream(bytes.NewReader(b), w.w, w.fd, false) if err != nil { if err, ok := err.(*jsonmessage.JSONError); ok { w.err = err return len(b), nil } } return len(b), err }
// CmdImport creates an empty filesystem image, imports the contents of the tarball into the image, and optionally tags the image. // // The URL argument is the address of a tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) file or a path to local file relative to docker client. If the URL is '-', then the tar file is read from STDIN. // // Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]] func (cli *DockerCli) CmdImport(args ...string) error { cmd := Cli.Subcmd("import", []string{"file|URL|- [REPOSITORY[:TAG]]"}, Cli.DockerCommands["import"].Description, true) flChanges := opts.NewListOpts(nil) cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image") message := cmd.String([]string{"m", "-message"}, "", "Set commit message for imported image") cmd.Require(flag.Min, 1) cmd.ParseFlags(args, true) var ( in io.Reader tag string src = cmd.Arg(0) srcName = src ref = cmd.Arg(1) changes = flChanges.GetAll() ) if cmd.NArg() == 3 { // FIXME(vdemeester) Which version has this been deprecated ? should we remove it ? fmt.Fprintf(cli.err, "[DEPRECATED] The format 'file|URL|- [REPOSITORY [TAG]]' has been deprecated. Please use file|URL|- [REPOSITORY[:TAG]]\n") tag = cmd.Arg(2) } if src == "-" { in = cli.in } else if !urlutil.IsURL(src) { srcName = "-" file, err := os.Open(src) if err != nil { return err } defer file.Close() in = file } source := types.ImageImportSource{ Source: in, SourceName: srcName, } options := types.ImageImportOptions{ Message: *message, Tag: tag, Changes: changes, } responseBody, err := cli.client.ImageImport(context.Background(), source, ref, options) if err != nil { return err } defer responseBody.Close() return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil) }
func (a *App) Build(e *env.Env, writer io.Writer) error { e.Log.Info(`Build app`) if a.Layer.ID == `` { return errors.New("layer not found") } if err := a.Config.Sync(e, a.Layer.ID); err != nil { return err } tar_path := fmt.Sprintf("%s/apps/%s", env.Default_root_path, a.Layer.ID) reader, err := os.Open(tar_path) if err != nil { return err } or, ow := io.Pipe() opts := interfaces.BuildImageOptions{ Name: a.Config.Image, RmTmpContainer: true, InputStream: reader, OutputStream: ow, RawJSONStream: true, } ch := make(chan error, 1) go func() { defer ow.Close() defer close(ch) if err := e.Containers.BuildImage(opts); err != nil { e.Log.Error(err) return } }() jsonmessage.DisplayJSONMessagesStream(or, writer, os.Stdout.Fd(), term.IsTerminal(os.Stdout.Fd()), nil) if err, ok := <-ch; ok { if err != nil { e.Log.Error(err) return err } } if err := a.Update(e); err != nil { return err } reader.Close() or.Close() return nil }
func (s *Storage) RunDockerClient(reader io.Reader, fn func(ch chan error)) (err error) { errChan := make(chan error, 1) go fn(errChan) go func(ch chan error) { err := jsonmessage.DisplayJSONMessagesStream(reader, os.Stdout, os.Stdout.Fd(), true) ch <- err }(errChan) err = <-errChan return }
// PushImage pushes the image func (c *DockerClient) PushImage(imageName string) (digest string, err error) { var ( img = imagename.NewFromString(imageName) buf bytes.Buffer pipeReader, pipeWriter = io.Pipe() outStream = io.MultiWriter(pipeWriter, &buf) fdOut, isTerminalOut = term.GetFdInfo(c.log.Out) out = c.log.Out opts = docker.PushImageOptions{ Name: img.NameWithRegistry(), Tag: img.GetTag(), Registry: img.Registry, OutputStream: outStream, RawJSONStream: true, } errch = make(chan error, 1) ) if !isTerminalOut { out = c.log.Writer() } c.log.Infof("| Push %s", img) c.log.Debugf("Push with options: %# v", opts) // TODO: DisplayJSONMessagesStream may fail by client.PushImage run without errors go func() { errch <- jsonmessage.DisplayJSONMessagesStream(pipeReader, out, fdOut, isTerminalOut) }() if err := c.client.PushImage(opts, c.auth); err != nil { return "", err } pipeWriter.Close() if err := <-errch; err != nil { return "", fmt.Errorf("Failed to process json stream, error %s", err) } // It is the best way to have pushed image digest so far matches := captureDigest.FindStringSubmatch(buf.String()) if len(matches) > 0 { digest = matches[1] } return digest, nil }
// PullImage pulls docker image func (c *DockerClient) PullImage(name string) error { image := imagename.NewFromString(name) // e.g. s3:bucket-name/image-name if image.Storage == imagename.StorageS3 { if isOld, warning := imagename.WarnIfOldS3ImageName(name); isOld { c.log.Warn(warning) } return c.s3storage.Pull(name) } var ( pipeReader, pipeWriter = io.Pipe() fdOut, isTerminalOut = term.GetFdInfo(c.log.Out) out = c.log.Out errch = make(chan error, 1) ) if !isTerminalOut { out = c.log.Writer() } opts := docker.PullImageOptions{ Repository: image.NameWithRegistry(), Registry: image.Registry, Tag: image.GetTag(), OutputStream: pipeWriter, RawJSONStream: true, } c.log.Infof("| Pull image %s", image) c.log.Debugf("Pull image %s with options: %# v", image, opts) go func() { errch <- jsonmessage.DisplayJSONMessagesStream(pipeReader, out, fdOut, isTerminalOut) }() auth, err := dockerclient.GetAuthForRegistry(c.auth, image) if err != nil { return fmt.Errorf("Failed to authenticate registry %s, error: %s", image.Registry, err) } if err := c.client.PullImage(opts, auth); err != nil { return err } pipeWriter.Close() return <-errch }
// Build implements Builder. It consumes the docker build API endpoint and sends // a tar of the specified service build context. func (d *DaemonBuilder) Build(imageName string, p *project.Project, service project.Service) error { if service.Config().Build == "" { return fmt.Errorf("Specified service does not have a build section") } ctx, err := CreateTar(p, service.Name()) if err != nil { return err } defer ctx.Close() var progBuff io.Writer = os.Stdout var buildBuff io.Writer = os.Stdout // Setup an upload progress bar progressOutput := streamformatter.NewStreamFormatter().NewProgressOutput(progBuff, true) var body io.Reader = progress.NewProgressReader(ctx, progressOutput, 0, "", "Sending build context to Docker daemon") client := d.context.ClientFactory.Create(service) logrus.Infof("Building %s...", imageName) outFd, isTerminalOut := term.GetFdInfo(os.Stdout) response, err := client.ImageBuild(context.Background(), types.ImageBuildOptions{ Context: body, Tags: []string{imageName}, NoCache: d.context.NoCache, Remove: true, Dockerfile: service.Config().Dockerfile, AuthConfigs: d.context.ConfigFile.AuthConfigs, }) err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, 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%s", progBuff, buildBuff) return fmt.Errorf("Status: %s, Code: %d", jerr.Message, jerr.Code) } } return err }
// PullImage pulls the specified image (can be a name, an id or a digest) // to the daemon store with the specified client. func PullImage(ctx context.Context, client client.ImageAPIClient, serviceName string, authLookup auth.Lookup, image string) error { fmt.Fprintf(os.Stderr, "Pulling %s (%s)...\n", serviceName, image) distributionRef, err := reference.ParseNamed(image) if err != nil { return err } repoInfo, err := registry.ParseRepositoryInfo(distributionRef) if err != nil { return err } authConfig := authLookup.Lookup(repoInfo) // Use ConfigFile.SaveToWriter to not re-define encodeAuthToBase64 encodedAuth, err := encodeAuthToBase64(authConfig) if err != nil { return err } options := types.ImagePullOptions{ RegistryAuth: encodedAuth, } responseBody, err := client.ImagePull(ctx, 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.Stderr outFd, isTerminalOut := term.GetFdInfo(os.Stderr) 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 *HyperClient) readStreamOutput(body io.ReadCloser, contentType string, setRawTerminal bool, stdout, stderr io.Writer) error { defer body.Close() if utils.MatchesContentType(contentType, "application/json") { return jsonmessage.DisplayJSONMessagesStream(body, stdout, cli.outFd, cli.isTerminalOut, nil) } if stdout != nil || stderr != nil { // When TTY is ON, use regular copy var err error if setRawTerminal { _, err = io.Copy(stdout, body) } else { _, err = stdcopy.StdCopy(stdout, stderr, body) } return err } return nil }
func (client *DockerClient) PullImage(name string, auth *AuthConfig, cliOut io.Writer) (err error) { v := url.Values{} v.Set("fromImage", name) uri := fmt.Sprintf("/%s/images/create?%s", APIVersion, v.Encode()) req, _ := http.NewRequest("POST", client.URL.String()+uri, nil) if auth != nil { req.Header.Add("X-Registry-Auth", auth.encode()) } var resp *http.Response resp, err = client.HTTPClient.Do(req) if err != nil { return } defer resp.Body.Close() errorReader := io.Reader(resp.Body) if cliOut != nil { pipeReader, pipeWriter := io.Pipe() streamErrChan := make(chan error) defer func() { pipeWriter.Close() if err == nil { err = <-streamErrChan } }() errorReader = io.TeeReader(resp.Body, pipeWriter) go func() { fd, isTerminalIn := term.GetFdInfo(cliOut) streamErrChan <- jsonmessage.DisplayJSONMessagesStream(pipeReader, cliOut, fd, isTerminalIn) }() } var finalObj map[string]interface{} for decoder := json.NewDecoder(errorReader); err == nil; err = decoder.Decode(&finalObj) { } if err != io.EOF { return } else { err = nil } if errObj, ok := finalObj["error"]; ok { err = fmt.Errorf("%v", errObj) return } return }
// Build implements Builder. It consumes the docker build API endpoint and sends // a tar of the specified service build context. func (d *DaemonBuilder) Build(ctx context.Context, imageName string) error { buildCtx, err := createTar(d.ContextDirectory, d.Dockerfile) if err != nil { return err } defer buildCtx.Close() var progBuff io.Writer = os.Stdout var buildBuff io.Writer = os.Stdout // Setup an upload progress bar progressOutput := streamformatter.NewStreamFormatter().NewProgressOutput(progBuff, true) var body io.Reader = progress.NewProgressReader(buildCtx, progressOutput, 0, "", "Sending build context to Docker daemon") logrus.Infof("Building %s...", imageName) outFd, isTerminalOut := term.GetFdInfo(os.Stdout) response, err := d.Client.ImageBuild(ctx, body, types.ImageBuildOptions{ Tags: []string{imageName}, NoCache: d.NoCache, Remove: true, ForceRemove: d.ForceRemove, PullParent: d.Pull, Dockerfile: d.Dockerfile, AuthConfigs: d.AuthConfigs, }) if err != nil { return err } err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, 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 } return fmt.Errorf("Status: %s, Code: %d", jerr.Message, jerr.Code) } } return err }
func (cli *DockerCli) streamBody(body io.ReadCloser, contentType string, rawTerminal bool, stdout, stderr io.Writer) error { defer body.Close() if api.MatchesContentType(contentType, "application/json") { return jsonmessage.DisplayJSONMessagesStream(body, stdout, cli.outFd, cli.isTerminalOut) } if stdout != nil || stderr != nil { // When TTY is ON, use regular copy var err error if rawTerminal { _, err = io.Copy(stdout, body) } else { _, err = stdcopy.StdCopy(stdout, stderr, body) } logrus.Debugf("[stream] End of stdout") return err } return nil }
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 := 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 } // 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 encodedAuth, err := cli.encodeRegistryAuth(repoInfo.Index) 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) }
func (cli *DockerCli) imagePullPrivileged(authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc) error { encodedAuth, err := encodeAuthToBase64(authConfig) if err != nil { return err } options := types.ImagePullOptions{ RegistryAuth: encodedAuth, PrivilegeFunc: requestPrivilege, } responseBody, err := cli.client.ImagePull(context.Background(), ref, options) if err != nil { return err } defer responseBody.Close() return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil) }
func (cli *DockerCli) imagePushPrivileged(authConfig types.AuthConfig, imageID, tag string, outputStream io.Writer, requestPrivilege lib.RequestPrivilegeFunc) error { encodedAuth, err := encodeAuthToBase64(authConfig) if err != nil { return err } options := types.ImagePushOptions{ ImageID: imageID, Tag: tag, RegistryAuth: encodedAuth, } responseBody, err := cli.client.ImagePush(options, requestPrivilege) if err != nil { return err } defer responseBody.Close() return jsonmessage.DisplayJSONMessagesStream(responseBody, outputStream, cli.outFd, cli.isTerminalOut) }