github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/daemon/rename.go (about)

     1  package daemon
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/Sirupsen/logrus"
     9  	dockercontainer "github.com/docker/docker/container"
    10  	"github.com/docker/libnetwork"
    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 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  	oldName = container.Name
    36  	oldIsAnonymousEndpoint := container.NetworkSettings.IsAnonymousEndpoint
    37  
    38  	if oldName == newName {
    39  		return errors.New("Renaming a container with the same name as its current name")
    40  	}
    41  
    42  	container.Lock()
    43  	defer container.Unlock()
    44  
    45  	links := map[string]*dockercontainer.Container{}
    46  	for k, v := range daemon.linkIndex.children(container) {
    47  		if !strings.HasPrefix(k, oldName) {
    48  			return fmt.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 fmt.Errorf("Error when allocating new name: %v", err)
    55  	}
    56  
    57  	for k, v := range links {
    58  		daemon.nameIndex.Reserve(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.nameIndex.Reserve(oldName+k, v.ID)
    72  				daemon.linkIndex.link(container, v, oldName+k)
    73  				daemon.linkIndex.unlink(newName+k, v, container)
    74  				daemon.nameIndex.Release(newName + k)
    75  			}
    76  			daemon.releaseName(newName)
    77  		}
    78  	}()
    79  
    80  	for k, v := range links {
    81  		daemon.linkIndex.unlink(oldName+k, v, container)
    82  		daemon.nameIndex.Release(oldName + k)
    83  	}
    84  	daemon.releaseName(oldName)
    85  	if err = container.ToDisk(); err != nil {
    86  		return err
    87  	}
    88  
    89  	attributes := map[string]string{
    90  		"oldName": oldName,
    91  	}
    92  
    93  	if !container.Running {
    94  		daemon.LogContainerEventWithAttributes(container, "rename", attributes)
    95  		return nil
    96  	}
    97  
    98  	defer func() {
    99  		if err != nil {
   100  			container.Name = oldName
   101  			container.NetworkSettings.IsAnonymousEndpoint = oldIsAnonymousEndpoint
   102  			if e := container.ToDisk(); e != nil {
   103  				logrus.Errorf("%s: Failed in writing to Disk on rename failure: %v", container.ID, e)
   104  			}
   105  		}
   106  	}()
   107  
   108  	sid = container.NetworkSettings.SandboxID
   109  	if daemon.netController != nil {
   110  		sb, err = daemon.netController.SandboxByID(sid)
   111  		if err != nil {
   112  			return err
   113  		}
   114  
   115  		err = sb.Rename(strings.TrimPrefix(container.Name, "/"))
   116  		if err != nil {
   117  			return err
   118  		}
   119  	}
   120  
   121  	daemon.LogContainerEventWithAttributes(container, "rename", attributes)
   122  	return nil
   123  }