Marcus Jones
Marcus Jones

Reputation: 970

Disable verbose stdout in Docker Golang SDK for client.ImagePull()

When pulling an image with ImagePull(), there is extensive stdout in the terminal showing the progress of the Pull, i.e.;

{"status":"Downloading","progressDetail":{"current":6433248,"total":7964517},"progress":"[========================================\u003e          ]  6.433MB/7.965MB","id":"ae5cee1a3f12"}
func PullImage(imageName string) bool {
    ctx := context.Background()
    cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
    if err != nil {
        log.Error(err)
        return false
    }

    //TODO: Need to disable Stdout!!
    log.Info("\t\tPulling image " + imageName)
    out, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
    if err != nil {
        log.Error(err)
        return false
    }
    defer out.Close()

    io.Copy(os.Stdout, out)

    log.Info("Pulled image " + imageName + " into host")

    return true
}

I have searched the documentation and haven't found a way to disable StdOut or change verbosity.

I don't really understand the io.Copy(os.Stdout, out) line, but disabling it causes no image to be pulled, as far as I can tell.

How can we hide the output from ImagePull()?

Upvotes: 0

Views: 434

Answers (1)

Omer Tuchfeld
Omer Tuchfeld

Reputation: 3022

I don't really understand the io.Copy(os.Stdout, out) line, but disabling it causes no image to be pulled, as far as I can tell.

io.Copy simply reads all data from an io.Reader (in this case an io.ReadCloser which is also an io.Reader) and writes it into an io.Writer.

My understanding is that if you don't perform this step, main returns before ImagePull gets a chance to finish in the background.

However, if you do perform io.Copy, the copying keeps main busy long enough for the pull to actually finish.

In my example in the comments above, I kept main busy with a for / sleep loop instead.

The reason you see all the output is because... well, you copy the output of ImagePull to Stdout with io.Copy(os.Stdout, out), so it's no surprise we see the output of ImagePull in stdout.

If instead we copied all output into some "blackhole" that makes the output disappear, we'd keep main busy while the copy is happening while suppressing all of its output.

One way to do that is to use io/ioutil's ioutil.Discard. This is an io.Writer that simply throws away all data written to it.

So simply replace you io.Copy(os.Stdout, out) line with the following:

import {
    "io/ioutil"
}

io.Copy(ioutil.Discard, out)

Upvotes: 2

Related Questions