mirror of https://github.com/docker/cli.git
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:
parent
283d8f95c8
commit
dd3407b6cc
|
@ -18,6 +18,7 @@ type PullOptions struct {
|
||||||
remote string
|
remote string
|
||||||
all bool
|
all bool
|
||||||
platform string
|
platform string
|
||||||
|
quiet bool
|
||||||
untrusted bool
|
untrusted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
|
||||||
flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")
|
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.AddPlatformFlag(flags, &opts.platform)
|
||||||
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
|
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")
|
return errors.New("tag can't be used with --all-tags/-a")
|
||||||
case !opts.all && reference.IsNameOnly(distributionRef):
|
case !opts.all && reference.IsNameOnly(distributionRef):
|
||||||
distributionRef = reference.TagNameOnly(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())
|
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
|
// Check if reference has a digest
|
||||||
_, isCanonical := distributionRef.(reference.Canonical)
|
_, isCanonical := distributionRef.(reference.Canonical)
|
||||||
if !opts.untrusted && !isCanonical {
|
if !opts.untrusted && !isCanonical {
|
||||||
err = trustedPull(ctx, cli, imgRefAndAuth, opts.platform)
|
err = trustedPull(ctx, cli, imgRefAndAuth, opts)
|
||||||
} else {
|
} else {
|
||||||
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts.all, opts.platform)
|
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "when fetching 'plugin'") {
|
if strings.Contains(err.Error(), "when fetching 'plugin'") {
|
||||||
|
@ -79,5 +81,6 @@ func RunPull(cli command.Cli, opts PullOptions) error {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fmt.Fprintln(cli.Out(), imgRefAndAuth.Reference().String())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ func TestNewPullCommandSuccess(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
args []string
|
args []string
|
||||||
|
flags map[string]string
|
||||||
expectedTag string
|
expectedTag string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
@ -62,6 +63,14 @@ func TestNewPullCommandSuccess(t *testing.T) {
|
||||||
args: []string{"image"},
|
args: []string{"image"},
|
||||||
expectedTag: "image:latest",
|
expectedTag: "image:latest",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "simple-quiet",
|
||||||
|
args: []string{"image"},
|
||||||
|
flags: map[string]string{
|
||||||
|
"quiet": "true",
|
||||||
|
},
|
||||||
|
expectedTag: "image:latest",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
Using default tag: latest
|
Using default tag: latest
|
||||||
|
docker.io/library/image:latest
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Using default tag: latest
|
||||||
|
docker.io/library/image:latest
|
|
@ -0,0 +1 @@
|
||||||
|
docker.io/library/image:tag
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/docker/cli/cli/command"
|
"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
|
// 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)
|
refs, err := getTrustedPullTargets(cli, imgRefAndAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -202,7 +203,12 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +274,7 @@ func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
// imagePullPrivileged pulls the image and displays it to the output
|
// 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())
|
ref := reference.FamiliarString(imgRefAndAuth.Reference())
|
||||||
|
|
||||||
encodedAuth, err := command.EncodeAuthToBase64(*imgRefAndAuth.AuthConfig())
|
encodedAuth, err := command.EncodeAuthToBase64(*imgRefAndAuth.AuthConfig())
|
||||||
|
@ -279,8 +285,8 @@ func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth tru
|
||||||
options := types.ImagePullOptions{
|
options := types.ImagePullOptions{
|
||||||
RegistryAuth: encodedAuth,
|
RegistryAuth: encodedAuth,
|
||||||
PrivilegeFunc: requestPrivilege,
|
PrivilegeFunc: requestPrivilege,
|
||||||
All: all,
|
All: opts.all,
|
||||||
Platform: platform,
|
Platform: opts.platform,
|
||||||
}
|
}
|
||||||
responseBody, err := cli.Client().ImagePull(ctx, ref, options)
|
responseBody, err := cli.Client().ImagePull(ctx, ref, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -288,7 +294,11 @@ func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth tru
|
||||||
}
|
}
|
||||||
defer responseBody.Close()
|
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
|
// TrustedReference returns the canonical trusted reference for an image reference
|
||||||
|
|
|
@ -24,6 +24,7 @@ Options:
|
||||||
-a, --all-tags Download all tagged images in the repository
|
-a, --all-tags Download all tagged images in the repository
|
||||||
--disable-content-trust Skip image verification (default true)
|
--disable-content-trust Skip image verification (default true)
|
||||||
--help Print usage
|
--help Print usage
|
||||||
|
-q, --quiet Suppress verbose output
|
||||||
```
|
```
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/e2e/internal/fixtures"
|
"github.com/docker/cli/e2e/internal/fixtures"
|
||||||
"github.com/docker/cli/internal/test/environment"
|
"github.com/docker/cli/internal/test/environment"
|
||||||
|
"gotest.tools/assert"
|
||||||
|
is "gotest.tools/assert/cmp"
|
||||||
"gotest.tools/golden"
|
"gotest.tools/golden"
|
||||||
"gotest.tools/icmd"
|
"gotest.tools/icmd"
|
||||||
"gotest.tools/skip"
|
"gotest.tools/skip"
|
||||||
|
@ -32,6 +34,13 @@ func TestPullWithContentTrust(t *testing.T) {
|
||||||
golden.Assert(t, result.Stdout(), "pull-with-content-trust.golden")
|
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) {
|
func TestPullWithContentTrustUsesCacheWhenNotaryUnavailable(t *testing.T) {
|
||||||
skip.If(t, environment.RemoteDaemon())
|
skip.If(t, environment.RemoteDaemon())
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,4 @@ Pull (1 of 1): registry:5000/trust-pull:latest@sha256:641b95ddb2ea9dc2af1a0113b6
|
||||||
sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d: Pulling from trust-pull
|
sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d: Pulling from trust-pull
|
||||||
Digest: sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d
|
Digest: sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d
|
||||||
Status: Downloaded newer image for registry:5000/trust-pull@sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d
|
Status: Downloaded newer image for registry:5000/trust-pull@sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d
|
||||||
|
registry:5000/trust-pull:latest
|
||||||
|
|
Loading…
Reference in New Issue