names.go 2.7 KB

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