diff --git a/api/client/commands.go b/api/client/commands.go index 5689dfd2cf39a..065322a6e9f3c 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -33,7 +33,6 @@ import ( "github.com/docker/docker/nat" "github.com/docker/docker/opts" "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/homedir" flag "github.com/docker/docker/pkg/mflag" @@ -43,6 +42,7 @@ import ( "github.com/docker/docker/pkg/promise" "github.com/docker/docker/pkg/resolvconf" "github.com/docker/docker/pkg/signal" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/term" "github.com/docker/docker/pkg/timeutils" @@ -1165,7 +1165,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error { if *noTrunc { fmt.Fprintf(w, "%s\t", outID) } else { - fmt.Fprintf(w, "%s\t", common.TruncateID(outID)) + fmt.Fprintf(w, "%s\t", stringid.TruncateID(outID)) } fmt.Fprintf(w, "%s ago\t", units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0)))) @@ -1180,7 +1180,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error { if *noTrunc { fmt.Fprintln(w, outID) } else { - fmt.Fprintln(w, common.TruncateID(outID)) + fmt.Fprintln(w, stringid.TruncateID(outID)) } } } @@ -1479,7 +1479,7 @@ func (cli *DockerCli) CmdImages(args ...string) error { } if matchName != "" { - if matchName == image.Get("Id") || matchName == common.TruncateID(image.Get("Id")) { + if matchName == image.Get("Id") || matchName == stringid.TruncateID(image.Get("Id")) { startImage = image } @@ -1549,7 +1549,7 @@ func (cli *DockerCli) CmdImages(args ...string) error { for _, out := range outs.Data { outID := out.Get("Id") if !*noTrunc { - outID = common.TruncateID(outID) + outID = stringid.TruncateID(outID) } repoTags := out.GetList("RepoTags") @@ -1629,8 +1629,8 @@ func (cli *DockerCli) printVizNode(noTrunc bool, image *engine.Env, prefix strin imageID = image.Get("Id") parentID = image.Get("ParentId") } else { - imageID = common.TruncateID(image.Get("Id")) - parentID = common.TruncateID(image.Get("ParentId")) + imageID = stringid.TruncateID(image.Get("Id")) + parentID = stringid.TruncateID(image.Get("ParentId")) } if parentID == "" { fmt.Fprintf(cli.out, " base -> \"%s\" [style=invis]\n", imageID) @@ -1649,7 +1649,7 @@ func (cli *DockerCli) printTreeNode(noTrunc bool, image *engine.Env, prefix stri if noTrunc { imageID = image.Get("Id") } else { - imageID = common.TruncateID(image.Get("Id")) + imageID = stringid.TruncateID(image.Get("Id")) } fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, units.HumanSize(float64(image.GetInt64("VirtualSize")))) @@ -1757,7 +1757,7 @@ func (cli *DockerCli) CmdPs(args ...string) error { outID := out.Get("Id") if !*noTrunc { - outID = common.TruncateID(outID) + outID = stringid.TruncateID(outID) } if *quiet { diff --git a/builder/evaluator.go b/builder/evaluator.go index 5e353c02b39e1..ec568d1fca6cd 100644 --- a/builder/evaluator.go +++ b/builder/evaluator.go @@ -32,8 +32,8 @@ import ( "github.com/docker/docker/builder/parser" "github.com/docker/docker/daemon" "github.com/docker/docker/engine" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/fileutils" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/tarsum" "github.com/docker/docker/registry" @@ -177,7 +177,7 @@ func (b *Builder) Run(context io.Reader) (string, error) { } return "", err } - fmt.Fprintf(b.OutStream, " ---> %s\n", common.TruncateID(b.image)) + fmt.Fprintf(b.OutStream, " ---> %s\n", stringid.TruncateID(b.image)) if b.Remove { b.clearTmp() } @@ -187,7 +187,7 @@ func (b *Builder) Run(context io.Reader) (string, error) { return "", fmt.Errorf("No image was generated. Is your Dockerfile empty?") } - fmt.Fprintf(b.OutStream, "Successfully built %s\n", common.TruncateID(b.image)) + fmt.Fprintf(b.OutStream, "Successfully built %s\n", stringid.TruncateID(b.image)) return b.image, nil } diff --git a/builder/internals.go b/builder/internals.go index 7c22b47b2b72d..e7e792aa0f0a9 100644 --- a/builder/internals.go +++ b/builder/internals.go @@ -25,10 +25,10 @@ import ( imagepkg "github.com/docker/docker/image" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/chrootarchive" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/progressreader" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/tarsum" @@ -557,7 +557,7 @@ func (b *Builder) create() (*daemon.Container, error) { } b.TmpContainers[c.ID] = struct{}{} - fmt.Fprintf(b.OutStream, " ---> Running in %s\n", common.TruncateID(c.ID)) + fmt.Fprintf(b.OutStream, " ---> Running in %s\n", stringid.TruncateID(c.ID)) if len(config.Cmd) > 0 { // override the entry point that may have been picked up from the base image @@ -753,11 +753,11 @@ func (b *Builder) clearTmp() { } if err := b.Daemon.Rm(tmp); err != nil { - fmt.Fprintf(b.OutStream, "Error removing intermediate container %s: %v\n", common.TruncateID(c), err) + fmt.Fprintf(b.OutStream, "Error removing intermediate container %s: %v\n", stringid.TruncateID(c), err) return } b.Daemon.DeleteVolumes(tmp.VolumePaths()) delete(b.TmpContainers, c) - fmt.Fprintf(b.OutStream, "Removing intermediate container %s\n", common.TruncateID(c)) + fmt.Fprintf(b.OutStream, "Removing intermediate container %s\n", stringid.TruncateID(c)) } } diff --git a/daemon/container.go b/daemon/container.go index db622334aaa7e..3f16ab2691428 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -30,12 +30,12 @@ import ( "github.com/docker/docker/nat" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/broadcastwriter" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/directory" "github.com/docker/docker/pkg/etchosts" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/promise" "github.com/docker/docker/pkg/resolvconf" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/ulimit" "github.com/docker/docker/runconfig" @@ -739,7 +739,7 @@ func (container *Container) Kill() error { if _, err := container.WaitStop(10 * time.Second); err != nil { // Ensure that we don't kill ourselves if pid := container.GetPid(); pid != 0 { - log.Infof("Container %s failed to exit within 10 seconds of kill - trying direct SIGKILL", common.TruncateID(container.ID)) + log.Infof("Container %s failed to exit within 10 seconds of kill - trying direct SIGKILL", stringid.TruncateID(container.ID)) if err := syscall.Kill(pid, 9); err != nil { if err != syscall.ESRCH { return err diff --git a/daemon/daemon.go b/daemon/daemon.go index 6a27a085a0210..b2c1561919fe1 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -31,13 +31,13 @@ import ( "github.com/docker/docker/image" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/broadcastwriter" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/graphdb" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/namesgenerator" "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/parsers/kernel" "github.com/docker/docker/pkg/resolvconf" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/sysinfo" "github.com/docker/docker/pkg/truncindex" "github.com/docker/docker/runconfig" @@ -517,7 +517,7 @@ func (daemon *Daemon) mergeAndVerifyConfig(config *runconfig.Config, img *image. func (daemon *Daemon) generateIdAndName(name string) (string, string, error) { var ( err error - id = common.GenerateRandomID() + id = stringid.GenerateRandomID() ) if name == "" { @@ -562,7 +562,7 @@ func (daemon *Daemon) reserveName(id, name string) (string, error) { nameAsKnownByUser := strings.TrimPrefix(name, "/") return "", fmt.Errorf( "Conflict. The name %q is already in use by container %s. You have to delete (or rename) that container to be able to reuse that name.", nameAsKnownByUser, - common.TruncateID(conflictingContainer.ID)) + stringid.TruncateID(conflictingContainer.ID)) } } return name, nil @@ -585,7 +585,7 @@ func (daemon *Daemon) generateNewName(id string) (string, error) { return name, nil } - name = "/" + common.TruncateID(id) + name = "/" + stringid.TruncateID(id) if _, err := daemon.containerGraph.Set(name, id); err != nil { return "", err } diff --git a/daemon/exec.go b/daemon/exec.go index 3af40ac014d02..c2e00e08dc1bc 100644 --- a/daemon/exec.go +++ b/daemon/exec.go @@ -12,9 +12,9 @@ import ( "github.com/docker/docker/daemon/execdriver/lxc" "github.com/docker/docker/engine" "github.com/docker/docker/pkg/broadcastwriter" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/promise" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/runconfig" ) @@ -141,7 +141,7 @@ func (d *Daemon) ContainerExecCreate(job *engine.Job) engine.Status { } execConfig := &execConfig{ - ID: common.GenerateRandomID(), + ID: stringid.GenerateRandomID(), OpenStdin: config.AttachStdin, OpenStdout: config.AttachStdout, OpenStderr: config.AttachStderr, diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go index 4d0c71c7ec4d0..bc4b5c0816435 100644 --- a/daemon/graphdriver/aufs/aufs.go +++ b/daemon/graphdriver/aufs/aufs.go @@ -34,9 +34,9 @@ import ( "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/chrootarchive" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/directory" mountpk "github.com/docker/docker/pkg/mount" + "github.com/docker/docker/pkg/stringid" "github.com/docker/libcontainer/label" ) @@ -405,7 +405,7 @@ func (a *Driver) Cleanup() error { for _, id := range ids { if err := a.unmount(id); err != nil { - log.Errorf("Unmounting %s: %s", common.TruncateID(id), err) + log.Errorf("Unmounting %s: %s", stringid.TruncateID(id), err) } } diff --git a/daemon/image_delete.go b/daemon/image_delete.go index 0c0a534cfdaf8..092c1082d0d9a 100644 --- a/daemon/image_delete.go +++ b/daemon/image_delete.go @@ -7,8 +7,8 @@ import ( "github.com/docker/docker/engine" "github.com/docker/docker/graph" "github.com/docker/docker/image" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/parsers" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/utils" ) @@ -148,11 +148,11 @@ func (daemon *Daemon) canDeleteImage(imgID string, force bool) error { if imgID == p.ID { if container.IsRunning() { if force { - return fmt.Errorf("Conflict, cannot force delete %s because the running container %s is using it, stop it and retry", common.TruncateID(imgID), common.TruncateID(container.ID)) + return fmt.Errorf("Conflict, cannot force delete %s because the running container %s is using it, stop it and retry", stringid.TruncateID(imgID), stringid.TruncateID(container.ID)) } - return fmt.Errorf("Conflict, cannot delete %s because the running container %s is using it, stop it and use -f to force", common.TruncateID(imgID), common.TruncateID(container.ID)) + return fmt.Errorf("Conflict, cannot delete %s because the running container %s is using it, stop it and use -f to force", stringid.TruncateID(imgID), stringid.TruncateID(container.ID)) } else if !force { - return fmt.Errorf("Conflict, cannot delete %s because the container %s is using it, use -f to force", common.TruncateID(imgID), common.TruncateID(container.ID)) + return fmt.Errorf("Conflict, cannot delete %s because the container %s is using it, use -f to force", stringid.TruncateID(imgID), stringid.TruncateID(container.ID)) } } return nil diff --git a/daemon/monitor.go b/daemon/monitor.go index 7c18b7a38c4f1..abe7dea2b22f0 100644 --- a/daemon/monitor.go +++ b/daemon/monitor.go @@ -8,7 +8,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/docker/docker/daemon/execdriver" - "github.com/docker/docker/pkg/common" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/runconfig" ) @@ -230,7 +230,7 @@ func (m *containerMonitor) shouldRestart(exitCode int) bool { // the default value of 0 for MaximumRetryCount means that we will not enforce a maximum count if max := m.restartPolicy.MaximumRetryCount; max != 0 && m.failureCount > max { log.Debugf("stopping restart of container %s because maximum failure could of %d has been reached", - common.TruncateID(m.container.ID), max) + stringid.TruncateID(m.container.ID), max) return false } diff --git a/engine/engine.go b/engine/engine.go index 60532349ab10f..5155e2774619a 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -10,8 +10,8 @@ import ( "sync" "time" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/ioutils" + "github.com/docker/docker/pkg/stringutils" ) // Installer is a standard interface for objects which can "install" themselves @@ -78,7 +78,7 @@ func (eng *Engine) RegisterCatchall(catchall Handler) { func New() *Engine { eng := &Engine{ handlers: make(map[string]Handler), - id: common.RandomString(), + id: stringutils.GenerateRandomString(), Stdout: os.Stdout, Stderr: os.Stderr, Stdin: os.Stdin, diff --git a/engine/env_test.go b/engine/env_test.go index 5182783bb32ba..11e930cad13e9 100644 --- a/engine/env_test.go +++ b/engine/env_test.go @@ -3,23 +3,11 @@ package engine import ( "bytes" "encoding/json" - "math/rand" "testing" "time" -) - -const chars = "abcdefghijklmnopqrstuvwxyz" + - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + - "~!@#$%^&*()-_+={}[]\\|<,>.?/\"';:` " -// RandomString returns random string of specified length -func RandomString(length int) string { - res := make([]byte, length) - for i := 0; i < length; i++ { - res[i] = chars[rand.Intn(len(chars))] - } - return string(res) -} + "github.com/docker/docker/pkg/stringutils" +) func TestEnvLenZero(t *testing.T) { env := &Env{} @@ -197,7 +185,7 @@ func TestMultiMap(t *testing.T) { func testMap(l int) [][2]string { res := make([][2]string, l) for i := 0; i < l; i++ { - t := [2]string{RandomString(5), RandomString(20)} + t := [2]string{stringutils.GenerateRandomAsciiString(5), stringutils.GenerateRandomAsciiString(20)} res[i] = t } return res diff --git a/graph/graph.go b/graph/graph.go index ecb52a0c5aa6a..0aaf8b3614647 100644 --- a/graph/graph.go +++ b/graph/graph.go @@ -17,8 +17,8 @@ import ( "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/image" "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/progressreader" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/truncindex" "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" @@ -118,7 +118,7 @@ func (graph *Graph) Get(name string) (*image.Image, error) { // Create creates a new image and registers it in the graph. func (graph *Graph) Create(layerData archive.ArchiveReader, containerID, containerImage, comment, author string, containerConfig, config *runconfig.Config) (*image.Image, error) { img := &image.Image{ - ID: common.GenerateRandomID(), + ID: stringid.GenerateRandomID(), Comment: comment, Created: time.Now().UTC(), DockerVersion: dockerversion.VERSION, @@ -217,7 +217,7 @@ func (graph *Graph) TempLayerArchive(id string, sf *utils.StreamFormatter, outpu Formatter: sf, Size: 0, NewLines: false, - ID: common.TruncateID(id), + ID: stringid.TruncateID(id), Action: "Buffering to disk", }) defer progressReader.Close() @@ -226,7 +226,7 @@ func (graph *Graph) TempLayerArchive(id string, sf *utils.StreamFormatter, outpu // Mktemp creates a temporary sub-directory inside the graph's filesystem. func (graph *Graph) Mktemp(id string) (string, error) { - dir := path.Join(graph.Root, "_tmp", common.GenerateRandomID()) + dir := path.Join(graph.Root, "_tmp", stringid.GenerateRandomID()) if err := os.MkdirAll(dir, 0700); err != nil { return "", err } diff --git a/graph/pull.go b/graph/pull.go index adad6f3239abf..8a0f0eba0b1a4 100644 --- a/graph/pull.go +++ b/graph/pull.go @@ -14,8 +14,8 @@ import ( "github.com/docker/distribution/digest" "github.com/docker/docker/engine" "github.com/docker/docker/image" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/progressreader" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/registry" "github.com/docker/docker/utils" ) @@ -172,9 +172,9 @@ func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, repoInfo * // ensure no two downloads of the same image happen at the same time if c, err := s.poolAdd("pull", "img:"+img.ID); err != nil { if c != nil { - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Layer already being pulled by another client. Waiting.", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Layer already being pulled by another client. Waiting.", nil)) <-c - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Download complete", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Download complete", nil)) } else { log.Debugf("Image (id: %s) pull is already running, skipping: %v", img.ID, err) } @@ -185,12 +185,12 @@ func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, repoInfo * } defer s.poolRemove("pull", "img:"+img.ID) - out.Write(sf.FormatProgress(common.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s", img.Tag, repoInfo.CanonicalName), nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s", img.Tag, repoInfo.CanonicalName), nil)) success := false var lastErr, err error var is_downloaded bool for _, ep := range repoInfo.Index.Mirrors { - out.Write(sf.FormatProgress(common.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, mirror: %s", img.Tag, repoInfo.CanonicalName, ep), nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, mirror: %s", img.Tag, repoInfo.CanonicalName, ep), nil)) if is_downloaded, err = s.pullImage(r, out, img.ID, ep, repoData.Tokens, sf); err != nil { // Don't report errors when pulling from mirrors. log.Debugf("Error pulling image (%s) from %s, mirror: %s, %s", img.Tag, repoInfo.CanonicalName, ep, err) @@ -202,12 +202,12 @@ func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, repoInfo * } if !success { for _, ep := range repoData.Endpoints { - out.Write(sf.FormatProgress(common.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, endpoint: %s", img.Tag, repoInfo.CanonicalName, ep), nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, endpoint: %s", img.Tag, repoInfo.CanonicalName, ep), nil)) if is_downloaded, err = s.pullImage(r, out, img.ID, ep, repoData.Tokens, sf); err != nil { // It's not ideal that only the last error is returned, it would be better to concatenate the errors. // As the error is also given to the output stream the user will see the error. lastErr = err - out.Write(sf.FormatProgress(common.TruncateID(img.ID), fmt.Sprintf("Error pulling image (%s) from %s, endpoint: %s, %s", img.Tag, repoInfo.CanonicalName, ep, err), nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), fmt.Sprintf("Error pulling image (%s) from %s, endpoint: %s, %s", img.Tag, repoInfo.CanonicalName, ep, err), nil)) continue } layers_downloaded = layers_downloaded || is_downloaded @@ -217,13 +217,13 @@ func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, repoInfo * } if !success { err := fmt.Errorf("Error pulling image (%s) from %s, %v", img.Tag, repoInfo.CanonicalName, lastErr) - out.Write(sf.FormatProgress(common.TruncateID(img.ID), err.Error(), nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), err.Error(), nil)) if parallel { errors <- err return } } - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Download complete", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Download complete", nil)) if parallel { errors <- nil @@ -270,7 +270,7 @@ func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint if err != nil { return false, err } - out.Write(sf.FormatProgress(common.TruncateID(imgID), "Pulling dependent layers", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(imgID), "Pulling dependent layers", nil)) // FIXME: Try to stream the images? // FIXME: Launch the getRemoteImage() in goroutines @@ -286,7 +286,7 @@ func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint defer s.poolRemove("pull", "layer:"+id) if !s.graph.Exists(id) { - out.Write(sf.FormatProgress(common.TruncateID(id), "Pulling metadata", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(id), "Pulling metadata", nil)) var ( imgJSON []byte imgSize int @@ -297,7 +297,7 @@ func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint for j := 1; j <= retries; j++ { imgJSON, imgSize, err = r.GetRemoteImageJSON(id, endpoint, token) if err != nil && j == retries { - out.Write(sf.FormatProgress(common.TruncateID(id), "Error pulling dependent layers", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(id), "Error pulling dependent layers", nil)) return layers_downloaded, err } else if err != nil { time.Sleep(time.Duration(j) * 500 * time.Millisecond) @@ -306,7 +306,7 @@ func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint img, err = image.NewImgJSON(imgJSON) layers_downloaded = true if err != nil && j == retries { - out.Write(sf.FormatProgress(common.TruncateID(id), "Error pulling dependent layers", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(id), "Error pulling dependent layers", nil)) return layers_downloaded, fmt.Errorf("Failed to parse json: %s", err) } else if err != nil { time.Sleep(time.Duration(j) * 500 * time.Millisecond) @@ -322,7 +322,7 @@ func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint if j > 1 { status = fmt.Sprintf("Pulling fs layer [retries: %d]", j) } - out.Write(sf.FormatProgress(common.TruncateID(id), status, nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(id), status, nil)) layer, err := r.GetRemoteImageLayer(img.ID, endpoint, token, int64(imgSize)) if uerr, ok := err.(*url.Error); ok { err = uerr.Err @@ -331,7 +331,7 @@ func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint time.Sleep(time.Duration(j) * 500 * time.Millisecond) continue } else if err != nil { - out.Write(sf.FormatProgress(common.TruncateID(id), "Error pulling dependent layers", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(id), "Error pulling dependent layers", nil)) return layers_downloaded, err } layers_downloaded = true @@ -344,21 +344,21 @@ func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint Formatter: sf, Size: imgSize, NewLines: false, - ID: common.TruncateID(id), + ID: stringid.TruncateID(id), Action: "Downloading", })) if terr, ok := err.(net.Error); ok && terr.Timeout() && j < retries { time.Sleep(time.Duration(j) * 500 * time.Millisecond) continue } else if err != nil { - out.Write(sf.FormatProgress(common.TruncateID(id), "Error downloading dependent layers", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(id), "Error downloading dependent layers", nil)) return layers_downloaded, err } else { break } } } - out.Write(sf.FormatProgress(common.TruncateID(id), "Download complete", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(id), "Download complete", nil)) } return layers_downloaded, nil } @@ -478,16 +478,16 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri } downloads[i].digest = dgst - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Pulling fs layer", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Pulling fs layer", nil)) downloadFunc := func(di *downloadInfo) error { log.Debugf("pulling blob %q to V1 img %s", sumStr, img.ID) if c, err := s.poolAdd("pull", "img:"+img.ID); err != nil { if c != nil { - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Layer already being pulled by another client. Waiting.", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Layer already being pulled by another client. Waiting.", nil)) <-c - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Download complete", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Download complete", nil)) } else { log.Debugf("Image (id: %s) pull is already running, skipping: %v", img.ID, err) } @@ -515,20 +515,20 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri Formatter: sf, Size: int(l), NewLines: false, - ID: common.TruncateID(img.ID), + ID: stringid.TruncateID(img.ID), Action: "Downloading", })); err != nil { return fmt.Errorf("unable to copy v2 image blob data: %s", err) } - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Verifying Checksum", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Verifying Checksum", nil)) if !verifier.Verified() { log.Infof("Image verification failed: checksum mismatch for %q", di.digest.String()) verified = false } - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Download complete", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Download complete", nil)) log.Debugf("Downloaded %s to tempfile %s", img.ID, tmpFile.Name()) di.tmpFile = tmpFile @@ -574,7 +574,7 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri Out: out, Formatter: sf, Size: int(d.length), - ID: common.TruncateID(d.img.ID), + ID: stringid.TruncateID(d.img.ID), Action: "Extracting", })) if err != nil { @@ -583,10 +583,10 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri // FIXME: Pool release here for parallel tag pull (ensures any downloads block until fully extracted) } - out.Write(sf.FormatProgress(common.TruncateID(d.img.ID), "Pull complete", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(d.img.ID), "Pull complete", nil)) tagUpdated = true } else { - out.Write(sf.FormatProgress(common.TruncateID(d.img.ID), "Already exists", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(d.img.ID), "Already exists", nil)) } } diff --git a/graph/push.go b/graph/push.go index f86df6d0b3c8c..6085113f86686 100644 --- a/graph/push.go +++ b/graph/push.go @@ -16,8 +16,8 @@ import ( "github.com/docker/distribution/digest" "github.com/docker/docker/engine" "github.com/docker/docker/image" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/progressreader" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/registry" "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" @@ -139,7 +139,7 @@ func lookupImageOnEndpoint(wg *sync.WaitGroup, r *registry.Session, out io.Write imagesToPush <- image.id continue } - out.Write(sf.FormatStatus("", "Image %s already pushed, skipping", common.TruncateID(image.id))) + out.Write(sf.FormatStatus("", "Image %s already pushed, skipping", stringid.TruncateID(image.id))) } } @@ -191,7 +191,7 @@ func (s *TagStore) pushImageToEndpoint(endpoint string, out io.Writer, remoteNam } } for _, tag := range tags[id] { - out.Write(sf.FormatStatus("", "Pushing tag for rev [%s] on {%s}", common.TruncateID(id), endpoint+"repositories/"+remoteName+"/tags/"+tag)) + out.Write(sf.FormatStatus("", "Pushing tag for rev [%s] on {%s}", stringid.TruncateID(id), endpoint+"repositories/"+remoteName+"/tags/"+tag)) if err := r.PushRegistryTag(remoteName, id, tag, endpoint, repo.Tokens); err != nil { return err } @@ -244,7 +244,7 @@ func (s *TagStore) pushImage(r *registry.Session, out io.Writer, imgID, ep strin if err != nil { return "", fmt.Errorf("Cannot retrieve the path for {%s}: %s", imgID, err) } - out.Write(sf.FormatProgress(common.TruncateID(imgID), "Pushing", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(imgID), "Pushing", nil)) imgData := ®istry.ImgData{ ID: imgID, @@ -253,7 +253,7 @@ func (s *TagStore) pushImage(r *registry.Session, out io.Writer, imgID, ep strin // Send the json if err := r.PushImageJSONRegistry(imgData, jsonRaw, ep, token); err != nil { if err == registry.ErrAlreadyExists { - out.Write(sf.FormatProgress(common.TruncateID(imgData.ID), "Image already pushed, skipping", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(imgData.ID), "Image already pushed, skipping", nil)) return "", nil } return "", err @@ -275,7 +275,7 @@ func (s *TagStore) pushImage(r *registry.Session, out io.Writer, imgID, ep strin Formatter: sf, Size: int(layerData.Size), NewLines: false, - ID: common.TruncateID(imgData.ID), + ID: stringid.TruncateID(imgData.ID), Action: "Pushing", }), ep, token, jsonRaw) if err != nil { @@ -288,7 +288,7 @@ func (s *TagStore) pushImage(r *registry.Session, out io.Writer, imgID, ep strin return "", err } - out.Write(sf.FormatProgress(common.TruncateID(imgData.ID), "Image successfully pushed", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(imgData.ID), "Image successfully pushed", nil)) return imgData.Checksum, nil } @@ -385,7 +385,7 @@ func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, o // Call mount blob exists, err = r.HeadV2ImageBlob(endpoint, repoInfo.RemoteName, sumParts[0], sumParts[1], auth) if err != nil { - out.Write(sf.FormatProgress(common.TruncateID(layer.ID), "Image push failed", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(layer.ID), "Image push failed", nil)) return err } } @@ -400,7 +400,7 @@ func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, o checksum = cs } } else { - out.Write(sf.FormatProgress(common.TruncateID(layer.ID), "Image already exists", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(layer.ID), "Image already exists", nil)) } m.FSLayers[i] = ®istry.FSLayer{BlobSum: checksum} m.History[i] = ®istry.ManifestHistory{V1Compatibility: string(jsonData)} @@ -443,7 +443,7 @@ func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, o // PushV2Image pushes the image content to the v2 registry, first buffering the contents to disk func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint *registry.Endpoint, imageName string, sf *utils.StreamFormatter, out io.Writer, auth *registry.RequestAuthorization) (string, error) { - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Buffering to Disk", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Buffering to Disk", nil)) image, err := s.graph.Get(img.ID) if err != nil { @@ -481,13 +481,13 @@ func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint * Formatter: sf, Size: int(size), NewLines: false, - ID: common.TruncateID(img.ID), + ID: stringid.TruncateID(img.ID), Action: "Pushing", }), auth); err != nil { - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Image push failed", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Image push failed", nil)) return "", err } - out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Image successfully pushed", nil)) + out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Image successfully pushed", nil)) return dgst.String(), nil } diff --git a/graph/tags.go b/graph/tags.go index 5d26b8cfba36e..87c045b8262e1 100644 --- a/graph/tags.go +++ b/graph/tags.go @@ -13,8 +13,8 @@ import ( "sync" "github.com/docker/docker/image" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/parsers" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/registry" "github.com/docker/docker/utils" "github.com/docker/libtrust" @@ -163,7 +163,7 @@ func (store *TagStore) ImageName(id string) string { if names, exists := store.ByID()[id]; exists && len(names) > 0 { return names[0] } - return common.TruncateID(id) + return stringid.TruncateID(id) } func (store *TagStore) DeleteAll(id string) error { @@ -331,7 +331,7 @@ func (store *TagStore) GetRepoRefs() map[string][]string { for name, repository := range store.Repositories { for tag, id := range repository { - shortID := common.TruncateID(id) + shortID := stringid.TruncateID(id) reporefs[shortID] = append(reporefs[shortID], utils.ImageReference(name, tag)) } } diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 9a8ee69e54903..954c0e5d9b46f 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -22,6 +22,7 @@ import ( "github.com/docker/docker/builder/command" "github.com/docker/docker/pkg/archive" + "github.com/docker/docker/pkg/stringutils" ) func TestBuildJSONEmptyRun(t *testing.T) { @@ -4420,7 +4421,7 @@ func TestBuildOnBuildOutput(t *testing.T) { } func TestBuildInvalidTag(t *testing.T) { - name := "abcd:" + makeRandomString(200) + name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200) defer deleteImages(name) _, out, err := buildImageWithOut(name, "FROM scratch\nMAINTAINER quux\n", true) // if the error doesnt check for illegal tag name, or the image is built diff --git a/integration-cli/docker_cli_images_test.go b/integration-cli/docker_cli_images_test.go index 694971191efc4..28b091efdf82c 100644 --- a/integration-cli/docker_cli_images_test.go +++ b/integration-cli/docker_cli_images_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/docker/docker/pkg/common" + "github.com/docker/docker/pkg/stringid" ) func TestImagesEnsureImageIsListed(t *testing.T) { @@ -196,7 +196,7 @@ func TestImagesEnsureDanglingImageOnlyListedOnce(t *testing.T) { if err != nil { t.Fatalf("error tagging foobox: %s", err) } - imageId := common.TruncateID(strings.TrimSpace(out)) + imageId := stringid.TruncateID(strings.TrimSpace(out)) defer deleteImages(imageId) // overwrite the tag, making the previous image dangling diff --git a/integration-cli/docker_cli_tag_test.go b/integration-cli/docker_cli_tag_test.go index 081e239c35758..b181e21771338 100644 --- a/integration-cli/docker_cli_tag_test.go +++ b/integration-cli/docker_cli_tag_test.go @@ -5,6 +5,8 @@ import ( "os/exec" "strings" "testing" + + "github.com/docker/docker/pkg/stringutils" ) // tagging a named image in a new unprefixed repo should work @@ -59,7 +61,7 @@ func TestTagInvalidUnprefixedRepo(t *testing.T) { // ensure we don't allow the use of invalid tags; these tag operations should fail func TestTagInvalidPrefixedRepo(t *testing.T) { - long_tag := makeRandomString(121) + long_tag := stringutils.GenerateRandomAlphaOnlyString(121) invalidTags := []string{"repo:fo$z$", "repo:Foo@3cc", "repo:Foo$3", "repo:Foo*3", "repo:Fo^3", "repo:Foo!3", "repo:%goodbye", "repo:#hashtagit", "repo:F)xcz(", "repo:-foo", "repo:..", long_tag} diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index e0b9bacc4a0c8..7abdc54dced0c 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -22,6 +22,7 @@ import ( "time" "github.com/docker/docker/api" + "github.com/docker/docker/pkg/stringutils" ) // Daemon represents a Docker daemon for the testing framework. @@ -695,8 +696,8 @@ func (f *remoteFileServer) Close() error { func newRemoteFileServer(ctx *FakeContext) (*remoteFileServer, error) { var ( - image = fmt.Sprintf("fileserver-img-%s", strings.ToLower(makeRandomString(10))) - container = fmt.Sprintf("fileserver-cnt-%s", strings.ToLower(makeRandomString(10))) + image = fmt.Sprintf("fileserver-img-%s", strings.ToLower(stringutils.GenerateRandomAlphaOnlyString(10))) + container = fmt.Sprintf("fileserver-cnt-%s", strings.ToLower(stringutils.GenerateRandomAlphaOnlyString(10))) ) // Build the image diff --git a/integration-cli/utils.go b/integration-cli/utils.go index 85e6f1ccd3166..d6b65acc063bf 100644 --- a/integration-cli/utils.go +++ b/integration-cli/utils.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "math/rand" "net/http" "net/http/httptest" "os" @@ -17,6 +16,7 @@ import ( "syscall" "time" + "github.com/docker/docker/pkg/stringutils" "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" ) @@ -301,21 +301,10 @@ func copyWithCP(source, target string) error { return nil } -func makeRandomString(n int) string { - // make a really long string - letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - b := make([]byte, n) - r := rand.New(rand.NewSource(time.Now().UTC().UnixNano())) - for i := range b { - b[i] = letters[r.Intn(len(letters))] - } - return string(b) -} - // randomUnixTmpDirPath provides a temporary unix path with rand string appended. // does not create or checks if it exists. func randomUnixTmpDirPath(s string) string { - return path.Join("/tmp", fmt.Sprintf("%s.%s", s, makeRandomString(10))) + return path.Join("/tmp", fmt.Sprintf("%s.%s", s, stringutils.GenerateRandomAlphaOnlyString(10))) } // Reads chunkSize bytes from reader after every interval. diff --git a/integration/commands_test.go b/integration/commands_test.go index 6c6ad0e71b37d..f748efd6d629b 100644 --- a/integration/commands_test.go +++ b/integration/commands_test.go @@ -12,7 +12,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/docker/docker/api/client" "github.com/docker/docker/daemon" - "github.com/docker/docker/pkg/common" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/term" "github.com/kr/pty" ) @@ -286,7 +286,7 @@ func TestAttachDetachTruncatedID(t *testing.T) { ch := make(chan struct{}) go func() { defer close(ch) - if err := cli.CmdAttach(common.TruncateID(container.ID)); err != nil { + if err := cli.CmdAttach(stringid.TruncateID(container.ID)); err != nil { if err != io.ErrClosedPipe { t.Fatal(err) } diff --git a/integration/graph_test.go b/integration/graph_test.go index 8518fae8ee62f..a481154551f19 100644 --- a/integration/graph_test.go +++ b/integration/graph_test.go @@ -2,19 +2,20 @@ package docker import ( "errors" - "github.com/docker/docker/autogen/dockerversion" - "github.com/docker/docker/daemon/graphdriver" - "github.com/docker/docker/graph" - "github.com/docker/docker/image" - "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/common" - "github.com/docker/docker/utils" "io" "io/ioutil" "os" "path" "testing" "time" + + "github.com/docker/docker/autogen/dockerversion" + "github.com/docker/docker/daemon/graphdriver" + "github.com/docker/docker/graph" + "github.com/docker/docker/image" + "github.com/docker/docker/pkg/archive" + "github.com/docker/docker/pkg/stringid" + "github.com/docker/docker/utils" ) func TestMount(t *testing.T) { @@ -70,7 +71,7 @@ func TestInterruptedRegister(t *testing.T) { defer nukeGraph(graph) badArchive, w := io.Pipe() // Use a pipe reader as a fake archive which never yields data image := &image.Image{ - ID: common.GenerateRandomID(), + ID: stringid.GenerateRandomID(), Comment: "testing", Created: time.Now(), } @@ -130,7 +131,7 @@ func TestRegister(t *testing.T) { t.Fatal(err) } image := &image.Image{ - ID: common.GenerateRandomID(), + ID: stringid.GenerateRandomID(), Comment: "testing", Created: time.Now(), } @@ -160,7 +161,7 @@ func TestDeletePrefix(t *testing.T) { graph, _ := tempGraph(t) defer nukeGraph(graph) img := createTestImage(graph, t) - if err := graph.Delete(common.TruncateID(img.ID)); err != nil { + if err := graph.Delete(stringid.TruncateID(img.ID)); err != nil { t.Fatal(err) } assertNImages(graph, t, 0) @@ -246,19 +247,19 @@ func TestByParent(t *testing.T) { graph, _ := tempGraph(t) defer nukeGraph(graph) parentImage := &image.Image{ - ID: common.GenerateRandomID(), + ID: stringid.GenerateRandomID(), Comment: "parent", Created: time.Now(), Parent: "", } childImage1 := &image.Image{ - ID: common.GenerateRandomID(), + ID: stringid.GenerateRandomID(), Comment: "child1", Created: time.Now(), Parent: parentImage.ID, } childImage2 := &image.Image{ - ID: common.GenerateRandomID(), + ID: stringid.GenerateRandomID(), Comment: "child2", Created: time.Now(), Parent: parentImage.ID, diff --git a/integration/runtime_test.go b/integration/runtime_test.go index 153c385627625..4c16327714c38 100644 --- a/integration/runtime_test.go +++ b/integration/runtime_test.go @@ -22,9 +22,9 @@ import ( "github.com/docker/docker/engine" "github.com/docker/docker/image" "github.com/docker/docker/nat" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/reexec" + "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" ) @@ -306,7 +306,7 @@ func TestDaemonCreate(t *testing.T) { &runconfig.HostConfig{}, "conflictname", ) - if _, _, err := daemon.Create(&runconfig.Config{Image: GetTestImage(daemon).ID, Cmd: []string{"ls", "-al"}}, &runconfig.HostConfig{}, testContainer.Name); err == nil || !strings.Contains(err.Error(), common.TruncateID(testContainer.ID)) { + if _, _, err := daemon.Create(&runconfig.Config{Image: GetTestImage(daemon).ID, Cmd: []string{"ls", "-al"}}, &runconfig.HostConfig{}, testContainer.Name); err == nil || !strings.Contains(err.Error(), stringid.TruncateID(testContainer.ID)) { t.Fatalf("Name conflict error doesn't include the correct short id. Message was: %v", err) } diff --git a/pkg/stringid/README.md b/pkg/stringid/README.md new file mode 100644 index 0000000000000..37a5098fd988e --- /dev/null +++ b/pkg/stringid/README.md @@ -0,0 +1 @@ +This package provides helper functions for dealing with string identifiers diff --git a/pkg/common/randomid.go b/pkg/stringid/stringid.go similarity index 83% rename from pkg/common/randomid.go rename to pkg/stringid/stringid.go index 5c6d5920e8205..bf39df9b731dd 100644 --- a/pkg/common/randomid.go +++ b/pkg/stringid/stringid.go @@ -1,4 +1,4 @@ -package common +package stringid import ( "crypto/rand" @@ -36,12 +36,3 @@ func GenerateRandomID() string { return value } } - -func RandomString() string { - id := make([]byte, 32) - - if _, err := io.ReadFull(rand.Reader, id); err != nil { - panic(err) // This shouldn't happen - } - return hex.EncodeToString(id) -} diff --git a/pkg/common/randomid_test.go b/pkg/stringid/stringid_test.go similarity index 58% rename from pkg/common/randomid_test.go rename to pkg/stringid/stringid_test.go index 1dba41254b566..21f8f8a2fbd8c 100644 --- a/pkg/common/randomid_test.go +++ b/pkg/stringid/stringid_test.go @@ -1,8 +1,14 @@ -package common +package stringid -import ( - "testing" -) +import "testing" + +func TestGenerateRandomID(t *testing.T) { + id := GenerateRandomID() + + if len(id) != 64 { + t.Fatalf("Id returned is incorrect: %s", id) + } +} func TestShortenId(t *testing.T) { id := GenerateRandomID() @@ -27,33 +33,3 @@ func TestShortenIdInvalid(t *testing.T) { t.Fatalf("Id returned is incorrect: truncate on %s returned %s", id, truncID) } } - -func TestGenerateRandomID(t *testing.T) { - id := GenerateRandomID() - - if len(id) != 64 { - t.Fatalf("Id returned is incorrect: %s", id) - } -} - -func TestRandomString(t *testing.T) { - id := RandomString() - if len(id) != 64 { - t.Fatalf("Id returned is incorrect: %s", id) - } -} - -func TestRandomStringUniqueness(t *testing.T) { - repeats := 25 - set := make(map[string]struct{}, repeats) - for i := 0; i < repeats; i = i + 1 { - id := RandomString() - if len(id) != 64 { - t.Fatalf("Id returned is incorrect: %s", id) - } - if _, ok := set[id]; ok { - t.Fatalf("Random number is repeated") - } - set[id] = struct{}{} - } -} diff --git a/pkg/stringutils/README.md b/pkg/stringutils/README.md new file mode 100644 index 0000000000000..b3e454573c329 --- /dev/null +++ b/pkg/stringutils/README.md @@ -0,0 +1 @@ +This package provides helper functions for dealing with strings diff --git a/pkg/stringutils/stringutils.go b/pkg/stringutils/stringutils.go new file mode 100644 index 0000000000000..bcb0ece57cd2c --- /dev/null +++ b/pkg/stringutils/stringutils.go @@ -0,0 +1,43 @@ +package stringutils + +import ( + "crypto/rand" + "encoding/hex" + "io" + mathrand "math/rand" + "time" +) + +// Generate 32 chars random string +func GenerateRandomString() string { + id := make([]byte, 32) + + if _, err := io.ReadFull(rand.Reader, id); err != nil { + panic(err) // This shouldn't happen + } + return hex.EncodeToString(id) +} + +// Generate alpha only random stirng with length n +func GenerateRandomAlphaOnlyString(n int) string { + // make a really long string + letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + b := make([]byte, n) + r := mathrand.New(mathrand.NewSource(time.Now().UTC().UnixNano())) + for i := range b { + b[i] = letters[r.Intn(len(letters))] + } + return string(b) +} + +// Generate Ascii random stirng with length n +func GenerateRandomAsciiString(n int) string { + chars := "abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "~!@#$%^&*()-_+={}[]\\|<,>.?/\"';:` " + res := make([]byte, n) + for i := 0; i < n; i++ { + res[i] = chars[mathrand.Intn(len(chars))] + } + return string(res) +} diff --git a/pkg/stringutils/stringutils_test.go b/pkg/stringutils/stringutils_test.go new file mode 100644 index 0000000000000..60b848ff5a09f --- /dev/null +++ b/pkg/stringutils/stringutils_test.go @@ -0,0 +1,25 @@ +package stringutils + +import "testing" + +func TestRandomString(t *testing.T) { + str := GenerateRandomString() + if len(str) != 64 { + t.Fatalf("Id returned is incorrect: %s", str) + } +} + +func TestRandomStringUniqueness(t *testing.T) { + repeats := 25 + set := make(map[string]struct{}, repeats) + for i := 0; i < repeats; i = i + 1 { + str := GenerateRandomString() + if len(str) != 64 { + t.Fatalf("Id returned is incorrect: %s", str) + } + if _, ok := set[str]; ok { + t.Fatalf("Random number is repeated") + } + set[str] = struct{}{} + } +} diff --git a/pkg/truncindex/truncindex_test.go b/pkg/truncindex/truncindex_test.go index 928653428091f..f46a662d7e21a 100644 --- a/pkg/truncindex/truncindex_test.go +++ b/pkg/truncindex/truncindex_test.go @@ -4,7 +4,7 @@ import ( "math/rand" "testing" - "github.com/docker/docker/pkg/common" + "github.com/docker/docker/pkg/stringid" ) // Test the behavior of TruncIndex, an index for querying IDs from a non-conflicting prefix. @@ -111,7 +111,7 @@ func assertIndexGet(t *testing.T, index *TruncIndex, input, expectedResult strin func BenchmarkTruncIndexAdd100(b *testing.B) { var testSet []string for i := 0; i < 100; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -127,7 +127,7 @@ func BenchmarkTruncIndexAdd100(b *testing.B) { func BenchmarkTruncIndexAdd250(b *testing.B) { var testSet []string for i := 0; i < 250; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -143,7 +143,7 @@ func BenchmarkTruncIndexAdd250(b *testing.B) { func BenchmarkTruncIndexAdd500(b *testing.B) { var testSet []string for i := 0; i < 500; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -160,7 +160,7 @@ func BenchmarkTruncIndexGet100(b *testing.B) { var testSet []string var testKeys []string for i := 0; i < 100; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } index := NewTruncIndex([]string{}) for _, id := range testSet { @@ -184,7 +184,7 @@ func BenchmarkTruncIndexGet250(b *testing.B) { var testSet []string var testKeys []string for i := 0; i < 250; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } index := NewTruncIndex([]string{}) for _, id := range testSet { @@ -208,7 +208,7 @@ func BenchmarkTruncIndexGet500(b *testing.B) { var testSet []string var testKeys []string for i := 0; i < 500; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } index := NewTruncIndex([]string{}) for _, id := range testSet { @@ -231,7 +231,7 @@ func BenchmarkTruncIndexGet500(b *testing.B) { func BenchmarkTruncIndexDelete100(b *testing.B) { var testSet []string for i := 0; i < 100; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -254,7 +254,7 @@ func BenchmarkTruncIndexDelete100(b *testing.B) { func BenchmarkTruncIndexDelete250(b *testing.B) { var testSet []string for i := 0; i < 250; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -277,7 +277,7 @@ func BenchmarkTruncIndexDelete250(b *testing.B) { func BenchmarkTruncIndexDelete500(b *testing.B) { var testSet []string for i := 0; i < 500; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -300,7 +300,7 @@ func BenchmarkTruncIndexDelete500(b *testing.B) { func BenchmarkTruncIndexNew100(b *testing.B) { var testSet []string for i := 0; i < 100; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -311,7 +311,7 @@ func BenchmarkTruncIndexNew100(b *testing.B) { func BenchmarkTruncIndexNew250(b *testing.B) { var testSet []string for i := 0; i < 250; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -322,7 +322,7 @@ func BenchmarkTruncIndexNew250(b *testing.B) { func BenchmarkTruncIndexNew500(b *testing.B) { var testSet []string for i := 0; i < 500; i++ { - testSet = append(testSet, common.GenerateRandomID()) + testSet = append(testSet, stringid.GenerateRandomID()) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -334,7 +334,7 @@ func BenchmarkTruncIndexAddGet100(b *testing.B) { var testSet []string var testKeys []string for i := 0; i < 500; i++ { - id := common.GenerateRandomID() + id := stringid.GenerateRandomID() testSet = append(testSet, id) l := rand.Intn(12) + 12 testKeys = append(testKeys, id[:l]) @@ -359,7 +359,7 @@ func BenchmarkTruncIndexAddGet250(b *testing.B) { var testSet []string var testKeys []string for i := 0; i < 500; i++ { - id := common.GenerateRandomID() + id := stringid.GenerateRandomID() testSet = append(testSet, id) l := rand.Intn(12) + 12 testKeys = append(testKeys, id[:l]) @@ -384,7 +384,7 @@ func BenchmarkTruncIndexAddGet500(b *testing.B) { var testSet []string var testKeys []string for i := 0; i < 500; i++ { - id := common.GenerateRandomID() + id := stringid.GenerateRandomID() testSet = append(testSet, id) l := rand.Intn(12) + 12 testKeys = append(testKeys, id[:l]) diff --git a/utils/utils.go b/utils/utils.go index 540ae6f57275b..d5ebb68c99bf2 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -21,9 +21,9 @@ import ( log "github.com/Sirupsen/logrus" "github.com/docker/docker/autogen/dockerversion" "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/common" "github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/ioutils" + "github.com/docker/docker/pkg/stringutils" ) type KeyValuePair struct { @@ -312,7 +312,7 @@ var globalTestID string // new directory. func TestDirectory(templateDir string) (dir string, err error) { if globalTestID == "" { - globalTestID = common.RandomString()[:4] + globalTestID = stringutils.GenerateRandomString()[:4] } prefix := fmt.Sprintf("docker-test%s-%s-", globalTestID, GetCallerName(2)) if prefix == "" { diff --git a/volumes/repository.go b/volumes/repository.go index dbd7a5f555065..ee555e4013451 100644 --- a/volumes/repository.go +++ b/volumes/repository.go @@ -9,7 +9,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/docker/docker/daemon/graphdriver" - "github.com/docker/docker/pkg/common" + "github.com/docker/docker/pkg/stringid" ) type Repository struct { @@ -43,7 +43,7 @@ func (r *Repository) newVolume(path string, writable bool) (*Volume, error) { var ( isBindMount bool err error - id = common.GenerateRandomID() + id = stringid.GenerateRandomID() ) if path != "" { isBindMount = true