rename.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package daemon // import "github.com/docker/docker/daemon"
  2. import (
  3. "context"
  4. "strings"
  5. "github.com/containerd/log"
  6. "github.com/docker/docker/api/types/events"
  7. dockercontainer "github.com/docker/docker/container"
  8. "github.com/docker/docker/errdefs"
  9. "github.com/docker/docker/libnetwork"
  10. "github.com/pkg/errors"
  11. )
  12. // ContainerRename changes the name of a container, using the oldName
  13. // to find the container. An error is returned if newName is already
  14. // reserved.
  15. func (daemon *Daemon) ContainerRename(oldName, newName string) (retErr error) {
  16. var (
  17. sid string
  18. sb *libnetwork.Sandbox
  19. )
  20. if oldName == "" || newName == "" {
  21. return errdefs.InvalidParameter(errors.New("Neither old nor new names may be empty"))
  22. }
  23. if newName[0] != '/' {
  24. newName = "/" + newName
  25. }
  26. container, err := daemon.GetContainer(oldName)
  27. if err != nil {
  28. return err
  29. }
  30. container.Lock()
  31. defer container.Unlock()
  32. oldName = container.Name
  33. oldIsAnonymousEndpoint := container.NetworkSettings.IsAnonymousEndpoint
  34. if oldName == newName {
  35. return errdefs.InvalidParameter(errors.New("Renaming a container with the same name as its current name"))
  36. }
  37. links := map[string]*dockercontainer.Container{}
  38. for k, v := range daemon.linkIndex.children(container) {
  39. if !strings.HasPrefix(k, oldName) {
  40. return errdefs.InvalidParameter(errors.Errorf("Linked container %s does not match parent %s", k, oldName))
  41. }
  42. links[strings.TrimPrefix(k, oldName)] = v
  43. }
  44. if newName, err = daemon.reserveName(container.ID, newName); err != nil {
  45. return errors.Wrap(err, "Error when allocating new name")
  46. }
  47. for k, v := range links {
  48. daemon.containersReplica.ReserveName(newName+k, v.ID)
  49. daemon.linkIndex.link(container, v, newName+k)
  50. }
  51. container.Name = newName
  52. container.NetworkSettings.IsAnonymousEndpoint = false
  53. defer func() {
  54. if retErr != nil {
  55. container.Name = oldName
  56. container.NetworkSettings.IsAnonymousEndpoint = oldIsAnonymousEndpoint
  57. daemon.reserveName(container.ID, oldName)
  58. for k, v := range links {
  59. daemon.containersReplica.ReserveName(oldName+k, v.ID)
  60. daemon.linkIndex.link(container, v, oldName+k)
  61. daemon.linkIndex.unlink(newName+k, v, container)
  62. daemon.containersReplica.ReleaseName(newName + k)
  63. }
  64. daemon.releaseName(newName)
  65. } else {
  66. daemon.releaseName(oldName)
  67. }
  68. }()
  69. for k, v := range links {
  70. daemon.linkIndex.unlink(oldName+k, v, container)
  71. daemon.containersReplica.ReleaseName(oldName + k)
  72. }
  73. if err = container.CheckpointTo(daemon.containersReplica); err != nil {
  74. return err
  75. }
  76. attributes := map[string]string{
  77. "oldName": oldName,
  78. }
  79. if !container.Running {
  80. daemon.LogContainerEventWithAttributes(container, events.ActionRename, attributes)
  81. return nil
  82. }
  83. defer func() {
  84. if retErr != nil {
  85. container.Name = oldName
  86. container.NetworkSettings.IsAnonymousEndpoint = oldIsAnonymousEndpoint
  87. if err := container.CheckpointTo(daemon.containersReplica); err != nil {
  88. log.G(context.TODO()).WithFields(log.Fields{
  89. "containerID": container.ID,
  90. "error": err,
  91. }).Error("failed to write container state to disk during rename")
  92. }
  93. }
  94. }()
  95. sid = container.NetworkSettings.SandboxID
  96. if sid != "" && daemon.netController != nil {
  97. sb, err = daemon.netController.SandboxByID(sid)
  98. if err != nil {
  99. return err
  100. }
  101. err = sb.Rename(strings.TrimPrefix(container.Name, "/"))
  102. if err != nil {
  103. return err
  104. }
  105. }
  106. daemon.LogContainerEventWithAttributes(container, events.ActionRename, attributes)
  107. return nil
  108. }