Visitar URL original
client.ImagePull needs a JSON message type · Issue #89 · docker-archive-public/docker.engine-api · GitHub
Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

client.ImagePull needs a JSON message type #89

Open

Description

@tamird

Currently the only way to deserialize events from the io.ReadCloser returned from (*Client).ImagePull is to use github.com/docker/docker/pkg/jsonmessage.JSONMessage which forces a dependency on the docker repo. Here's what code currently has to look like:

    rc, err := cli.ImagePull(context.Background(), types.ImagePullOptions{
        ImageID: containerConfig.Image,
        Tag:     tag,
    }, nil)
    if err != nil {
        return err
    }
    defer rc.Close()
    dec := json.NewDecoder(rc)
    for {
        var message jsonmessage.JSONMessage
        if err := dec.Decode(&message); err != nil {
            if err == io.EOF {
                break
            }
            return err
        }
        log.Infof("ImagePull response: %s", message)
    }

Please introduce a new type in the engine-api repo (akin to github.com/docker/engine-api/types/events.Message) that would allow deserializing these events.

Activity

  1. vdemeester commented on Feb 13, 2016

    @vdemeester
    Contributor

    I guess we could bring JSONMessage to the engine-api, @calavera @MHBauer wdyt ?

  2. tamird commented on Feb 13, 2016

    @tamird
    ContributorAuthor

    github.com/docker/engine-api/types/events.Message contains a comment that indicates some deprecated fields are copied from JSONMessage. Is there an analogous custom message type planned for ImagePull?

    type Message struct {
        // Deprecated information from JSONMessage.
        // With data only in container events.
        ...
    }
  3. calavera commented on Feb 16, 2016

    @calavera
    Contributor

    I'd rather not bring JSONMessage here. There are a few packages in docker that depend on it, which would create a weird dependency.

    Personally, I think JSONMessage is a bad generalization of a bunch of things we use in docker. I'd rather have a clean implementation that's independent from Docker's package.

  4. LK4D4 commented on Feb 16, 2016

    @LK4D4
    Contributor

    I agree, JSONMessage is awful.

  5. stevvooe commented on Mar 7, 2016

    @stevvooe
    Contributor

    This should be hidden behind the Go API. One should not be deserializing a raw io.ReadCloser. The signature should be something like:

    ImagePull(ctx context.Context, name string, opts ImagePullOptions) (Progress, error)
    

    Where Progress is some structure reporting the progress of the pull.

  6. Random-Liu commented on Mar 18, 2016

    @Random-Liu
    Contributor

    Hi, all! We plan to start using this official api. Just wanna know how and when this will be solved? :)

  7. stevvooe commented on Mar 18, 2016

    @stevvooe
    Contributor

    I have a helper function with the following signature in my local project using an api similar to this (events):

    (*client).Events(ctx context.Context, options types.EventOptions) (messages <-events.Message, errs chan error)

    This can be consumed with the following Go code:

    ctx, cancel := context.WithCancel(ctx)
    
    msgs, errs := client.Events(ctx, opts)
    select {
    case msg := <-msgs:
       if terminal(msg) {
         cancel() // canceling context shuts down channel
         return errTerminal
       }
    case err := <- errs:
       // errs channel is closed or receives an error.
       // if err != nil, we msgs will get no new events.
       return err
    }

    I propose we follow a similar convention for the ImagePush/Pull API:

    (*client).ImagePull(ctx context.Context, options types.EventOptions) (messages <-types.Progress, errs chan error)

    To complement this, we need to define a Progress type. The following is the output of progress from the docker API:

    {"status":"Downloading","progressDetail":{"current":5399737,"total":65687381},"progress":"[====\u003e                                              ]   5.4 MB/65.69 MB","id":"203137e8afd5"}

    While we do use this in the client, we probably shouldn't be sending this much data (will require an API revision) and the actual bar should be calculated on the client-side. We can propose the minimal following Go API necessary for progress reporting:

    type Progress struct {
        Resource Resource
        Status string
        Current int64
        Total   int64 
        Start   int64 
    }
    
    type Resource struct {
        Type string
        ID string
        Name string
    }

    Progress becomes simply the integer fields from "progressDetail" and we get a portable description of a resource, which can be used to report progress on other kinds of asynchronous operations. The contents of "progress" can be recalculated from the provided fields (using text/template for clarity):

    tmpl := `{{.Resource.ID}}: {{.Status}} {{.|statusBar}} {{.Current | human}}/{{.Total | human}}`

    This provides the benefit of having a future-proof type for such API methods, while avoiding dependence on JSONMessage. Eventually, we can drop the progress field from the json and reduce the amount of data sent over the docker API.

  8. calavera commented on Mar 22, 2016

    @calavera
    Contributor

    @stevvooe all that sounds awesome to me.

  9. stevvooe commented on Mar 23, 2016

    @stevvooe
    Contributor

    @calavera I'm going to wire this up nearly identically in my current project, and then come back with a PR if it works out.

  10. tamird commented on Jul 31, 2016

    @tamird
    ContributorAuthor

    @stevvooe any progress on this?

  11. stevvooe commented on Aug 1, 2016

    @stevvooe
    Contributor

    @tamird #315 is the closest to providing progress here.

    If someone wants to take on the design from #89 (comment), that would be great, but I can probably get to this in the next month or so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions