2018-02-05 21:05:59 +00:00
|
|
|
package daemon // import "github.com/docker/docker/daemon"
|
2016-05-24 15:49:26 +00:00
|
|
|
|
|
|
|
import (
|
2023-06-23 00:33:17 +00:00
|
|
|
"context"
|
2016-05-24 15:49:26 +00:00
|
|
|
"fmt"
|
2016-11-23 19:45:35 +00:00
|
|
|
"strings"
|
2016-05-24 15:49:26 +00:00
|
|
|
|
2023-09-13 15:41:45 +00:00
|
|
|
"github.com/containerd/log"
|
2016-05-24 15:49:26 +00:00
|
|
|
"github.com/docker/docker/container"
|
2017-09-06 15:35:06 +00:00
|
|
|
"github.com/docker/docker/daemon/names"
|
2018-01-11 19:53:06 +00:00
|
|
|
"github.com/docker/docker/errdefs"
|
2016-05-24 15:49:26 +00:00
|
|
|
"github.com/docker/docker/pkg/namesgenerator"
|
|
|
|
"github.com/docker/docker/pkg/stringid"
|
2017-07-19 14:20:13 +00:00
|
|
|
"github.com/pkg/errors"
|
2016-05-24 15:49:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2017-09-06 15:35:06 +00:00
|
|
|
validContainerNameChars = names.RestrictedNameChars
|
|
|
|
validContainerNamePattern = names.RestrictedNamePattern
|
2016-05-24 15:49:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func (daemon *Daemon) registerName(container *container.Container) error {
|
|
|
|
if daemon.Exists(container.ID) {
|
|
|
|
return fmt.Errorf("Container is already loaded")
|
|
|
|
}
|
|
|
|
if err := validateID(container.ID); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if container.Name == "" {
|
2023-06-13 11:33:33 +00:00
|
|
|
name, err := daemon.generateAndReserveName(container.ID)
|
2016-05-24 15:49:26 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
container.Name = name
|
2023-06-13 11:33:33 +00:00
|
|
|
return nil
|
2016-05-24 15:49:26 +00:00
|
|
|
}
|
2017-06-30 01:56:22 +00:00
|
|
|
return daemon.containersReplica.ReserveName(container.Name, container.ID)
|
2016-05-24 15:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
|
|
|
|
var (
|
|
|
|
err error
|
2019-06-07 10:21:18 +00:00
|
|
|
id = stringid.GenerateRandomID()
|
2016-05-24 15:49:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if name == "" {
|
2023-06-13 11:33:33 +00:00
|
|
|
if name, err = daemon.generateAndReserveName(id); err != nil {
|
2016-05-24 15:49:26 +00:00
|
|
|
return "", "", err
|
|
|
|
}
|
|
|
|
return id, name, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if name, err = daemon.reserveName(id, name); err != nil {
|
|
|
|
return "", "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return id, name, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (daemon *Daemon) reserveName(id, name string) (string, error) {
|
2016-11-23 19:45:35 +00:00
|
|
|
if !validContainerNamePattern.MatchString(strings.TrimPrefix(name, "/")) {
|
2017-11-29 04:09:37 +00:00
|
|
|
return "", errdefs.InvalidParameter(errors.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars))
|
2016-05-24 15:49:26 +00:00
|
|
|
}
|
|
|
|
if name[0] != '/' {
|
|
|
|
name = "/" + name
|
|
|
|
}
|
|
|
|
|
2017-06-30 01:56:22 +00:00
|
|
|
if err := daemon.containersReplica.ReserveName(name, id); err != nil {
|
2022-07-08 11:29:56 +00:00
|
|
|
if errors.Is(err, container.ErrNameReserved) {
|
2017-06-30 01:56:22 +00:00
|
|
|
id, err := daemon.containersReplica.Snapshot().GetID(name)
|
2016-05-24 15:49:26 +00:00
|
|
|
if err != nil {
|
2023-06-23 00:33:17 +00:00
|
|
|
log.G(context.TODO()).Errorf("got unexpected error while looking up reserved name: %v", err)
|
2016-05-24 15:49:26 +00:00
|
|
|
return "", err
|
|
|
|
}
|
2017-09-28 15:13:51 +00:00
|
|
|
return "", nameConflictError{id: id, name: name}
|
2016-05-24 15:49:26 +00:00
|
|
|
}
|
2017-07-19 14:20:13 +00:00
|
|
|
return "", errors.Wrapf(err, "error reserving name: %q", name)
|
2016-05-24 15:49:26 +00:00
|
|
|
}
|
|
|
|
return name, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (daemon *Daemon) releaseName(name string) {
|
2017-06-30 01:56:22 +00:00
|
|
|
daemon.containersReplica.ReleaseName(name)
|
2016-05-24 15:49:26 +00:00
|
|
|
}
|
|
|
|
|
2023-06-13 11:33:33 +00:00
|
|
|
func (daemon *Daemon) generateAndReserveName(id string) (string, error) {
|
2016-05-24 15:49:26 +00:00
|
|
|
var name string
|
|
|
|
for i := 0; i < 6; i++ {
|
|
|
|
name = namesgenerator.GetRandomName(i)
|
|
|
|
if name[0] != '/' {
|
|
|
|
name = "/" + name
|
|
|
|
}
|
|
|
|
|
2017-06-30 01:56:22 +00:00
|
|
|
if err := daemon.containersReplica.ReserveName(name, id); err != nil {
|
2022-07-08 11:29:56 +00:00
|
|
|
if errors.Is(err, container.ErrNameReserved) {
|
2016-05-24 15:49:26 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return name, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
name = "/" + stringid.TruncateID(id)
|
2017-06-30 01:56:22 +00:00
|
|
|
if err := daemon.containersReplica.ReserveName(name, id); err != nil {
|
2016-05-24 15:49:26 +00:00
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return name, nil
|
|
|
|
}
|
2016-05-27 09:32:26 +00:00
|
|
|
|
|
|
|
func validateID(id string) error {
|
|
|
|
if id == "" {
|
|
|
|
return fmt.Errorf("Invalid empty id")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|