在 Docker Golang SDK 中为 client.ImagePull() 禁用详细标准输出

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

当使用 ImagePull() 拉取镜像时,终端中有大量的标准输出显示拉取的进度,即;

{"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
}

我搜索了 documentation,但没有找到禁用 StdOut 或更改详细信息的方法。

我不太了解 io.Copy(os.Stdout, out) 行,但据我所知,禁用它不会导致任何图像被拉取。

我们如何隐藏 ImagePull() 的输出?

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 只是从 io.Reader 中读取所有数据(在本例中是 io.ReadCloser,也是 io.Reader)并将其写入 io.Writer.

我的理解是,如果您不执行此步骤,main returns 在 ImagePull 之前有机会在后台完成。

但是,如果您确实执行了 io.Copy,复制会使 main 忙碌足够长的时间,以便拉动真正完成。

在上面评论中的示例中,我让 main 忙于 for / sleep 循环。

你看到所有输出的原因是因为......好吧,你用 io.Copy(os.Stdout, out)ImagePull 的输出复制到 Stdout,所以我们看到输出也就不足为奇了标准输出中的 ImagePull

如果相反,我们将所有输出复制到某个使输出消失的“黑洞”中,我们将在复制发生时保持 main 忙碌,同时抑制其所有输出。

一种方法是使用 io/ioutilioutil.Discard。这是一个 io.Writer,它会简单地丢弃所有写入它的数据。

所以只需将 io.Copy(os.Stdout, out) 行替换为以下内容:

import {
    "io/ioutil"
}

io.Copy(ioutil.Discard, out)