hide --detach for docker < 17.05

Signed-off-by: Victor Vieux <victorvieux@gmail.com>
This commit is contained in:
Victor Vieux 2017-06-26 18:19:36 -07:00
parent 0133e13353
commit db60f25561
5 changed files with 76 additions and 23 deletions

View File

@ -124,12 +124,9 @@ func runCreate(dockerCli *command.DockerCli, flags *pflag.FlagSet, opts *service
fmt.Fprintf(dockerCli.Out(), "%s\n", response.ID) fmt.Fprintf(dockerCli.Out(), "%s\n", response.ID)
if opts.detach { if opts.detach {
if !flags.Changed("detach") { warnDetachDefault(dockerCli.Err(), apiClient.ClientVersion(), flags, "created")
fmt.Fprintln(dockerCli.Err(), "Since --detach=false was not specified, tasks will be created in the background.\n"+
"In a future release, --detach=false will become the default.")
}
return nil return nil
} }
return waitOnService(ctx, dockerCli, response.ID, opts) return waitOnService(ctx, dockerCli, response.ID, opts.quiet)
} }

View File

@ -1,18 +1,21 @@
package service package service
import ( import (
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/service/progress" "github.com/docker/cli/cli/command/service/progress"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
"github.com/spf13/pflag"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
// waitOnService waits for the service to converge. It outputs a progress bar, // waitOnService waits for the service to converge. It outputs a progress bar,
// if appropriate based on the CLI flags. // if appropriate based on the CLI flags.
func waitOnService(ctx context.Context, dockerCli *command.DockerCli, serviceID string, opts *serviceOptions) error { func waitOnService(ctx context.Context, dockerCli *command.DockerCli, serviceID string, quiet bool) error {
errChan := make(chan error, 1) errChan := make(chan error, 1)
pipeReader, pipeWriter := io.Pipe() pipeReader, pipeWriter := io.Pipe()
@ -20,7 +23,7 @@ func waitOnService(ctx context.Context, dockerCli *command.DockerCli, serviceID
errChan <- progress.ServiceProgress(ctx, dockerCli.Client(), serviceID, pipeWriter) errChan <- progress.ServiceProgress(ctx, dockerCli.Client(), serviceID, pipeWriter)
}() }()
if opts.quiet { if quiet {
go io.Copy(ioutil.Discard, pipeReader) go io.Copy(ioutil.Discard, pipeReader)
return <-errChan return <-errChan
} }
@ -31,3 +34,11 @@ func waitOnService(ctx context.Context, dockerCli *command.DockerCli, serviceID
} }
return err return err
} }
// warnDetachDefault warns about the --detach flag future change if it's supported.
func warnDetachDefault(err io.Writer, clientVersion string, flags *pflag.FlagSet, msg string) {
if !flags.Changed("detach") && versions.GreaterThanOrEqualTo(clientVersion, "1.29") {
fmt.Fprintf(err, "Since --detach=false was not specified, tasks will be %s in the background.\n"+
"In a future release, --detach=false will become the default.\n", msg)
}
}

View File

@ -0,0 +1,40 @@
package service
import (
"bytes"
"testing"
"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
)
func TestWarnDetachDefault(t *testing.T) {
var detach bool
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
addDetachFlag(flags, &detach)
var tests = []struct {
detach bool
version string
expectWarning bool
}{
{true, "1.28", false},
{true, "1.29", false},
{false, "1.28", false},
{false, "1.29", true},
}
for _, test := range tests {
out := new(bytes.Buffer)
flags.Lookup(flagDetach).Changed = test.detach
warnDetachDefault(out, test.version, flags, "")
if test.expectWarning {
assert.NotEmpty(t, out.String(), "expected warning")
} else {
assert.Empty(t, out.String(), "expected no warning")
}
}
}

View File

