github.com/niusmallnan/moby@v1.13.1/daemon/names.go (about)

     1  package daemon
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/Sirupsen/logrus"
     8  	"github.com/docker/docker/container"
     9  	"github.com/docker/docker/pkg/namesgenerator"
    10  	"github.com/docker/docker/pkg/registrar"
    11  	"github.com/docker/docker/pkg/stringid"
    12  	"github.com/docker/docker/utils"
    13  )
    14  
    15  var (
    16  	validContainerNameChars   = utils.RestrictedNameChars
    17  	validContainerNamePattern = utils.RestrictedNamePattern
    18  )
    19  
    20  func (daemon *Daemon) registerName(container *container.Container) error {
    21  	if daemon.Exists(container.ID) {
    22  		return fmt.Errorf("Container is already loaded")
    23  	}
    24  	if err := validateID(container.ID); err != nil {
    25  		return err
    26  	}
    27  	if container.Name == "" {
    28  		name, err := daemon.generateNewName(container.ID)
    29  		if err != nil {
    30  			return err
    31  		}
    32  		container.Name = name
    33  
    34  		if err := container.ToDiskLocking(); err != nil {
    35  			logrus.Errorf("Error saving container name to disk: %v", err)
    36  		}
    37  	}
    38  	return daemon.nameIndex.Reserve(container.Name, container.ID)
    39  }
    40  
    41  func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
    42  	var (
    43  		err error
    44  		id  = stringid.GenerateNonCryptoID()
    45  	)
    46  
    47  	if name == "" {
    48  		if name, err = daemon.generateNewName(id); err != nil {
    49  			return "", "", err
    50  		}
    51  		return id, name, nil
    52  	}
    53  
    54  	if name, err = daemon.reserveName(id, name); err != nil {
    55  		return "", "", err
    56  	}
    57  
    58  	return id, name, nil
    59  }
    60  
    61  func (daemon *Daemon) reserveName(id, name string) (string, error) {
    62  	if !validContainerNamePattern.MatchString(strings.TrimPrefix(name, "/")) {
    63  		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
    64  	}
    65  	if name[0] != '/' {
    66  		name = "/" + name
    67  	}
    68  
    69  	if err := daemon.nameIndex.Reserve(name, id); err != nil {
    70  		if err == registrar.ErrNameReserved {
    71  			id, err := daemon.nameIndex.Get(name)
    72  			if err != nil {
    73  				logrus.Errorf("got unexpected error while looking up reserved name: %v", err)
    74  				return "", err
    75  			}
    76  			return "", fmt.Errorf("Conflict. The container name %q is already in use by container %s. You have to remove (or rename) that container to be able to reuse that name.", name, id)
    77  		}
    78  		return "", fmt.Errorf("error reserving name: %s, error: %v", name, err)
    79  	}
    80  	return name, nil
    81  }
    82  
    83  func (daemon *Daemon) releaseName(name string) {
    84  	daemon.nameIndex.Release(name)
    85  }
    86  
    87  func (daemon *Daemon) generateNewName(id string) (string, error) {
    88  	var name string
    89  	for i := 0; i < 6; i++ {
    90  		name = namesgenerator.GetRandomName(i)
    91  		if name[0] != '/' {
    92  			name = "/" + name
    93  		}
    94  
    95  		if err := daemon.nameIndex.Reserve(name, id); err != nil {
    96  			if err == registrar.ErrNameReserved {
    97  				continue
    98  			}
    99  			return "", err
   100  		}
   101  		return name, nil
   102  	}
   103  
   104  	name = "/" + stringid.TruncateID(id)
   105  	if err := daemon.nameIndex.Reserve(name, id); err != nil {
   106  		return "", err
   107  	}
   108  	return name, nil
   109  }
   110  
   111  func validateID(id string) error {
   112  	if id == "" {
   113  		return fmt.Errorf("Invalid empty id")
   114  	}
   115  	return nil
   116  }