Remove the utils package
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,9 @@ |
| 0 |
+package api |
|
| 1 |
+ |
|
| 2 |
+import "regexp" |
|
| 3 |
+ |
|
| 4 |
+// RestrictedNameChars collects the characters allowed to represent a name, normally used to validate container and volume names. |
|
| 5 |
+const RestrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]` |
|
| 6 |
+ |
|
| 7 |
+// RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters. |
|
| 8 |
+var RestrictedNamePattern = regexp.MustCompile(`^` + RestrictedNameChars + `+$`) |
| ... | ... |
@@ -10,7 +10,7 @@ import ( |
| 10 | 10 |
"github.com/docker/docker/cli/command" |
| 11 | 11 |
"github.com/docker/docker/cli/command/formatter" |
| 12 | 12 |
"github.com/docker/docker/opts" |
| 13 |
- "github.com/docker/docker/utils/templates" |
|
| 13 |
+ "github.com/docker/docker/pkg/templates" |
|
| 14 | 14 |
"github.com/spf13/cobra" |
| 15 | 15 |
) |
| 16 | 16 |
|
| ... | ... |
@@ -17,7 +17,7 @@ import ( |
| 17 | 17 |
"github.com/docker/docker/cli/command" |
| 18 | 18 |
"github.com/docker/docker/opts" |
| 19 | 19 |
"github.com/docker/docker/pkg/jsonlog" |
| 20 |
- "github.com/docker/docker/utils/templates" |
|
| 20 |
+ "github.com/docker/docker/pkg/templates" |
|
| 21 | 21 |
"github.com/spf13/cobra" |
| 22 | 22 |
) |
| 23 | 23 |
|
| ... | ... |
@@ -12,9 +12,9 @@ import ( |
| 12 | 12 |
"github.com/docker/docker/api/types/swarm" |
| 13 | 13 |
"github.com/docker/docker/cli" |
| 14 | 14 |
"github.com/docker/docker/cli/command" |
| 15 |
+ "github.com/docker/docker/cli/debug" |
|
| 15 | 16 |
"github.com/docker/docker/pkg/ioutils" |
| 16 |
- "github.com/docker/docker/utils" |
|
| 17 |
- "github.com/docker/docker/utils/templates" |
|
| 17 |
+ "github.com/docker/docker/pkg/templates" |
|
| 18 | 18 |
"github.com/docker/go-units" |
| 19 | 19 |
"github.com/spf13/cobra" |
| 20 | 20 |
) |
| ... | ... |
@@ -206,7 +206,7 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error {
|
| 206 | 206 |
ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Name: %s\n", info.Name) |
| 207 | 207 |
ioutils.FprintfIfNotEmpty(dockerCli.Out(), "ID: %s\n", info.ID) |
| 208 | 208 |
fmt.Fprintf(dockerCli.Out(), "Docker Root Dir: %s\n", info.DockerRootDir) |
| 209 |
- fmt.Fprintf(dockerCli.Out(), "Debug Mode (client): %v\n", utils.IsDebugEnabled()) |
|
| 209 |
+ fmt.Fprintf(dockerCli.Out(), "Debug Mode (client): %v\n", debug.IsEnabled()) |
|
| 210 | 210 |
fmt.Fprintf(dockerCli.Out(), "Debug Mode (server): %v\n", info.Debug) |
| 211 | 211 |
|
| 212 | 212 |
if info.Debug {
|
| ... | ... |
@@ -11,7 +11,7 @@ import ( |
| 11 | 11 |
"github.com/docker/docker/cli" |
| 12 | 12 |
"github.com/docker/docker/cli/command" |
| 13 | 13 |
"github.com/docker/docker/dockerversion" |
| 14 |
- "github.com/docker/docker/utils/templates" |
|
| 14 |
+ "github.com/docker/docker/pkg/templates" |
|
| 15 | 15 |
"github.com/spf13/cobra" |
| 16 | 16 |
) |
| 17 | 17 |
|
| 18 | 18 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,26 @@ |
| 0 |
+package debug |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "os" |
|
| 4 |
+ |
|
| 5 |
+ "github.com/Sirupsen/logrus" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// Enable sets the DEBUG env var to true |
|
| 9 |
+// and makes the logger to log at debug level. |
|
| 10 |
+func Enable() {
|
|
| 11 |
+ os.Setenv("DEBUG", "1")
|
|
| 12 |
+ logrus.SetLevel(logrus.DebugLevel) |
|
| 13 |
+} |
|
| 14 |
+ |
|
| 15 |
+// Disable sets the DEBUG env var to false |
|
| 16 |
+// and makes the logger to log at info level. |
|
| 17 |
+func Disable() {
|
|
| 18 |
+ os.Setenv("DEBUG", "")
|
|
| 19 |
+ logrus.SetLevel(logrus.InfoLevel) |
|
| 20 |
+} |
|
| 21 |
+ |
|
| 22 |
+// IsEnabled checks whether the debug flag is set or not. |
|
| 23 |
+func IsEnabled() bool {
|
|
| 24 |
+ return os.Getenv("DEBUG") != ""
|
|
| 25 |
+} |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,43 @@ |
| 0 |
+package debug |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "os" |
|
| 4 |
+ "testing" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/Sirupsen/logrus" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+func TestEnable(t *testing.T) {
|
|
| 10 |
+ defer func() {
|
|
| 11 |
+ os.Setenv("DEBUG", "")
|
|
| 12 |
+ logrus.SetLevel(logrus.InfoLevel) |
|
| 13 |
+ }() |
|
| 14 |
+ Enable() |
|
| 15 |
+ if os.Getenv("DEBUG") != "1" {
|
|
| 16 |
+ t.Fatalf("expected DEBUG=1, got %s\n", os.Getenv("DEBUG"))
|
|
| 17 |
+ } |
|
| 18 |
+ if logrus.GetLevel() != logrus.DebugLevel {
|
|
| 19 |
+ t.Fatalf("expected log level %v, got %v\n", logrus.DebugLevel, logrus.GetLevel())
|
|
| 20 |
+ } |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 23 |
+func TestDisable(t *testing.T) {
|
|
| 24 |
+ Disable() |
|
| 25 |
+ if os.Getenv("DEBUG") != "" {
|
|
| 26 |
+ t.Fatalf("expected DEBUG=\"\", got %s\n", os.Getenv("DEBUG"))
|
|
| 27 |
+ } |
|
| 28 |
+ if logrus.GetLevel() != logrus.InfoLevel {
|
|
| 29 |
+ t.Fatalf("expected log level %v, got %v\n", logrus.InfoLevel, logrus.GetLevel())
|
|
| 30 |
+ } |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+func TestEnabled(t *testing.T) {
|
|
| 34 |
+ Enable() |
|
| 35 |
+ if !IsEnabled() {
|
|
| 36 |
+ t.Fatal("expected debug enabled, got false")
|
|
| 37 |
+ } |
|
| 38 |
+ Disable() |
|
| 39 |
+ if IsEnabled() {
|
|
| 40 |
+ t.Fatal("expected debug disabled, got true")
|
|
| 41 |
+ } |
|
| 42 |
+} |
| ... | ... |
@@ -10,11 +10,11 @@ import ( |
| 10 | 10 |
"github.com/docker/docker/cli" |
| 11 | 11 |
"github.com/docker/docker/cli/command" |
| 12 | 12 |
"github.com/docker/docker/cli/command/commands" |
| 13 |
+ "github.com/docker/docker/cli/debug" |
|
| 13 | 14 |
cliflags "github.com/docker/docker/cli/flags" |
| 14 | 15 |
"github.com/docker/docker/cliconfig" |
| 15 | 16 |
"github.com/docker/docker/dockerversion" |
| 16 | 17 |
"github.com/docker/docker/pkg/term" |
| 17 |
- "github.com/docker/docker/utils" |
|
| 18 | 18 |
"github.com/spf13/cobra" |
| 19 | 19 |
"github.com/spf13/pflag" |
| 20 | 20 |
) |
| ... | ... |
@@ -130,7 +130,7 @@ func dockerPreRun(opts *cliflags.ClientOptions) {
|
| 130 | 130 |
} |
| 131 | 131 |
|
| 132 | 132 |
if opts.Common.Debug {
|
| 133 |
- utils.EnableDebug() |
|
| 133 |
+ debug.Enable() |
|
| 134 | 134 |
} |
| 135 | 135 |
} |
| 136 | 136 |
|
| ... | ... |
@@ -7,12 +7,12 @@ import ( |
| 7 | 7 |
|
| 8 | 8 |
"github.com/Sirupsen/logrus" |
| 9 | 9 |
"github.com/docker/docker/cli/command" |
| 10 |
+ "github.com/docker/docker/cli/debug" |
|
| 10 | 11 |
"github.com/docker/docker/pkg/testutil/assert" |
| 11 |
- "github.com/docker/docker/utils" |
|
| 12 | 12 |
) |
| 13 | 13 |
|
| 14 | 14 |
func TestClientDebugEnabled(t *testing.T) {
|
| 15 |
- defer utils.DisableDebug() |
|
| 15 |
+ defer debug.Disable() |
|
| 16 | 16 |
|
| 17 | 17 |
cmd := newDockerCommand(&command.DockerCli{})
|
| 18 | 18 |
cmd.Flags().Set("debug", "true")
|
| ... | ... |
@@ -26,6 +26,7 @@ import ( |
| 26 | 26 |
systemrouter "github.com/docker/docker/api/server/router/system" |
| 27 | 27 |
"github.com/docker/docker/api/server/router/volume" |
| 28 | 28 |
"github.com/docker/docker/builder/dockerfile" |
| 29 |
+ "github.com/docker/docker/cli/debug" |
|
| 29 | 30 |
cliflags "github.com/docker/docker/cli/flags" |
| 30 | 31 |
"github.com/docker/docker/cliconfig" |
| 31 | 32 |
"github.com/docker/docker/daemon" |
| ... | ... |
@@ -44,7 +45,6 @@ import ( |
| 44 | 44 |
"github.com/docker/docker/plugin" |
| 45 | 45 |
"github.com/docker/docker/registry" |
| 46 | 46 |
"github.com/docker/docker/runconfig" |
| 47 |
- "github.com/docker/docker/utils" |
|
| 48 | 47 |
"github.com/docker/go-connections/tlsconfig" |
| 49 | 48 |
"github.com/spf13/pflag" |
| 50 | 49 |
) |
| ... | ... |
@@ -137,7 +137,7 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) {
|
| 137 | 137 |
} |
| 138 | 138 |
|
| 139 | 139 |
if cli.Config.Debug {
|
| 140 |
- utils.EnableDebug() |
|
| 140 |
+ debug.Enable() |
|
| 141 | 141 |
} |
| 142 | 142 |
|
| 143 | 143 |
if cli.Config.Experimental {
|
| ... | ... |
@@ -351,13 +351,13 @@ func (cli *DaemonCli) reloadConfig() {
|
| 351 | 351 |
} |
| 352 | 352 |
|
| 353 | 353 |
if config.IsValueSet("debug") {
|
| 354 |
- debugEnabled := utils.IsDebugEnabled() |
|
| 354 |
+ debugEnabled := debug.IsEnabled() |
|
| 355 | 355 |
switch {
|
| 356 | 356 |
case debugEnabled && !config.Debug: // disable debug |
| 357 |
- utils.DisableDebug() |
|
| 357 |
+ debug.Disable() |
|
| 358 | 358 |
cli.api.DisableProfiler() |
| 359 | 359 |
case config.Debug && !debugEnabled: // enable debug |
| 360 |
- utils.EnableDebug() |
|
| 360 |
+ debug.Enable() |
|
| 361 | 361 |
cli.api.EnableProfiler() |
| 362 | 362 |
} |
| 363 | 363 |
|
| ... | ... |
@@ -488,7 +488,7 @@ func initRouter(s *apiserver.Server, d *daemon.Daemon, c *cluster.Cluster) {
|
| 488 | 488 |
} |
| 489 | 489 |
} |
| 490 | 490 |
|
| 491 |
- s.InitRouter(utils.IsDebugEnabled(), routers...) |
|
| 491 |
+ s.InitRouter(debug.IsEnabled(), routers...) |
|
| 492 | 492 |
} |
| 493 | 493 |
|
| 494 | 494 |
func (cli *DaemonCli) initMiddlewares(s *apiserver.Server, cfg *apiserver.Config) error {
|
| ... | ... |
@@ -16,7 +16,6 @@ import ( |
| 16 | 16 |
"github.com/docker/docker/pkg/stringid" |
| 17 | 17 |
"github.com/docker/docker/pkg/symlink" |
| 18 | 18 |
"github.com/docker/docker/pkg/system" |
| 19 |
- "github.com/docker/docker/utils" |
|
| 20 | 19 |
"github.com/docker/docker/volume" |
| 21 | 20 |
"github.com/opencontainers/runc/libcontainer/label" |
| 22 | 21 |
"golang.org/x/sys/unix" |
| ... | ... |
@@ -69,7 +68,7 @@ func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string |
| 69 | 69 |
// because the env on the container can override certain default values |
| 70 | 70 |
// we need to replace the 'env' keys where they match and append anything |
| 71 | 71 |
// else. |
| 72 |
- env = utils.ReplaceOrAppendEnvValues(env, container.Config.Env) |
|
| 72 |
+ env = ReplaceOrAppendEnvValues(env, container.Config.Env) |
|
| 73 | 73 |
return env |
| 74 | 74 |
} |
| 75 | 75 |
|
| ... | ... |
@@ -8,7 +8,6 @@ import ( |
| 8 | 8 |
"path/filepath" |
| 9 | 9 |
|
| 10 | 10 |
containertypes "github.com/docker/docker/api/types/container" |
| 11 |
- "github.com/docker/docker/utils" |
|
| 12 | 11 |
) |
| 13 | 12 |
|
| 14 | 13 |
// Container holds fields specific to the Windows implementation. See |
| ... | ... |
@@ -30,7 +29,7 @@ func (container *Container) CreateDaemonEnvironment(_ bool, linkedEnv []string) |
| 30 | 30 |
// because the env on the container can override certain default values |
| 31 | 31 |
// we need to replace the 'env' keys where they match and append anything |
| 32 | 32 |
// else. |
| 33 |
- return utils.ReplaceOrAppendEnvValues(linkedEnv, container.Config.Env) |
|
| 33 |
+ return ReplaceOrAppendEnvValues(linkedEnv, container.Config.Env) |
|
| 34 | 34 |
} |
| 35 | 35 |
|
| 36 | 36 |
// UnmountIpcMounts unmounts Ipc related mounts. |
| 37 | 37 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,43 @@ |
| 0 |
+package container |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "strings" |
|
| 4 |
+) |
|
| 5 |
+ |
|
| 6 |
+// ReplaceOrAppendEnvValues returns the defaults with the overrides either |
|
| 7 |
+// replaced by env key or appended to the list |
|
| 8 |
+func ReplaceOrAppendEnvValues(defaults, overrides []string) []string {
|
|
| 9 |
+ cache := make(map[string]int, len(defaults)) |
|
| 10 |
+ for i, e := range defaults {
|
|
| 11 |
+ parts := strings.SplitN(e, "=", 2) |
|
| 12 |
+ cache[parts[0]] = i |
|
| 13 |
+ } |
|
| 14 |
+ |
|
| 15 |
+ for _, value := range overrides {
|
|
| 16 |
+ // Values w/o = means they want this env to be removed/unset. |
|
| 17 |
+ if !strings.Contains(value, "=") {
|
|
| 18 |
+ if i, exists := cache[value]; exists {
|
|
| 19 |
+ defaults[i] = "" // Used to indicate it should be removed |
|
| 20 |
+ } |
|
| 21 |
+ continue |
|
| 22 |
+ } |
|
| 23 |
+ |
|
| 24 |
+ // Just do a normal set/update |
|
| 25 |
+ parts := strings.SplitN(value, "=", 2) |
|
| 26 |
+ if i, exists := cache[parts[0]]; exists {
|
|
| 27 |
+ defaults[i] = value |
|
| 28 |
+ } else {
|
|
| 29 |
+ defaults = append(defaults, value) |
|
| 30 |
+ } |
|
| 31 |
+ } |
|
| 32 |
+ |
|
| 33 |
+ // Now remove all entries that we want to "unset" |
|
| 34 |
+ for i := 0; i < len(defaults); i++ {
|
|
| 35 |
+ if defaults[i] == "" {
|
|
| 36 |
+ defaults = append(defaults[:i], defaults[i+1:]...) |
|
| 37 |
+ i-- |
|
| 38 |
+ } |
|
| 39 |
+ } |
|
| 40 |
+ |
|
| 41 |
+ return defaults |
|
| 42 |
+} |
| 0 | 43 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 0 |
+package container |
|
| 1 |
+ |
|
| 2 |
+import "testing" |
|
| 3 |
+ |
|
| 4 |
+func TestReplaceAndAppendEnvVars(t *testing.T) {
|
|
| 5 |
+ var ( |
|
| 6 |
+ d = []string{"HOME=/"}
|
|
| 7 |
+ o = []string{"HOME=/root", "TERM=xterm"}
|
|
| 8 |
+ ) |
|
| 9 |
+ |
|
| 10 |
+ env := ReplaceOrAppendEnvValues(d, o) |
|
| 11 |
+ if len(env) != 2 {
|
|
| 12 |
+ t.Fatalf("expected len of 2 got %d", len(env))
|
|
| 13 |
+ } |
|
| 14 |
+ if env[0] != "HOME=/root" {
|
|
| 15 |
+ t.Fatalf("expected HOME=/root got '%s'", env[0])
|
|
| 16 |
+ } |
|
| 17 |
+ if env[1] != "TERM=xterm" {
|
|
| 18 |
+ t.Fatalf("expected TERM=xterm got '%s'", env[1])
|
|
| 19 |
+ } |
|
| 20 |
+} |
| ... | ... |
@@ -7,13 +7,13 @@ import ( |
| 7 | 7 |
"os" |
| 8 | 8 |
"path/filepath" |
| 9 | 9 |
|
| 10 |
+ "github.com/docker/docker/api" |
|
| 10 | 11 |
"github.com/docker/docker/api/types" |
| 11 |
- "github.com/docker/docker/utils" |
|
| 12 | 12 |
) |
| 13 | 13 |
|
| 14 | 14 |
var ( |
| 15 |
- validCheckpointNameChars = utils.RestrictedNameChars |
|
| 16 |
- validCheckpointNamePattern = utils.RestrictedNamePattern |
|
| 15 |
+ validCheckpointNameChars = api.RestrictedNameChars |
|
| 16 |
+ validCheckpointNamePattern = api.RestrictedNamePattern |
|
| 17 | 17 |
) |
| 18 | 18 |
|
| 19 | 19 |
// CheckpointCreate checkpoints the process running in a container with CRIU |
| ... | ... |
@@ -18,7 +18,6 @@ import ( |
| 18 | 18 |
"github.com/docker/docker/pkg/pools" |
| 19 | 19 |
"github.com/docker/docker/pkg/signal" |
| 20 | 20 |
"github.com/docker/docker/pkg/term" |
| 21 |
- "github.com/docker/docker/utils" |
|
| 22 | 21 |
) |
| 23 | 22 |
|
| 24 | 23 |
// Seconds to wait after sending TERM before trying KILL |
| ... | ... |
@@ -94,7 +93,7 @@ func (d *Daemon) getActiveContainer(name string) (*container.Container, error) {
|
| 94 | 94 |
|
| 95 | 95 |
// ContainerExecCreate sets up an exec in a running container. |
| 96 | 96 |
func (d *Daemon) ContainerExecCreate(name string, config *types.ExecConfig) (string, error) {
|
| 97 |
- container, err := d.getActiveContainer(name) |
|
| 97 |
+ cntr, err := d.getActiveContainer(name) |
|
| 98 | 98 |
if err != nil {
|
| 99 | 99 |
return "", err |
| 100 | 100 |
} |
| ... | ... |
@@ -115,7 +114,7 @@ func (d *Daemon) ContainerExecCreate(name string, config *types.ExecConfig) (str |
| 115 | 115 |
execConfig.OpenStdin = config.AttachStdin |
| 116 | 116 |
execConfig.OpenStdout = config.AttachStdout |
| 117 | 117 |
execConfig.OpenStderr = config.AttachStderr |
| 118 |
- execConfig.ContainerID = container.ID |
|
| 118 |
+ execConfig.ContainerID = cntr.ID |
|
| 119 | 119 |
execConfig.DetachKeys = keys |
| 120 | 120 |
execConfig.Entrypoint = entrypoint |
| 121 | 121 |
execConfig.Args = args |
| ... | ... |
@@ -123,18 +122,18 @@ func (d *Daemon) ContainerExecCreate(name string, config *types.ExecConfig) (str |
| 123 | 123 |
execConfig.Privileged = config.Privileged |
| 124 | 124 |
execConfig.User = config.User |
| 125 | 125 |
|
| 126 |
- linkedEnv, err := d.setupLinkedContainers(container) |
|
| 126 |
+ linkedEnv, err := d.setupLinkedContainers(cntr) |
|
| 127 | 127 |
if err != nil {
|
| 128 | 128 |
return "", err |
| 129 | 129 |
} |
| 130 |
- execConfig.Env = utils.ReplaceOrAppendEnvValues(container.CreateDaemonEnvironment(config.Tty, linkedEnv), config.Env) |
|
| 130 |
+ execConfig.Env = container.ReplaceOrAppendEnvValues(cntr.CreateDaemonEnvironment(config.Tty, linkedEnv), config.Env) |
|
| 131 | 131 |
if len(execConfig.User) == 0 {
|
| 132 |
- execConfig.User = container.Config.User |
|
| 132 |
+ execConfig.User = cntr.Config.User |
|
| 133 | 133 |
} |
| 134 | 134 |
|
| 135 |
- d.registerExecCommand(container, execConfig) |
|
| 135 |
+ d.registerExecCommand(cntr, execConfig) |
|
| 136 | 136 |
|
| 137 |
- d.LogContainerEvent(container, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " ")) |
|
| 137 |
+ d.LogContainerEvent(cntr, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " ")) |
|
| 138 | 138 |
|
| 139 | 139 |
return execConfig.ID, nil |
| 140 | 140 |
} |
| ... | ... |
@@ -10,6 +10,7 @@ import ( |
| 10 | 10 |
"github.com/Sirupsen/logrus" |
| 11 | 11 |
"github.com/docker/docker/api" |
| 12 | 12 |
"github.com/docker/docker/api/types" |
| 13 |
+ "github.com/docker/docker/cli/debug" |
|
| 13 | 14 |
"github.com/docker/docker/container" |
| 14 | 15 |
"github.com/docker/docker/dockerversion" |
| 15 | 16 |
"github.com/docker/docker/pkg/fileutils" |
| ... | ... |
@@ -19,7 +20,6 @@ import ( |
| 19 | 19 |
"github.com/docker/docker/pkg/sysinfo" |
| 20 | 20 |
"github.com/docker/docker/pkg/system" |
| 21 | 21 |
"github.com/docker/docker/registry" |
| 22 |
- "github.com/docker/docker/utils" |
|
| 23 | 22 |
"github.com/docker/docker/volume/drivers" |
| 24 | 23 |
"github.com/docker/go-connections/sockets" |
| 25 | 24 |
) |
| ... | ... |
@@ -102,7 +102,7 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
|
| 102 | 102 |
IPv4Forwarding: !sysInfo.IPv4ForwardingDisabled, |
| 103 | 103 |
BridgeNfIptables: !sysInfo.BridgeNFCallIPTablesDisabled, |
| 104 | 104 |
BridgeNfIP6tables: !sysInfo.BridgeNFCallIP6TablesDisabled, |
| 105 |
- Debug: utils.IsDebugEnabled(), |
|
| 105 |
+ Debug: debug.IsEnabled(), |
|
| 106 | 106 |
NFd: fileutils.GetTotalUsedFds(), |
| 107 | 107 |
NGoroutines: runtime.NumGoroutine(), |
| 108 | 108 |
SystemTime: time.Now().Format(time.RFC3339Nano), |
| ... | ... |
@@ -5,16 +5,16 @@ import ( |
| 5 | 5 |
"strings" |
| 6 | 6 |
|
| 7 | 7 |
"github.com/Sirupsen/logrus" |
| 8 |
+ "github.com/docker/docker/api" |
|
| 8 | 9 |
"github.com/docker/docker/container" |
| 9 | 10 |
"github.com/docker/docker/pkg/namesgenerator" |
| 10 | 11 |
"github.com/docker/docker/pkg/registrar" |
| 11 | 12 |
"github.com/docker/docker/pkg/stringid" |
| 12 |
- "github.com/docker/docker/utils" |
|
| 13 | 13 |
) |
| 14 | 14 |
|
| 15 | 15 |
var ( |
| 16 |
- validContainerNameChars = utils.RestrictedNameChars |
|
| 17 |
- validContainerNamePattern = utils.RestrictedNamePattern |
|
| 16 |
+ validContainerNameChars = api.RestrictedNameChars |
|
| 17 |
+ validContainerNamePattern = api.RestrictedNamePattern |
|
| 18 | 18 |
) |
| 19 | 19 |
|
| 20 | 20 |
func (daemon *Daemon) registerName(container *container.Container) error {
|
| ... | ... |
@@ -1,19 +1,23 @@ |
| 1 | 1 |
package distribution |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "fmt" |
|
| 5 |
+ "io/ioutil" |
|
| 4 | 6 |
"net/http" |
| 5 | 7 |
"net/http/httptest" |
| 6 | 8 |
"net/url" |
| 7 | 9 |
"os" |
| 10 |
+ "runtime" |
|
| 8 | 11 |
"strings" |
| 9 | 12 |
"testing" |
| 10 | 13 |
|
| 11 | 14 |
"github.com/Sirupsen/logrus" |
| 12 | 15 |
"github.com/docker/docker/api/types" |
| 13 | 16 |
registrytypes "github.com/docker/docker/api/types/registry" |
| 17 |
+ "github.com/docker/docker/pkg/archive" |
|
| 18 |
+ "github.com/docker/docker/pkg/stringid" |
|
| 14 | 19 |
"github.com/docker/docker/reference" |
| 15 | 20 |
"github.com/docker/docker/registry" |
| 16 |
- "github.com/docker/docker/utils" |
|
| 17 | 21 |
"golang.org/x/net/context" |
| 18 | 22 |
) |
| 19 | 23 |
|
| ... | ... |
@@ -38,7 +42,7 @@ func (h *tokenPassThruHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) |
| 38 | 38 |
} |
| 39 | 39 |
|
| 40 | 40 |
func testTokenPassThru(t *testing.T, ts *httptest.Server) {
|
| 41 |
- tmp, err := utils.TestDirectory("")
|
|
| 41 |
+ tmp, err := testDirectory("")
|
|
| 42 | 42 |
if err != nil {
|
| 43 | 43 |
t.Fatal(err) |
| 44 | 44 |
} |
| ... | ... |
@@ -134,3 +138,36 @@ func TestTokenPassThruDifferentHost(t *testing.T) {
|
| 134 | 134 |
t.Fatal("Redirect should not forward Authorization header to another host")
|
| 135 | 135 |
} |
| 136 | 136 |
} |
| 137 |
+ |
|
| 138 |
+// TestDirectory creates a new temporary directory and returns its path. |
|
| 139 |
+// The contents of directory at path `templateDir` is copied into the |
|
| 140 |
+// new directory. |
|
| 141 |
+func testDirectory(templateDir string) (dir string, err error) {
|
|
| 142 |
+ testID := stringid.GenerateNonCryptoID()[:4] |
|
| 143 |
+ prefix := fmt.Sprintf("docker-test%s-%s-", testID, getCallerName(2))
|
|
| 144 |
+ if prefix == "" {
|
|
| 145 |
+ prefix = "docker-test-" |
|
| 146 |
+ } |
|
| 147 |
+ dir, err = ioutil.TempDir("", prefix)
|
|
| 148 |
+ if err = os.Remove(dir); err != nil {
|
|
| 149 |
+ return |
|
| 150 |
+ } |
|
| 151 |
+ if templateDir != "" {
|
|
| 152 |
+ if err = archive.CopyWithTar(templateDir, dir); err != nil {
|
|
| 153 |
+ return |
|
| 154 |
+ } |
|
| 155 |
+ } |
|
| 156 |
+ return |
|
| 157 |
+} |
|
| 158 |
+ |
|
| 159 |
+// getCallerName introspects the call stack and returns the name of the |
|
| 160 |
+// function `depth` levels down in the stack. |
|
| 161 |
+func getCallerName(depth int) string {
|
|
| 162 |
+ // Use the caller function name as a prefix. |
|
| 163 |
+ // This helps trace temp directories back to their test. |
|
| 164 |
+ pc, _, _, _ := runtime.Caller(depth + 1) |
|
| 165 |
+ callerLongName := runtime.FuncForPC(pc).Name() |
|
| 166 |
+ parts := strings.Split(callerLongName, ".") |
|
| 167 |
+ callerShortName := parts[len(parts)-1] |
|
| 168 |
+ return callerShortName |
|
| 169 |
+} |
| ... | ... |
@@ -21,8 +21,7 @@ import ( |
| 21 | 21 |
"github.com/Sirupsen/logrus" |
| 22 | 22 |
containerd "github.com/docker/containerd/api/grpc/types" |
| 23 | 23 |
"github.com/docker/docker/pkg/locker" |
| 24 |
- sysinfo "github.com/docker/docker/pkg/system" |
|
| 25 |
- "github.com/docker/docker/utils" |
|
| 24 |
+ "github.com/docker/docker/pkg/system" |
|
| 26 | 25 |
"github.com/golang/protobuf/ptypes" |
| 27 | 26 |
"github.com/golang/protobuf/ptypes/timestamp" |
| 28 | 27 |
"golang.org/x/net/context" |
| ... | ... |
@@ -81,7 +80,7 @@ func New(stateDir string, options ...RemoteOption) (_ Remote, err error) {
|
| 81 | 81 |
} |
| 82 | 82 |
} |
| 83 | 83 |
|
| 84 |
- if err := sysinfo.MkdirAll(stateDir, 0700); err != nil {
|
|
| 84 |
+ if err := system.MkdirAll(stateDir, 0700); err != nil {
|
|
| 85 | 85 |
return nil, err |
| 86 | 86 |
} |
| 87 | 87 |
|
| ... | ... |
@@ -164,8 +163,8 @@ func (r *remote) handleConnectionChange() {
|
| 164 | 164 |
transientFailureCount++ |
| 165 | 165 |
if transientFailureCount >= maxConnectionRetryCount {
|
| 166 | 166 |
transientFailureCount = 0 |
| 167 |
- if utils.IsProcessAlive(r.daemonPid) {
|
|
| 168 |
- utils.KillProcess(r.daemonPid) |
|
| 167 |
+ if system.IsProcessAlive(r.daemonPid) {
|
|
| 168 |
+ system.KillProcess(r.daemonPid) |
|
| 169 | 169 |
} |
| 170 | 170 |
<-r.daemonWaitCh |
| 171 | 171 |
if err := r.runContainerdDaemon(); err != nil { //FIXME: Handle error
|
| ... | ... |
@@ -188,13 +187,13 @@ func (r *remote) Cleanup() {
|
| 188 | 188 |
|
| 189 | 189 |
// Wait up to 15secs for it to stop |
| 190 | 190 |
for i := time.Duration(0); i < containerdShutdownTimeout; i += time.Second {
|
| 191 |
- if !utils.IsProcessAlive(r.daemonPid) {
|
|
| 191 |
+ if !system.IsProcessAlive(r.daemonPid) {
|
|
| 192 | 192 |
break |
| 193 | 193 |
} |
| 194 | 194 |
time.Sleep(time.Second) |
| 195 | 195 |
} |
| 196 | 196 |
|
| 197 |
- if utils.IsProcessAlive(r.daemonPid) {
|
|
| 197 |
+ if system.IsProcessAlive(r.daemonPid) {
|
|
| 198 | 198 |
logrus.Warnf("libcontainerd: containerd (%d) didn't stop within 15 secs, killing it\n", r.daemonPid)
|
| 199 | 199 |
syscall.Kill(r.daemonPid, syscall.SIGKILL) |
| 200 | 200 |
} |
| ... | ... |
@@ -354,7 +353,7 @@ func (r *remote) runContainerdDaemon() error {
|
| 354 | 354 |
if err != nil {
|
| 355 | 355 |
return err |
| 356 | 356 |
} |
| 357 |
- if utils.IsProcessAlive(int(pid)) {
|
|
| 357 |
+ if system.IsProcessAlive(int(pid)) {
|
|
| 358 | 358 |
logrus.Infof("libcontainerd: previous instance of containerd still alive (%d)", pid)
|
| 359 | 359 |
r.daemonPid = int(pid) |
| 360 | 360 |
return nil |
| ... | ... |
@@ -417,11 +416,11 @@ func (r *remote) runContainerdDaemon() error {
|
| 417 | 417 |
} |
| 418 | 418 |
logrus.Infof("libcontainerd: new containerd process, pid: %d", cmd.Process.Pid)
|
| 419 | 419 |
if err := setOOMScore(cmd.Process.Pid, r.oomScore); err != nil {
|
| 420 |
- utils.KillProcess(cmd.Process.Pid) |
|
| 420 |
+ system.KillProcess(cmd.Process.Pid) |
|
| 421 | 421 |
return err |
| 422 | 422 |
} |
| 423 | 423 |
if _, err := f.WriteString(fmt.Sprintf("%d", cmd.Process.Pid)); err != nil {
|
| 424 |
- utils.KillProcess(cmd.Process.Pid) |
|
| 424 |
+ system.KillProcess(cmd.Process.Pid) |
|
| 425 | 425 |
return err |
| 426 | 426 |
} |
| 427 | 427 |
|
| 428 | 428 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,22 @@ |
| 0 |
+// +build linux freebsd solaris |
|
| 1 |
+ |
|
| 2 |
+package system |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "syscall" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// IsProcessAlive returns true if process with a given pid is running. |
|
| 9 |
+func IsProcessAlive(pid int) bool {
|
|
| 10 |
+ err := syscall.Kill(pid, syscall.Signal(0)) |
|
| 11 |
+ if err == nil || err == syscall.EPERM {
|
|
| 12 |
+ return true |
|
| 13 |
+ } |
|
| 14 |
+ |
|
| 15 |
+ return false |
|
| 16 |
+} |
|
| 17 |
+ |
|
| 18 |
+// KillProcess force-stops a process. |
|
| 19 |
+func KillProcess(pid int) {
|
|
| 20 |
+ syscall.Kill(pid, syscall.SIGKILL) |
|
| 21 |
+} |
| 0 | 22 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,20 @@ |
| 0 |
+package system |
|
| 1 |
+ |
|
| 2 |
+// IsProcessAlive returns true if process with a given pid is running. |
|
| 3 |
+func IsProcessAlive(pid int) bool {
|
|
| 4 |
+ // TODO Windows containerd. Not sure this is needed |
|
| 5 |
+ // p, err := os.FindProcess(pid) |
|
| 6 |
+ // if err == nil {
|
|
| 7 |
+ // return true |
|
| 8 |
+ // } |
|
| 9 |
+ return false |
|
| 10 |
+} |
|
| 11 |
+ |
|
| 12 |
+// KillProcess force-stops a process. |
|
| 13 |
+func KillProcess(pid int) {
|
|
| 14 |
+ // TODO Windows containerd. Not sure this is needed |
|
| 15 |
+ // p, err := os.FindProcess(pid) |
|
| 16 |
+ // if err == nil {
|
|
| 17 |
+ // p.Kill() |
|
| 18 |
+ // } |
|
| 19 |
+} |
| 0 | 20 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,42 @@ |
| 0 |
+package templates |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/json" |
|
| 4 |
+ "strings" |
|
| 5 |
+ "text/template" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// basicFunctions are the set of initial |
|
| 9 |
+// functions provided to every template. |
|
| 10 |
+var basicFunctions = template.FuncMap{
|
|
| 11 |
+ "json": func(v interface{}) string {
|
|
| 12 |
+ a, _ := json.Marshal(v) |
|
| 13 |
+ return string(a) |
|
| 14 |
+ }, |
|
| 15 |
+ "split": strings.Split, |
|
| 16 |
+ "join": strings.Join, |
|
| 17 |
+ "title": strings.Title, |
|
| 18 |
+ "lower": strings.ToLower, |
|
| 19 |
+ "upper": strings.ToUpper, |
|
| 20 |
+ "pad": padWithSpace, |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 23 |
+// Parse creates a new annonymous template with the basic functions |
|
| 24 |
+// and parses the given format. |
|
| 25 |
+func Parse(format string) (*template.Template, error) {
|
|
| 26 |
+ return NewParse("", format)
|
|
| 27 |
+} |
|
| 28 |
+ |
|
| 29 |
+// NewParse creates a new tagged template with the basic functions |
|
| 30 |
+// and parses the given format. |
|
| 31 |
+func NewParse(tag, format string) (*template.Template, error) {
|
|
| 32 |
+ return template.New(tag).Funcs(basicFunctions).Parse(format) |
|
| 33 |
+} |
|
| 34 |
+ |
|
| 35 |
+// padWithSpace adds whitespace to the input if the input is non-empty |
|
| 36 |
+func padWithSpace(source string, prefix, suffix int) string {
|
|
| 37 |
+ if source == "" {
|
|
| 38 |
+ return source |
|
| 39 |
+ } |
|
| 40 |
+ return strings.Repeat(" ", prefix) + source + strings.Repeat(" ", suffix)
|
|
| 41 |
+} |
| 0 | 42 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,38 @@ |
| 0 |
+package templates |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "bytes" |
|
| 4 |
+ "testing" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+func TestParseStringFunctions(t *testing.T) {
|
|
| 8 |
+ tm, err := Parse(`{{join (split . ":") "/"}}`)
|
|
| 9 |
+ if err != nil {
|
|
| 10 |
+ t.Fatal(err) |
|
| 11 |
+ } |
|
| 12 |
+ |
|
| 13 |
+ var b bytes.Buffer |
|
| 14 |
+ if err := tm.Execute(&b, "text:with:colon"); err != nil {
|
|
| 15 |
+ t.Fatal(err) |
|
| 16 |
+ } |
|
| 17 |
+ want := "text/with/colon" |
|
| 18 |
+ if b.String() != want {
|
|
| 19 |
+ t.Fatalf("expected %s, got %s", want, b.String())
|
|
| 20 |
+ } |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 23 |
+func TestNewParse(t *testing.T) {
|
|
| 24 |
+ tm, err := NewParse("foo", "this is a {{ . }}")
|
|
| 25 |
+ if err != nil {
|
|
| 26 |
+ t.Fatal(err) |
|
| 27 |
+ } |
|
| 28 |
+ |
|
| 29 |
+ var b bytes.Buffer |
|
| 30 |
+ if err := tm.Execute(&b, "string"); err != nil {
|
|
| 31 |
+ t.Fatal(err) |
|
| 32 |
+ } |
|
| 33 |
+ want := "this is a string" |
|
| 34 |
+ if b.String() != want {
|
|
| 35 |
+ t.Fatalf("expected %s, got %s", want, b.String())
|
|
| 36 |
+ } |
|
| 37 |
+} |
| 18 | 18 |
deleted file mode 100644 |
| ... | ... |
@@ -1,26 +0,0 @@ |
| 1 |
-package utils |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "os" |
|
| 5 |
- |
|
| 6 |
- "github.com/Sirupsen/logrus" |
|
| 7 |
-) |
|
| 8 |
- |
|
| 9 |
-// EnableDebug sets the DEBUG env var to true |
|
| 10 |
-// and makes the logger to log at debug level. |
|
| 11 |
-func EnableDebug() {
|
|
| 12 |
- os.Setenv("DEBUG", "1")
|
|
| 13 |
- logrus.SetLevel(logrus.DebugLevel) |
|
| 14 |
-} |
|
| 15 |
- |
|
| 16 |
-// DisableDebug sets the DEBUG env var to false |
|
| 17 |
-// and makes the logger to log at info level. |
|
| 18 |
-func DisableDebug() {
|
|
| 19 |
- os.Setenv("DEBUG", "")
|
|
| 20 |
- logrus.SetLevel(logrus.InfoLevel) |
|
| 21 |
-} |
|
| 22 |
- |
|
| 23 |
-// IsDebugEnabled checks whether the debug flag is set or not. |
|
| 24 |
-func IsDebugEnabled() bool {
|
|
| 25 |
- return os.Getenv("DEBUG") != ""
|
|
| 26 |
-} |
| 27 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,43 +0,0 @@ |
| 1 |
-package utils |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "os" |
|
| 5 |
- "testing" |
|
| 6 |
- |
|
| 7 |
- "github.com/Sirupsen/logrus" |
|
| 8 |
-) |
|
| 9 |
- |
|
| 10 |
-func TestEnableDebug(t *testing.T) {
|
|
| 11 |
- defer func() {
|
|
| 12 |
- os.Setenv("DEBUG", "")
|
|
| 13 |
- logrus.SetLevel(logrus.InfoLevel) |
|
| 14 |
- }() |
|
| 15 |
- EnableDebug() |
|
| 16 |
- if os.Getenv("DEBUG") != "1" {
|
|
| 17 |
- t.Fatalf("expected DEBUG=1, got %s\n", os.Getenv("DEBUG"))
|
|
| 18 |
- } |
|
| 19 |
- if logrus.GetLevel() != logrus.DebugLevel {
|
|
| 20 |
- t.Fatalf("expected log level %v, got %v\n", logrus.DebugLevel, logrus.GetLevel())
|
|
| 21 |
- } |
|
| 22 |
-} |
|
| 23 |
- |
|
| 24 |
-func TestDisableDebug(t *testing.T) {
|
|
| 25 |
- DisableDebug() |
|
| 26 |
- if os.Getenv("DEBUG") != "" {
|
|
| 27 |
- t.Fatalf("expected DEBUG=\"\", got %s\n", os.Getenv("DEBUG"))
|
|
| 28 |
- } |
|
| 29 |
- if logrus.GetLevel() != logrus.InfoLevel {
|
|
| 30 |
- t.Fatalf("expected log level %v, got %v\n", logrus.InfoLevel, logrus.GetLevel())
|
|
| 31 |
- } |
|
| 32 |
-} |
|
| 33 |
- |
|
| 34 |
-func TestDebugEnabled(t *testing.T) {
|
|
| 35 |
- EnableDebug() |
|
| 36 |
- if !IsDebugEnabled() {
|
|
| 37 |
- t.Fatal("expected debug enabled, got false")
|
|
| 38 |
- } |
|
| 39 |
- DisableDebug() |
|
| 40 |
- if IsDebugEnabled() {
|
|
| 41 |
- t.Fatal("expected debug disabled, got true")
|
|
| 42 |
- } |
|
| 43 |
-} |
| 44 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,9 +0,0 @@ |
| 1 |
-package utils |
|
| 2 |
- |
|
| 3 |
-import "regexp" |
|
| 4 |
- |
|
| 5 |
-// RestrictedNameChars collects the characters allowed to represent a name, normally used to validate container and volume names. |
|
| 6 |
-const RestrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]` |
|
| 7 |
- |
|
| 8 |
-// RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters. |
|
| 9 |
-var RestrictedNamePattern = regexp.MustCompile(`^` + RestrictedNameChars + `+$`) |
| 10 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,22 +0,0 @@ |
| 1 |
-// +build linux freebsd solaris |
|
| 2 |
- |
|
| 3 |
-package utils |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "syscall" |
|
| 7 |
-) |
|
| 8 |
- |
|
| 9 |
-// IsProcessAlive returns true if process with a given pid is running. |
|
| 10 |
-func IsProcessAlive(pid int) bool {
|
|
| 11 |
- err := syscall.Kill(pid, syscall.Signal(0)) |
|
| 12 |
- if err == nil || err == syscall.EPERM {
|
|
| 13 |
- return true |
|
| 14 |
- } |
|
| 15 |
- |
|
| 16 |
- return false |
|
| 17 |
-} |
|
| 18 |
- |
|
| 19 |
-// KillProcess force-stops a process. |
|
| 20 |
-func KillProcess(pid int) {
|
|
| 21 |
- syscall.Kill(pid, syscall.SIGKILL) |
|
| 22 |
-} |
| 23 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,20 +0,0 @@ |
| 1 |
-package utils |
|
| 2 |
- |
|
| 3 |
-// IsProcessAlive returns true if process with a given pid is running. |
|
| 4 |
-func IsProcessAlive(pid int) bool {
|
|
| 5 |
- // TODO Windows containerd. Not sure this is needed |
|
| 6 |
- // p, err := os.FindProcess(pid) |
|
| 7 |
- // if err == nil {
|
|
| 8 |
- // return true |
|
| 9 |
- // } |
|
| 10 |
- return false |
|
| 11 |
-} |
|
| 12 |
- |
|
| 13 |
-// KillProcess force-stops a process. |
|
| 14 |
-func KillProcess(pid int) {
|
|
| 15 |
- // TODO Windows containerd. Not sure this is needed |
|
| 16 |
- // p, err := os.FindProcess(pid) |
|
| 17 |
- // if err == nil {
|
|
| 18 |
- // p.Kill() |
|
| 19 |
- // } |
|
| 20 |
-} |
| 21 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,42 +0,0 @@ |
| 1 |
-package templates |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "encoding/json" |
|
| 5 |
- "strings" |
|
| 6 |
- "text/template" |
|
| 7 |
-) |
|
| 8 |
- |
|
| 9 |
-// basicFunctions are the set of initial |
|
| 10 |
-// functions provided to every template. |
|
| 11 |
-var basicFunctions = template.FuncMap{
|
|
| 12 |
- "json": func(v interface{}) string {
|
|
| 13 |
- a, _ := json.Marshal(v) |
|
| 14 |
- return string(a) |
|
| 15 |
- }, |
|
| 16 |
- "split": strings.Split, |
|
| 17 |
- "join": strings.Join, |
|
| 18 |
- "title": strings.Title, |
|
| 19 |
- "lower": strings.ToLower, |
|
| 20 |
- "upper": strings.ToUpper, |
|
| 21 |
- "pad": padWithSpace, |
|
| 22 |
-} |
|
| 23 |
- |
|
| 24 |
-// Parse creates a new annonymous template with the basic functions |
|
| 25 |
-// and parses the given format. |
|
| 26 |
-func Parse(format string) (*template.Template, error) {
|
|
| 27 |
- return NewParse("", format)
|
|
| 28 |
-} |
|
| 29 |
- |
|
| 30 |
-// NewParse creates a new tagged template with the basic functions |
|
| 31 |
-// and parses the given format. |
|
| 32 |
-func NewParse(tag, format string) (*template.Template, error) {
|
|
| 33 |
- return template.New(tag).Funcs(basicFunctions).Parse(format) |
|
| 34 |
-} |
|
| 35 |
- |
|
| 36 |
-// padWithSpace adds whitespace to the input if the input is non-empty |
|
| 37 |
-func padWithSpace(source string, prefix, suffix int) string {
|
|
| 38 |
- if source == "" {
|
|
| 39 |
- return source |
|
| 40 |
- } |
|
| 41 |
- return strings.Repeat(" ", prefix) + source + strings.Repeat(" ", suffix)
|
|
| 42 |
-} |
| 43 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,38 +0,0 @@ |
| 1 |
-package templates |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "bytes" |
|
| 5 |
- "testing" |
|
| 6 |
-) |
|
| 7 |
- |
|
| 8 |
-func TestParseStringFunctions(t *testing.T) {
|
|
| 9 |
- tm, err := Parse(`{{join (split . ":") "/"}}`)
|
|
| 10 |
- if err != nil {
|
|
| 11 |
- t.Fatal(err) |
|
| 12 |
- } |
|
| 13 |
- |
|
| 14 |
- var b bytes.Buffer |
|
| 15 |
- if err := tm.Execute(&b, "text:with:colon"); err != nil {
|
|
| 16 |
- t.Fatal(err) |
|
| 17 |
- } |
|
| 18 |
- want := "text/with/colon" |
|
| 19 |
- if b.String() != want {
|
|
| 20 |
- t.Fatalf("expected %s, got %s", want, b.String())
|
|
| 21 |
- } |
|
| 22 |
-} |
|
| 23 |
- |
|
| 24 |
-func TestNewParse(t *testing.T) {
|
|
| 25 |
- tm, err := NewParse("foo", "this is a {{ . }}")
|
|
| 26 |
- if err != nil {
|
|
| 27 |
- t.Fatal(err) |
|
| 28 |
- } |
|
| 29 |
- |
|
| 30 |
- var b bytes.Buffer |
|
| 31 |
- if err := tm.Execute(&b, "string"); err != nil {
|
|
| 32 |
- t.Fatal(err) |
|
| 33 |
- } |
|
| 34 |
- want := "this is a string" |
|
| 35 |
- if b.String() != want {
|
|
| 36 |
- t.Fatalf("expected %s, got %s", want, b.String())
|
|
| 37 |
- } |
|
| 38 |
-} |
| 39 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,87 +0,0 @@ |
| 1 |
-package utils |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "fmt" |
|
| 5 |
- "io/ioutil" |
|
| 6 |
- "os" |
|
| 7 |
- "runtime" |
|
| 8 |
- "strings" |
|
| 9 |
- |
|
| 10 |
- "github.com/docker/docker/pkg/archive" |
|
| 11 |
- "github.com/docker/docker/pkg/stringid" |
|
| 12 |
-) |
|
| 13 |
- |
|
| 14 |
-var globalTestID string |
|
| 15 |
- |
|
| 16 |
-// TestDirectory creates a new temporary directory and returns its path. |
|
| 17 |
-// The contents of directory at path `templateDir` is copied into the |
|
| 18 |
-// new directory. |
|
| 19 |
-func TestDirectory(templateDir string) (dir string, err error) {
|
|
| 20 |
- if globalTestID == "" {
|
|
| 21 |
- globalTestID = stringid.GenerateNonCryptoID()[:4] |
|
| 22 |
- } |
|
| 23 |
- prefix := fmt.Sprintf("docker-test%s-%s-", globalTestID, GetCallerName(2))
|
|
| 24 |
- if prefix == "" {
|
|
| 25 |
- prefix = "docker-test-" |
|
| 26 |
- } |
|
| 27 |
- dir, err = ioutil.TempDir("", prefix)
|
|
| 28 |
- if err = os.Remove(dir); err != nil {
|
|
| 29 |
- return |
|
| 30 |
- } |
|
| 31 |
- if templateDir != "" {
|
|
| 32 |
- if err = archive.CopyWithTar(templateDir, dir); err != nil {
|
|
| 33 |
- return |
|
| 34 |
- } |
|
| 35 |
- } |
|
| 36 |
- return |
|
| 37 |
-} |
|
| 38 |
- |
|
| 39 |
-// GetCallerName introspects the call stack and returns the name of the |
|
| 40 |
-// function `depth` levels down in the stack. |
|
| 41 |
-func GetCallerName(depth int) string {
|
|
| 42 |
- // Use the caller function name as a prefix. |
|
| 43 |
- // This helps trace temp directories back to their test. |
|
| 44 |
- pc, _, _, _ := runtime.Caller(depth + 1) |
|
| 45 |
- callerLongName := runtime.FuncForPC(pc).Name() |
|
| 46 |
- parts := strings.Split(callerLongName, ".") |
|
| 47 |
- callerShortName := parts[len(parts)-1] |
|
| 48 |
- return callerShortName |
|
| 49 |
-} |
|
| 50 |
- |
|
| 51 |
-// ReplaceOrAppendEnvValues returns the defaults with the overrides either |
|
| 52 |
-// replaced by env key or appended to the list |
|
| 53 |
-func ReplaceOrAppendEnvValues(defaults, overrides []string) []string {
|
|
| 54 |
- cache := make(map[string]int, len(defaults)) |
|
| 55 |
- for i, e := range defaults {
|
|
| 56 |
- parts := strings.SplitN(e, "=", 2) |
|
| 57 |
- cache[parts[0]] = i |
|
| 58 |
- } |
|
| 59 |
- |
|
| 60 |
- for _, value := range overrides {
|
|
| 61 |
- // Values w/o = means they want this env to be removed/unset. |
|
| 62 |
- if !strings.Contains(value, "=") {
|
|
| 63 |
- if i, exists := cache[value]; exists {
|
|
| 64 |
- defaults[i] = "" // Used to indicate it should be removed |
|
| 65 |
- } |
|
| 66 |
- continue |
|
| 67 |
- } |
|
| 68 |
- |
|
| 69 |
- // Just do a normal set/update |
|
| 70 |
- parts := strings.SplitN(value, "=", 2) |
|
| 71 |
- if i, exists := cache[parts[0]]; exists {
|
|
| 72 |
- defaults[i] = value |
|
| 73 |
- } else {
|
|
| 74 |
- defaults = append(defaults, value) |
|
| 75 |
- } |
|
| 76 |
- } |
|
| 77 |
- |
|
| 78 |
- // Now remove all entries that we want to "unset" |
|
| 79 |
- for i := 0; i < len(defaults); i++ {
|
|
| 80 |
- if defaults[i] == "" {
|
|
| 81 |
- defaults = append(defaults[:i], defaults[i+1:]...) |
|
| 82 |
- i-- |
|
| 83 |
- } |
|
| 84 |
- } |
|
| 85 |
- |
|
| 86 |
- return defaults |
|
| 87 |
-} |
| 88 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,21 +0,0 @@ |
| 1 |
-package utils |
|
| 2 |
- |
|
| 3 |
-import "testing" |
|
| 4 |
- |
|
| 5 |
-func TestReplaceAndAppendEnvVars(t *testing.T) {
|
|
| 6 |
- var ( |
|
| 7 |
- d = []string{"HOME=/"}
|
|
| 8 |
- o = []string{"HOME=/root", "TERM=xterm"}
|
|
| 9 |
- ) |
|
| 10 |
- |
|
| 11 |
- env := ReplaceOrAppendEnvValues(d, o) |
|
| 12 |
- if len(env) != 2 {
|
|
| 13 |
- t.Fatalf("expected len of 2 got %d", len(env))
|
|
| 14 |
- } |
|
| 15 |
- if env[0] != "HOME=/root" {
|
|
| 16 |
- t.Fatalf("expected HOME=/root got '%s'", env[0])
|
|
| 17 |
- } |
|
| 18 |
- if env[1] != "TERM=xterm" {
|
|
| 19 |
- t.Fatalf("expected TERM=xterm got '%s'", env[1])
|
|
| 20 |
- } |
|
| 21 |
-} |
| ... | ... |
@@ -16,9 +16,9 @@ import ( |
| 16 | 16 |
"github.com/pkg/errors" |
| 17 | 17 |
|
| 18 | 18 |
"github.com/Sirupsen/logrus" |
| 19 |
+ "github.com/docker/docker/api" |
|
| 19 | 20 |
"github.com/docker/docker/pkg/idtools" |
| 20 | 21 |
"github.com/docker/docker/pkg/mount" |
| 21 |
- "github.com/docker/docker/utils" |
|
| 22 | 22 |
"github.com/docker/docker/volume" |
| 23 | 23 |
) |
| 24 | 24 |
|
| ... | ... |
@@ -36,7 +36,7 @@ var ( |
| 36 | 36 |
// volumeNameRegex ensures the name assigned for the volume is valid. |
| 37 | 37 |
// This name is used to create the bind directory, so we need to avoid characters that |
| 38 | 38 |
// would make the path to escape the root directory. |
| 39 |
- volumeNameRegex = utils.RestrictedNamePattern |
|
| 39 |
+ volumeNameRegex = api.RestrictedNamePattern |
|
| 40 | 40 |
) |
| 41 | 41 |
|
| 42 | 42 |
type validationError struct {
|
| ... | ... |
@@ -269,7 +269,7 @@ func (r *Root) validateName(name string) error {
|
| 269 | 269 |
return validationError{fmt.Errorf("volume name is too short, names should be at least two alphanumeric characters")}
|
| 270 | 270 |
} |
| 271 | 271 |
if !volumeNameRegex.MatchString(name) {
|
| 272 |
- return validationError{fmt.Errorf("%q includes invalid characters for a local volume name, only %q are allowed. If you intented to pass a host directory, use absolute path", name, utils.RestrictedNameChars)}
|
|
| 272 |
+ return validationError{fmt.Errorf("%q includes invalid characters for a local volume name, only %q are allowed. If you intented to pass a host directory, use absolute path", name, api.RestrictedNameChars)}
|
|
| 273 | 273 |
} |
| 274 | 274 |
return nil |
| 275 | 275 |
} |