@ -690,6 +690,11 @@ func buildServiceDefaultFlagMapping() flagDefaults {
return defaultFlagValues return defaultFlagValues
} }
func addDetachFlag(flags *pflag.FlagSet, detach *bool) {
flags.BoolVarP(detach, flagDetach, "d", true, "Exit immediately instead of waiting for the service to converge")
flags.SetAnnotation(flagDetach, "version", []string{"1.29"})
}
// addServiceFlags adds all flags that are common to both `create` and `update`. // addServiceFlags adds all flags that are common to both `create` and `update`.
// Any flags that are not common are added separately in the individual command // Any flags that are not common are added separately in the individual command
func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValues flagDefaults) { func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValues flagDefaults) {
@ -700,8 +705,8 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValu
return desc return desc
} }
flags.BoolVarP(&opts.detach, "detach", "d", true, "Exit immediately instead of waiting for the service to converge") addDetachFlag(flags, &opts.detach)
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress progress output") flags.BoolVarP(&opts.quiet, flagQuiet, "q", false, "Suppress progress output")
flags.StringVarP(&opts.workdir, flagWorkdir, "w", "", "Working directory inside the container") flags.StringVarP(&opts.workdir, flagWorkdir, "w", "", "Working directory inside the container")
flags.StringVarP(&opts.user, flagUser, "u", "", "Username or UID (format: <name|uid>[:<group|gid>])") flags.StringVarP(&opts.user, flagUser, "u", "", "Username or UID (format: <name|uid>[:<group|gid>])")
@ -792,6 +797,7 @@ const (
flagContainerLabel = "container-label" flagContainerLabel = "container-label"
flagContainerLabelRemove = "container-label-rm" flagContainerLabelRemove = "container-label-rm"
flagContainerLabelAdd = "container-label-add" flagContainerLabelAdd = "container-label-add"
flagDetach = "detach"
flagDNS = "dns" flagDNS = "dns"
flagDNSRemove = "dns-rm" flagDNSRemove = "dns-rm"
flagDNSAdd = "dns-add" flagDNSAdd = "dns-add"
@ -803,10 +809,6 @@ const (
flagDNSSearchAdd = "dns-search-add" flagDNSSearchAdd = "dns-search-add"
flagEndpointMode = "endpoint-mode" flagEndpointMode = "endpoint-mode"
flagEntrypoint = "entrypoint" flagEntrypoint = "entrypoint"
flagHost = "host"
flagHostAdd = "host-add"
flagHostRemove = "host-rm"
flagHostname = "hostname"
flagEnv = "env" flagEnv = "env"
flagEnvFile = "env-file" flagEnvFile = "env-file"
flagEnvRemove = "env-rm" flagEnvRemove = "env-rm"
@ -814,6 +816,10 @@ const (
flagGroup = "group" flagGroup = "group"
flagGroupAdd = "group-add" flagGroupAdd = "group-add"
flagGroupRemove = "group-rm" flagGroupRemove = "group-rm"
flagHost = "host"
flagHostAdd = "host-add"
flagHostRemove = "host-rm"
flagHostname = "hostname"
flagLabel = "label" flagLabel = "label"
flagLabelRemove = "label-rm" flagLabelRemove = "label-rm"
flagLabelAdd = "label-add" flagLabelAdd = "label-add"
@ -830,6 +836,7 @@ const (
flagPublish = "publish" flagPublish = "publish"
flagPublishRemove = "publish-rm" flagPublishRemove = "publish-rm"
flagPublishAdd = "publish-add" flagPublishAdd = "publish-add"
flagQuiet = "quiet"
flagReadOnly = "read-only" flagReadOnly = "read-only"
flagReplicas = "replicas" flagReplicas = "replicas"
flagReserveCPU = "reserve-cpu" flagReserveCPU = "reserve-cpu"
@ -838,6 +845,7 @@ const (
flagRestartDelay = "restart-delay" flagRestartDelay = "restart-delay"
flagRestartMaxAttempts = "restart-max-attempts" flagRestartMaxAttempts = "restart-max-attempts"
flagRestartWindow = "restart-window" flagRestartWindow = "restart-window"
flagRollback = "rollback"
flagRollbackDelay = "rollback-delay" flagRollbackDelay = "rollback-delay"
flagRollbackFailureAction = "rollback-failure-action" flagRollbackFailureAction = "rollback-failure-action"
flagRollbackMaxFailureRatio = "rollback-max-failure-ratio" flagRollbackMaxFailureRatio = "rollback-max-failure-ratio"

View File

@ -37,8 +37,8 @@ func newUpdateCommand(dockerCli *command.DockerCli) *cobra.Command {
flags := cmd.Flags() flags := cmd.Flags()
flags.String("image", "", "Service image tag") flags.String("image", "", "Service image tag")
flags.Var(&ShlexOpt{}, "args", "Service command args") flags.Var(&ShlexOpt{}, "args", "Service command args")
flags.Bool("rollback", false, "Rollback to previous specification") flags.Bool(flagRollback, false, "Rollback to previous specification")
flags.SetAnnotation("rollback", "version", []string{"1.25"}) flags.SetAnnotation(flagRollback, "version", []string{"1.25"})
flags.Bool("force", false, "Force update even if no changes require it") flags.Bool("force", false, "Force update even if no changes require it")
flags.SetAnnotation("force", "version", []string{"1.25"}) flags.SetAnnotation("force", "version", []string{"1.25"})
addServiceFlags(flags, options, nil) addServiceFlags(flags, options, nil)
@ -112,7 +112,7 @@ func runUpdate(dockerCli *command.DockerCli, flags *pflag.FlagSet, options *serv
return err return err
} }
rollback, err := flags.GetBool("rollback") rollback, err := flags.GetBool(flagRollback)
if err != nil { if err != nil {
return err return err
} }
@ -130,7 +130,7 @@ func runUpdate(dockerCli *command.DockerCli, flags *pflag.FlagSet, options *serv
// Rollback can't be combined with other flags. // Rollback can't be combined with other flags.
otherFlagsPassed := false otherFlagsPassed := false
flags.VisitAll(func(f *pflag.Flag) { flags.VisitAll(func(f *pflag.Flag) {
if f.Name == "rollback" || f.Name == "detach" || f.Name == "quiet" { if f.Name == flagRollback || f.Name == flagDetach || f.Name == flagQuiet {
return return
} }
if flags.Changed(f.Name) { if flags.Changed(f.Name) {
@ -141,7 +141,7 @@ func runUpdate(dockerCli *command.DockerCli, flags *pflag.FlagSet, options *serv
return errors.New("other flags may not be combined with --rollback") return errors.New("other flags may not be combined with --rollback")
} }
if versions.LessThan(dockerCli.Client().ClientVersion(), "1.28") { if versions.LessThan(apiClient.ClientVersion(), "1.28") {
clientSideRollback = true clientSideRollback = true
spec = service.PreviousSpec spec = service.PreviousSpec
if spec == nil { if spec == nil {
@ -217,14 +217,11 @@ func runUpdate(dockerCli *command.DockerCli, flags *pflag.FlagSet, options *serv
fmt.Fprintf(dockerCli.Out(), "%s\n", serviceID) fmt.Fprintf(dockerCli.Out(), "%s\n", serviceID)
if options.detach { if options.detach {
if !flags.Changed("detach") { warnDetachDefault(dockerCli.Err(), dockerCli.Client().ClientVersion(), flags, "updated")
fmt.Fprintln(dockerCli.Err(), "Since --detach=false was not specified, tasks will be updated in the background.\n"+
"In a future release, --detach=false will become the default.")
}
return nil return nil
} }
return waitOnService(ctx, dockerCli, serviceID, options) return waitOnService(ctx, dockerCli, serviceID, options.quiet)
} }
// nolint: gocyclo // nolint: gocyclo