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