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