github.com/rhatdan/docker@v0.7.7-0.20180119204836-47a0dcbcd20a/daemon/names.go (about)

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