github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/daemon/names.go (about) 1 package daemon 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/Sirupsen/logrus" 8 "github.com/docker/docker/api" 9 "github.com/docker/docker/container" 10 "github.com/docker/docker/pkg/namesgenerator" 11 "github.com/docker/docker/pkg/registrar" 12 "github.com/docker/docker/pkg/stringid" 13 ) 14 15 var ( 16 validContainerNameChars = api.RestrictedNameChars 17 validContainerNamePattern = api.RestrictedNamePattern 18 ) 19 20 func (daemon *Daemon) registerName(container *container.Container) error { 21 if daemon.Exists(container.ID) { 22 return fmt.Errorf("Container is already loaded") 23 } 24 if err := validateID(container.ID); err != nil { 25 return err 26 } 27 if container.Name == "" { 28 name, err := daemon.generateNewName(container.ID) 29 if err != nil { 30 return err 31 } 32 container.Name = name 33 34 if err := container.ToDiskLocking(); err != nil { 35 logrus.Errorf("Error saving container name to disk: %v", err) 36 } 37 } 38 return daemon.nameIndex.Reserve(container.Name, container.ID) 39 } 40 41 func (daemon *Daemon) generateIDAndName(name string) (string, string, error) { 42 var ( 43 err error 44 id = stringid.GenerateNonCryptoID() 45 ) 46 47 if name == "" { 48 if name, err = daemon.generateNewName(id); err != nil { 49 return "", "", err 50 } 51 return id, name, nil 52 } 53 54 if name, err = daemon.reserveName(id, name); err != nil { 55 return "", "", err 56 } 57 58 return id, name, nil 59 } 60 61 func (daemon *Daemon) reserveName(id, name string) (string, error) { 62 if !validContainerNamePattern.MatchString(strings.TrimPrefix(name, "/")) { 63 return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars) 64 } 65 if name[0] != '/' { 66 name = "/" + name 67 } 68 69 if err := daemon.nameIndex.Reserve(name, id); err != nil { 70 if err == registrar.ErrNameReserved { 71 id, err := daemon.nameIndex.Get(name) 72 if err != nil { 73 logrus.Errorf("got unexpected error while looking up reserved name: %v", err) 74 return "", err 75 } 76 return "", fmt.Errorf("Conflict. The container name %q is already in use by container %s. You have to remove (or rename) that container to be able to reuse that name.", name, id) 77 } 78 return "", fmt.Errorf("error reserving name: %s, error: %v", name, err) 79 } 80 return name, nil 81 } 82 83 func (daemon *Daemon) releaseName(name string) { 84 daemon.nameIndex.Release(name) 85 } 86 87 func (daemon *Daemon) generateNewName(id string) (string, error) { 88 var name string 89 for i := 0; i < 6; i++ { 90 name = namesgenerator.GetRandomName(i) 91 if name[0] != '/' { 92 name = "/" + name 93 } 94 95 if err := daemon.nameIndex.Reserve(name, id); err != nil { 96 if err == registrar.ErrNameReserved { 97 continue 98 } 99 return "", err 100 } 101 return name, nil 102 } 103 104 name = "/" + stringid.TruncateID(id) 105 if err := daemon.nameIndex.Reserve(name, id); err != nil { 106 return "", err 107 } 108 return name, nil 109 } 110 111 func validateID(id string) error { 112 if id == "" { 113 return fmt.Errorf("Invalid empty id") 114 } 115 return nil 116 }