github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/daemon/names.go (about) 1 package daemon 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/docker/docker/container" 8 "github.com/docker/docker/daemon/names" 9 "github.com/docker/docker/pkg/namesgenerator" 10 "github.com/docker/docker/pkg/stringid" 11 "github.com/pkg/errors" 12 "github.com/sirupsen/logrus" 13 ) 14 15 var ( 16 validContainerNameChars = names.RestrictedNameChars 17 validContainerNamePattern = names.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 return daemon.containersReplica.ReserveName(container.Name, container.ID) 35 } 36 37 func (daemon *Daemon) generateIDAndName(name string) (string, string, error) { 38 var ( 39 err error 40 id = stringid.GenerateNonCryptoID() 41 ) 42 43 if name == "" { 44 if name, err = daemon.generateNewName(id); err != nil { 45 return "", "", err 46 } 47 return id, name, nil 48 } 49 50 if name, err = daemon.reserveName(id, name); err != nil { 51 return "", "", err 52 } 53 54 return id, name, nil 55 } 56 57 func (daemon *Daemon) reserveName(id, name string) (string, error) { 58 if !validContainerNamePattern.MatchString(strings.TrimPrefix(name, "/")) { 59 return "", validationError{errors.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)} 60 } 61 if name[0] != '/' { 62 name = "/" + name 63 } 64 65 if err := daemon.containersReplica.ReserveName(name, id); err != nil { 66 if err == container.ErrNameReserved { 67 id, err := daemon.containersReplica.Snapshot().GetID(name) 68 if err != nil { 69 logrus.Errorf("got unexpected error while looking up reserved name: %v", err) 70 return "", err 71 } 72 return "", nameConflictError{id: id, name: name} 73 } 74 return "", errors.Wrapf(err, "error reserving name: %q", name) 75 } 76 return name, nil 77 } 78 79 func (daemon *Daemon) releaseName(name string) { 80 daemon.containersReplica.ReleaseName(name) 81 } 82 83 func (daemon *Daemon) generateNewName(id string) (string, error) { 84 var name string 85 for i := 0; i < 6; i++ { 86 name = namesgenerator.GetRandomName(i) 87 if name[0] != '/' { 88 name = "/" + name 89 } 90 91 if err := daemon.containersReplica.ReserveName(name, id); err != nil { 92 if err == container.ErrNameReserved { 93 continue 94 } 95 return "", err 96 } 97 return name, nil 98 } 99 100 name = "/" + stringid.TruncateID(id) 101 if err := daemon.containersReplica.ReserveName(name, id); err != nil { 102 return "", err 103 } 104 return name, nil 105 } 106 107 func validateID(id string) error { 108 if id == "" { 109 return fmt.Errorf("Invalid empty id") 110 } 111 return nil 112 }