github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/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/pkg/namesgenerator"
    10  	"github.com/docker/docker/pkg/stringid"
    11  	"github.com/pkg/errors"
    12  	"github.com/sirupsen/logrus"
    13  )
    14  
    15  var (
    16  	validContainerNameChars   = names.RestrictedNameChars
    17  	validContainerNamePattern = names.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  	return daemon.containersReplica.ReserveName(container.Name, container.ID)
    35  }
    36  
    37  func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
    38  	var (
    39  		err error
    40  		id  = stringid.GenerateNonCryptoID()
    41  	)
    42  
    43  	if name == "" {
    44  		if name, err = daemon.generateNewName(id); err != nil {
    45  			return "", "", err
    46  		}
    47  		return id, name, nil
    48  	}
    49  
    50  	if name, err = daemon.reserveName(id, name); err != nil {
    51  		return "", "", err
    52  	}
    53  
    54  	return id, name, nil
    55  }
    56  
    57  func (daemon *Daemon) reserveName(id, name string) (string, error) {
    58  	if !validContainerNamePattern.MatchString(strings.TrimPrefix(name, "/")) {
    59  		return "", validationError{errors.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)}
    60  	}
    61  	if name[0] != '/' {
    62  		name = "/" + name
    63  	}
    64  
    65  	if err := daemon.containersReplica.ReserveName(name, id); err != nil {
    66  		if err == container.ErrNameReserved {
    67  			id, err := daemon.containersReplica.Snapshot().GetID(name)
    68  			if err != nil {
    69  				logrus.Errorf("got unexpected error while looking up reserved name: %v", err)
    70  				return "", err
    71  			}
    72  			return "", nameConflictError{id: id, name: name}
    73  		}
    74  		return "", errors.Wrapf(err, "error reserving name: %q", name)
    75  	}
    76  	return name, nil
    77  }
    78  
    79  func (daemon *Daemon) releaseName(name string) {
    80  	daemon.containersReplica.ReleaseName(name)
    81  }
    82  
    83  func (daemon *Daemon) generateNewName(id string) (string, error) {
    84  	var name string
    85  	for i := 0; i < 6; i++ {
    86  		name = namesgenerator.GetRandomName(i)
    87  		if name[0] != '/' {
    88  			name = "/" + name
    89  		}
    90  
    91  		if err := daemon.containersReplica.ReserveName(name, id); err != nil {
    92  			if err == container.ErrNameReserved {
    93  				continue
    94  			}
    95  			return "", err
    96  		}
    97  		return name, nil
    98  	}
    99  
   100  	name = "/" + stringid.TruncateID(id)
   101  	if err := daemon.containersReplica.ReserveName(name, id); err != nil {
   102  		return "", err
   103  	}
   104  	return name, nil
   105  }
   106  
   107  func validateID(id string) error {
   108  	if id == "" {
   109  		return fmt.Errorf("Invalid empty id")
   110  	}
   111  	return nil
   112  }