github.com/kim0/docker@v0.6.2-0.20161130212042-4addda3f07e7/daemon/names.go (about)

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