Add option to pull images quietly

Add `--quiet` to the `docker image pull` subcommand that will not pull
the image quietly.

```
$ docker pull -q golang
Using default tag: latest
```

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
Vincent Demeester 2018-12-19 13:48:41 +01:00
parent 283d8f95c8
commit dd3407b6cc
No known key found for this signature in database
GPG Key ID: 083CC6FD6EB699A3
9 changed files with 46 additions and 9 deletions

View File

@ -18,6 +18,7 @@ type PullOptions struct {
remote string
all bool
platform string
quiet bool
untrusted bool
}
@ -38,6 +39,7 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command {
flags := cmd.Flags()
flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress verbose output")
command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
@ -55,7 +57,7 @@ func RunPull(cli command.Cli, opts PullOptions) error {
return errors.New("tag can't be used with --all-tags/-a")
case !opts.all && reference.IsNameOnly(distributionRef):
distributionRef = reference.TagNameOnly(distributionRef)
if tagged, ok := distributionRef.(reference.Tagged); ok {
if tagged, ok := distributionRef.(reference.Tagged); ok && !opts.quiet {
fmt.Fprintf(cli.Out(), "Using default tag: %s\n", tagged.Tag())
}
}
@ -69,9 +71,9 @@ func RunPull(cli command.Cli, opts PullOptions) error {
// Check if reference has a digest
_, isCanonical := distributionRef.(reference.Canonical)
if !opts.untrusted && !isCanonical {
err = trustedPull(ctx, cli, imgRefAndAuth, opts.platform)
err = trustedPull(ctx, cli, imgRefAndAuth, opts)
} else {
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts.all, opts.platform)
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts)
}
if err != nil {
if strings.Contains(err.Error(), "when fetching 'plugin'") {
@ -79,5 +81,6 @@ func RunPull(cli command.Cli, opts PullOptions) error {
}
return err
}
fmt.Fprintln(cli.Out(), imgRefAndAuth.Reference().String())
return nil
}

View File

@ -50,6 +50,7 @@ func TestNewPullCommandSuccess(t *testing.T) {
testCases := []struct {
name string
args []string
flags map[string]string
expectedTag string
}{
{
@ -62,6 +63,14 @@ func TestNewPullCommandSuccess(t *testing.T) {
args: []string{"image"},
expectedTag: "image:latest",
},
{
name: "simple-quiet",
args: []string{"image"},
flags: map[string]string{
"quiet": "true",
},
expectedTag: "image:latest",
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{

View File

@ -1 +1,2 @@
Using default tag: latest
docker.io/library/image:latest

View File

@ -0,0 +1,2 @@
Using default tag: latest
docker.io/library/image:latest

View File

@ -0,0 +1 @@
docker.io/library/image:tag

View File

@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"sort"
"github.com/docker/cli/cli/command"
@ -180,7 +181,7 @@ func imagePushPrivileged(ctx context.Context, cli command.Cli, authConfig types.
}
// trustedPull handles content trust pulling of an image
func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, platform string) error {
func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, opts PullOptions) error {
refs, err := getTrustedPullTargets(cli, imgRefAndAuth)
if err != nil {
return err
@ -202,7 +203,12 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
if err != nil {
return err
}
if err := imagePullPrivileged(ctx, cli, updatedImgRefAndAuth, false, platform); err != nil {
if err := imagePullPrivileged(ctx, cli, updatedImgRefAndAuth, PullOptions{
all: false,
platform: opts.platform,
quiet: opts.quiet,
remote: opts.remote,
}); err != nil {
return err
}
@ -268,7 +274,7 @@ func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth)
}
// imagePullPrivileged pulls the image and displays it to the output
func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, all bool, platform string) error {
func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, opts PullOptions) error {
ref := reference.FamiliarString(imgRefAndAuth.Reference())
encodedAuth, err := command.EncodeAuthToBase64(*imgRefAndAuth.AuthConfig())
@ -279,8 +285,8 @@ func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth tru
options := types.ImagePullOptions{
RegistryAuth: encodedAuth,
PrivilegeFunc: requestPrivilege,
All: all,
Platform: platform,
All: opts.all,
Platform: opts.platform,
}
responseBody, err := cli.Client().ImagePull(ctx, ref, options)
if err != nil {
@ -288,7 +294,11 @@ func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth tru
}
defer responseBody.Close()
return jsonmessage.DisplayJSONMessagesToStream(responseBody, cli.Out(), nil)
out := cli.Out()
if opts.quiet {
out = command.NewOutStream(ioutil.Discard)
}
return jsonmessage.DisplayJSONMessagesToStream(responseBody, out, nil)
}
// TrustedReference returns the canonical trusted reference for an image reference

View File

@ -24,6 +24,7 @@ Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
--help Print usage
-q, --quiet Suppress verbose output
```
## Description

View File

@ -5,6 +5,8 @@ import (
"github.com/docker/cli/e2e/internal/fixtures"
"github.com/docker/cli/internal/test/environment"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
"gotest.tools/golden"
"gotest.tools/icmd"
"gotest.tools/skip"
@ -32,6 +34,13 @@ func TestPullWithContentTrust(t *testing.T) {
golden.Assert(t, result.Stdout(), "pull-with-content-trust.golden")
}
func TestPullQuiet(t *testing.T) {
result := icmd.RunCommand("docker", "pull", "--quiet", fixtures.AlpineImage)
result.Assert(t, icmd.Success)
assert.Check(t, is.Equal(result.Stdout(), "registry:5000/alpine:3.6\n"))
assert.Check(t, is.Equal(result.Stderr(), ""))
}
func TestPullWithContentTrustUsesCacheWhenNotaryUnavailable(t *testing.T) {
skip.If(t, environment.RemoteDaemon())

View File

@ -2,3 +2,4 @@ Pull (1 of 1): registry:5000/trust-pull:latest@sha256:641b95ddb2ea9dc2af1a0113b6
sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d: Pulling from trust-pull
Digest: sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d
Status: Downloaded newer image for registry:5000/trust-pull@sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d
registry:5000/trust-pull:latest