github.com/rawahars/moby@v24.0.4+incompatible/daemon/names.go (about)

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