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