From 0efa67f7d2e080b30c64f03b9158eabbd8e3ae6d Mon Sep 17 00:00:00 2001 From: Christopher Crone Date: Thu, 21 May 2020 19:28:42 +0200 Subject: [PATCH 1/3] Set random container name if not set Signed-off-by: Christopher Crone --- cli/cmd/run/run.go | 9 +-------- cli/cmd/run/run_test.go | 23 ----------------------- cli/options/run/opts.go | 10 ++++++++++ cli/options/run/opts_test.go | 16 ++++++++++++++++ 4 files changed, 27 insertions(+), 31 deletions(-) delete mode 100644 cli/cmd/run/run_test.go diff --git a/cli/cmd/run/run.go b/cli/cmd/run/run.go index 5b448f875..6c5e864e8 100644 --- a/cli/cmd/run/run.go +++ b/cli/cmd/run/run.go @@ -30,9 +30,7 @@ package run import ( "context" "fmt" - "strings" - "github.com/docker/docker/pkg/namesgenerator" "github.com/spf13/cobra" "github.com/docker/api/cli/options/run" @@ -52,7 +50,7 @@ func Command() *cobra.Command { } cmd.Flags().StringArrayVarP(&opts.Publish, "publish", "p", []string{}, "Publish a container's port(s). [HOST_PORT:]CONTAINER_PORT") - cmd.Flags().StringVar(&opts.Name, "name", getRandomName(), "Assign a name to the container") + cmd.Flags().StringVar(&opts.Name, "name", "", "Assign a name to the container") cmd.Flags().StringArrayVarP(&opts.Labels, "label", "l", []string{}, "Set meta data on a container") cmd.Flags().StringArrayVarP(&opts.Volumes, "volume", "v", []string{}, "Volume. Ex: user:key@my_share:/absolute/path/to/target") @@ -77,8 +75,3 @@ func runRun(ctx context.Context, image string, opts run.Opts) error { return nil } - -func getRandomName() string { - // Azure supports hyphen but not underscore in names - return strings.Replace(namesgenerator.GetRandomName(0), "_", "-", -1) -} diff --git a/cli/cmd/run/run_test.go b/cli/cmd/run/run_test.go deleted file mode 100644 index 2ef4b81f9..000000000 --- a/cli/cmd/run/run_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package run - -import ( - "regexp" - "testing" - - "github.com/stretchr/testify/require" -) - -var ( - // AzureNameRegex is used to validate container names - // Regex was taken from server side error: - // The container name must contain no more than 63 characters and must match the regex '[a-z0-9]([-a-z0-9]*[a-z0-9])?' (e.g. 'my-name'). - AzureNameRegex = regexp.MustCompile("[a-z0-9]([-a-z0-9]*[a-z0-9])") -) - -// TestAzureRandomName ensures compliance with Azure naming requirements -func TestAzureRandomName(t *testing.T) { - n := getRandomName() - require.Less(t, len(n), 64) - require.Greater(t, len(n), 1) - require.Regexp(t, AzureNameRegex, n) -} diff --git a/cli/options/run/opts.go b/cli/options/run/opts.go index af3bd9918..2e55c953a 100644 --- a/cli/options/run/opts.go +++ b/cli/options/run/opts.go @@ -5,6 +5,7 @@ import ( "strconv" "strings" + "github.com/docker/docker/pkg/namesgenerator" "github.com/docker/go-connections/nat" "github.com/docker/api/containers" @@ -20,6 +21,10 @@ type Opts struct { // ToContainerConfig convert run options to a container configuration func (r *Opts) ToContainerConfig(image string) (containers.ContainerConfig, error) { + if r.Name == "" { + r.Name = getRandomName() + } + publish, err := r.toPorts() if err != nil { return containers.ContainerConfig{}, err @@ -83,3 +88,8 @@ func toLabels(labels []string) (map[string]string, error) { return result, nil } + +func getRandomName() string { + // Azure supports hyphen but not underscore in names + return strings.Replace(namesgenerator.GetRandomName(0), "_", "-", -1) +} diff --git a/cli/options/run/opts_test.go b/cli/options/run/opts_test.go index b2e4f4ee3..881ff253e 100644 --- a/cli/options/run/opts_test.go +++ b/cli/options/run/opts_test.go @@ -2,6 +2,7 @@ package run import ( "errors" + "regexp" "testing" "github.com/stretchr/testify/assert" @@ -15,6 +16,21 @@ type RunOptsSuite struct { suite.Suite } +var ( + // AzureNameRegex is used to validate container names + // Regex was taken from server side error: + // The container name must contain no more than 63 characters and must match the regex '[a-z0-9]([-a-z0-9]*[a-z0-9])?' (e.g. 'my-name'). + AzureNameRegex = regexp.MustCompile("[a-z0-9]([-a-z0-9]*[a-z0-9])") +) + +// TestAzureRandomName ensures compliance with Azure naming requirements +func (s *RunOptsSuite) TestAzureRandomName() { + n := getRandomName() + require.Less(s.T(), len(n), 64) + require.Greater(s.T(), len(n), 1) + require.Regexp(s.T(), AzureNameRegex, n) +} + func (s *RunOptsSuite) TestPortParse() { testCases := []struct { in string From dd66646c060761a16c71de6ebde1f24474e9f494 Mon Sep 17 00:00:00 2001 From: Christopher Crone Date: Thu, 21 May 2020 20:03:06 +0200 Subject: [PATCH 2/3] Unit test run help Signed-off-by: Christopher Crone --- cli/cmd/run/run_test.go | 42 ++++++++++++++++++++++++++++ cli/cmd/run/testdata/run-help.golden | 10 +++++++ 2 files changed, 52 insertions(+) create mode 100644 cli/cmd/run/run_test.go create mode 100644 cli/cmd/run/testdata/run-help.golden diff --git a/cli/cmd/run/run_test.go b/cli/cmd/run/run_test.go new file mode 100644 index 000000000..d34050d44 --- /dev/null +++ b/cli/cmd/run/run_test.go @@ -0,0 +1,42 @@ +/* + Copyright (c) 2020 Docker Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH + THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package run + +import ( + "bytes" + "testing" + + "gotest.tools/v3/golden" +) + +func TestHelp(t *testing.T) { + var b bytes.Buffer + c := Command() + c.SetOutput(&b) + _ = c.Help() + golden.Assert(t, b.String(), "run-help.golden") +} diff --git a/cli/cmd/run/testdata/run-help.golden b/cli/cmd/run/testdata/run-help.golden new file mode 100644 index 000000000..7bdf7de85 --- /dev/null +++ b/cli/cmd/run/testdata/run-help.golden @@ -0,0 +1,10 @@ +Run a container + +Usage: + run [flags] + +Flags: + -l, --label stringArray Set meta data on a container + --name string Assign a name to the container + -p, --publish stringArray Publish a container's port(s). [HOST_PORT:]CONTAINER_PORT + -v, --volume stringArray Volume. Ex: user:key@my_share:/absolute/path/to/target From 88ba591fc3b1b1057ded3e601f985860bf45e24a Mon Sep 17 00:00:00 2001 From: Christopher Crone Date: Fri, 22 May 2020 10:45:01 +0200 Subject: [PATCH 3/3] Seed random with nanosecond time It's possible that users will run commands more than once a second. Thus, seeding the random number generator with the current time in seconds could produce results like the same container name in subsequent commands. Seeding with the current time in nanoseconds reduces the probability of this. Signed-off-by: Christopher Crone --- azure/login/login.go | 5 ----- cli/main.go | 4 ++++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/azure/login/login.go b/azure/login/login.go index 3c13c5434..dd4c63be2 100644 --- a/azure/login/login.go +++ b/azure/login/login.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "log" - "math/rand" "net/url" "os/exec" "path/filepath" @@ -24,10 +23,6 @@ import ( "github.com/pkg/errors" ) -func init() { - rand.Seed(time.Now().Unix()) -} - //go login process, derived from code sample provided by MS at https://github.com/devigned/go-az-cli-stuff const ( authorizeFormat = "https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&state=%s&prompt=select_account&response_mode=query&scope=%s" diff --git a/cli/main.go b/cli/main.go index 110b80290..328a3a5cb 100644 --- a/cli/main.go +++ b/cli/main.go @@ -30,11 +30,13 @@ package main import ( "context" "fmt" + "math/rand" "os" "os/exec" "os/signal" "path/filepath" "syscall" + "time" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -69,6 +71,8 @@ func init() { if err := os.Setenv("PATH", fmt.Sprintf("%s:%s", os.Getenv("PATH"), path)); err != nil { panic(err) } + // Seed random + rand.Seed(time.Now().UnixNano()) } func isOwnCommand(cmd *cobra.Command) bool {