github.com/mforkel/docker-ce-i386@v17.12.1-ce-rc2+incompatible/components/engine/daemon/rename.go (about) 1 package daemon 2 3 import ( 4 "strings" 5 6 dockercontainer "github.com/docker/docker/container" 7 "github.com/docker/libnetwork" 8 "github.com/pkg/errors" 9 "github.com/sirupsen/logrus" 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 validationError{errors.New("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 container.Lock() 35 defer container.Unlock() 36 37 oldName = container.Name 38 oldIsAnonymousEndpoint := container.NetworkSettings.IsAnonymousEndpoint 39 40 if oldName == newName { 41 return validationError{errors.New("Renaming a container with the same name as its current name")} 42 } 43 44 links := map[string]*dockercontainer.Container{} 45 for k, v := range daemon.linkIndex.children(container) { 46 if !strings.HasPrefix(k, oldName) { 47 return validationError{errors.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 errors.Wrap(err, "Error when allocating new name") 54 } 55 56 for k, v := range links { 57 daemon.containersReplica.ReserveName(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.containersReplica.ReserveName(oldName+k, v.ID) 71 daemon.linkIndex.link(container, v, oldName+k) 72 daemon.linkIndex.unlink(newName+k, v, container) 73 daemon.containersReplica.ReleaseName(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.containersReplica.ReleaseName(oldName + k) 82 } 83 daemon.releaseName(oldName) 84 if err = container.CheckpointTo(daemon.containersReplica); 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.CheckpointTo(daemon.containersReplica); 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 sid != "" && 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 }