github.com/kaisenlinux/docker@v0.0.0-20230510090727-ea55db55fac7/engine/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/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  }