Przeglądaj źródła

Move some container related methods and structs to smaller files

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Vincent Demeester 9 lat temu
rodzic
commit
fb48bf518b
7 zmienionych plików z 279 dodań i 258 usunięć
  1. 1 1
      daemon/changes.go
  2. 145 0
      daemon/container.go
  3. 12 0
      daemon/create.go
  4. 0 257
      daemon/daemon.go
  5. 4 0
      daemon/kill.go
  6. 108 0
      daemon/names.go
  7. 9 0
      daemon/stats.go

+ 1 - 1
daemon/changes.go

@@ -11,5 +11,5 @@ func (daemon *Daemon) ContainerChanges(name string) ([]archive.Change, error) {
 
 	container.Lock()
 	defer container.Unlock()
-	return daemon.changes(container)
+	return container.RWLayer.Changes()
 }

+ 145 - 0
daemon/container.go

@@ -0,0 +1,145 @@
+package daemon
+
+import (
+	"fmt"
+	"path/filepath"
+	"time"
+
+	"github.com/docker/docker/container"
+	"github.com/docker/docker/daemon/network"
+	"github.com/docker/docker/errors"
+	"github.com/docker/docker/image"
+	"github.com/docker/docker/pkg/truncindex"
+	containertypes "github.com/docker/engine-api/types/container"
+)
+
+// GetContainer looks for a container using the provided information, which could be
+// one of the following inputs from the caller:
+//  - A full container ID, which will exact match a container in daemon's list
+//  - A container name, which will only exact match via the GetByName() function
+//  - A partial container ID prefix (e.g. short ID) of any length that is
+//    unique enough to only return a single container object
+//  If none of these searches succeed, an error is returned
+func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) {
+	if len(prefixOrName) == 0 {
+		return nil, errors.NewBadRequestError(fmt.Errorf("No container name or ID supplied"))
+	}
+
+	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
+		// prefix is an exact match to a full container ID
+		return containerByID, nil
+	}
+
+	// GetByName will match only an exact name provided; we ignore errors
+	if containerByName, _ := daemon.GetByName(prefixOrName); containerByName != nil {
+		// prefix is an exact match to a full container Name
+		return containerByName, nil
+	}
+
+	containerID, indexError := daemon.idIndex.Get(prefixOrName)
+	if indexError != nil {
+		// When truncindex defines an error type, use that instead
+		if indexError == truncindex.ErrNotExist {
+			err := fmt.Errorf("No such container: %s", prefixOrName)
+			return nil, errors.NewRequestNotFoundError(err)
+		}
+		return nil, indexError
+	}
+	return daemon.containers.Get(containerID), nil
+}
+
+// Exists returns a true if a container of the specified ID or name exists,
+// false otherwise.
+func (daemon *Daemon) Exists(id string) bool {
+	c, _ := daemon.GetContainer(id)
+	return c != nil
+}
+
+// IsPaused returns a bool indicating if the specified container is paused.
+func (daemon *Daemon) IsPaused(id string) bool {
+	c, _ := daemon.GetContainer(id)
+	return c.State.IsPaused()
+}
+
+func (daemon *Daemon) containerRoot(id string) string {
+	return filepath.Join(daemon.repository, id)
+}
+
+// Load reads the contents of a container from disk
+// This is typically done at startup.
+func (daemon *Daemon) load(id string) (*container.Container, error) {
+	container := daemon.newBaseContainer(id)
+
+	if err := container.FromDisk(); err != nil {
+		return nil, err
+	}
+
+	if container.ID != id {
+		return container, fmt.Errorf("Container %s is stored at %s", container.ID, id)
+	}
+
+	return container, nil
+}
+
+// Register makes a container object usable by the daemon as <container.ID>
+func (daemon *Daemon) Register(c *container.Container) error {
+	// Attach to stdout and stderr
+	if c.Config.OpenStdin {
+		c.NewInputPipes()
+	} else {
+		c.NewNopInputPipe()
+	}
+
+	daemon.containers.Add(c.ID, c)
+	daemon.idIndex.Add(c.ID)
+
+	return nil
+}
+
+func (daemon *Daemon) newContainer(name string, config *containertypes.Config, imgID image.ID) (*container.Container, error) {
+	var (
+		id             string
+		err            error
+		noExplicitName = name == ""
+	)
+	id, name, err = daemon.generateIDAndName(name)
+	if err != nil {
+		return nil, err
+	}
+
+	daemon.generateHostname(id, config)
+	entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
+
+	base := daemon.newBaseContainer(id)
+	base.Created = time.Now().UTC()
+	base.Path = entrypoint
+	base.Args = args //FIXME: de-duplicate from config
+	base.Config = config
+	base.HostConfig = &containertypes.HostConfig{}
+	base.ImageID = imgID
+	base.NetworkSettings = &network.Settings{IsAnonymousEndpoint: noExplicitName}
+	base.Name = name
+	base.Driver = daemon.GraphDriverName()
+
+	return base, err
+}
+
+// GetByName returns a container given a name.
+func (daemon *Daemon) GetByName(name string) (*container.Container, error) {
+	if len(name) == 0 {
+		return nil, fmt.Errorf("No container name supplied")
+	}
+	fullName := name
+	if name[0] != '/' {
+		fullName = "/" + name
+	}
+	id, err := daemon.nameIndex.Get(fullName)
+	if err != nil {
+		return nil, fmt.Errorf("Could not find entity for %s", name)
+	}
+	e := daemon.containers.Get(id)
+	if e == nil {
+		return nil, fmt.Errorf("Could not find container for entity id %s", id)
+	}
+	return e, nil
+}

+ 12 - 0
daemon/create.go

@@ -218,3 +218,15 @@ func (daemon *Daemon) VolumeCreate(name, driverName string, opts, labels map[str
 	apiV.Mountpoint = v.Path()
 	return apiV, nil
 }
+
+func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *image.Image) error {
+	if img != nil && img.Config != nil {
+		if err := merge(config, img.Config); err != nil {
+			return err
+		}
+	}
+	if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
+		return fmt.Errorf("No command specified")
+	}
+	return nil
+}

+ 0 - 257
daemon/daemon.go

@@ -36,7 +36,6 @@ import (
 	"github.com/docker/engine-api/types/strslice"
 	// register graph drivers
 	_ "github.com/docker/docker/daemon/graphdriver/register"
-	"github.com/docker/docker/daemon/network"
 	dmetadata "github.com/docker/docker/distribution/metadata"
 	"github.com/docker/docker/distribution/xfer"
 	"github.com/docker/docker/dockerversion"
@@ -44,16 +43,13 @@ import (
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/migrate/v1"
-	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/graphdb"
 	"github.com/docker/docker/pkg/idtools"
-	"github.com/docker/docker/pkg/namesgenerator"
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/pkg/registrar"
 	"github.com/docker/docker/pkg/signal"
 	"github.com/docker/docker/pkg/streamformatter"
-	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/sysinfo"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/pkg/truncindex"
@@ -73,9 +69,6 @@ import (
 )
 
 var (
-	validContainerNameChars   = utils.RestrictedNameChars
-	validContainerNamePattern = utils.RestrictedNamePattern
-
 	errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.")
 )
 
@@ -112,110 +105,6 @@ type Daemon struct {
 	defaultIsolation          containertypes.Isolation // Default isolation mode on Windows
 }
 
-// GetContainer looks for a container using the provided information, which could be
-// one of the following inputs from the caller:
-//  - A full container ID, which will exact match a container in daemon's list
-//  - A container name, which will only exact match via the GetByName() function
-//  - A partial container ID prefix (e.g. short ID) of any length that is
-//    unique enough to only return a single container object
-//  If none of these searches succeed, an error is returned
-func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) {
-	if len(prefixOrName) == 0 {
-		return nil, errors.NewBadRequestError(fmt.Errorf("No container name or ID supplied"))
-	}
-
-	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
-		// prefix is an exact match to a full container ID
-		return containerByID, nil
-	}
-
-	// GetByName will match only an exact name provided; we ignore errors
-	if containerByName, _ := daemon.GetByName(prefixOrName); containerByName != nil {
-		// prefix is an exact match to a full container Name
-		return containerByName, nil
-	}
-
-	containerID, indexError := daemon.idIndex.Get(prefixOrName)
-	if indexError != nil {
-		// When truncindex defines an error type, use that instead
-		if indexError == truncindex.ErrNotExist {
-			err := fmt.Errorf("No such container: %s", prefixOrName)
-			return nil, errors.NewRequestNotFoundError(err)
-		}
-		return nil, indexError
-	}
-	return daemon.containers.Get(containerID), nil
-}
-
-// Exists returns a true if a container of the specified ID or name exists,
-// false otherwise.
-func (daemon *Daemon) Exists(id string) bool {
-	c, _ := daemon.GetContainer(id)
-	return c != nil
-}
-
-// IsPaused returns a bool indicating if the specified container is paused.
-func (daemon *Daemon) IsPaused(id string) bool {
-	c, _ := daemon.GetContainer(id)
-	return c.State.IsPaused()
-}
-
-func (daemon *Daemon) containerRoot(id string) string {
-	return filepath.Join(daemon.repository, id)
-}
-
-// Load reads the contents of a container from disk
-// This is typically done at startup.
-func (daemon *Daemon) load(id string) (*container.Container, error) {
-	container := daemon.newBaseContainer(id)
-
-	if err := container.FromDisk(); err != nil {
-		return nil, err
-	}
-
-	if container.ID != id {
-		return container, fmt.Errorf("Container %s is stored at %s", container.ID, id)
-	}
-
-	return container, nil
-}
-
-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 == "" {
-		name, err := daemon.generateNewName(container.ID)
-		if err != nil {
-			return err
-		}
-		container.Name = name
-
-		if err := container.ToDiskLocking(); err != nil {
-			logrus.Errorf("Error saving container name to disk: %v", err)
-		}
-	}
-	return daemon.nameIndex.Reserve(container.Name, container.ID)
-}
-
-// Register makes a container object usable by the daemon as <container.ID>
-func (daemon *Daemon) Register(c *container.Container) error {
-	// Attach to stdout and stderr
-	if c.Config.OpenStdin {
-		c.NewInputPipes()
-	} else {
-		c.NewNopInputPipe()
-	}
-
-	daemon.containers.Add(c.ID, c)
-	daemon.idIndex.Add(c.ID)
-
-	return nil
-}
-
 func (daemon *Daemon) restore() error {
 	var (
 		debug         = utils.IsDebugEnabled()
@@ -431,88 +320,6 @@ func (daemon *Daemon) waitForNetworks(c *container.Container) {
 	}
 }
 
-func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *image.Image) error {
-	if img != nil && img.Config != nil {
-		if err := merge(config, img.Config); err != nil {
-			return err
-		}
-	}
-	if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
-		return fmt.Errorf("No command specified")
-	}
-	return nil
-}
-
-func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
-	var (
-		err error
-		id  = stringid.GenerateNonCryptoID()
-	)
-
-	if name == "" {
-		if name, err = daemon.generateNewName(id); err != nil {
-			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) {
-	if !validContainerNamePattern.MatchString(name) {
-		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
-	}
-	if name[0] != '/' {
-		name = "/" + name
-	}
-
-	if err := daemon.nameIndex.Reserve(name, id); err != nil {
-		if err == registrar.ErrNameReserved {
-			id, err := daemon.nameIndex.Get(name)
-			if err != nil {
-				logrus.Errorf("got unexpected error while looking up reserved name: %v", err)
-				return "", err
-			}
-			return "", fmt.Errorf("Conflict. The 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)
-		}
-		return "", fmt.Errorf("error reserving name: %s, error: %v", name, err)
-	}
-	return name, nil
-}
-
-func (daemon *Daemon) releaseName(name string) {
-	daemon.nameIndex.Release(name)
-}
-
-func (daemon *Daemon) generateNewName(id string) (string, error) {
-	var name string
-	for i := 0; i < 6; i++ {
-		name = namesgenerator.GetRandomName(i)
-		if name[0] != '/' {
-			name = "/" + name
-		}
-
-		if err := daemon.nameIndex.Reserve(name, id); err != nil {
-			if err == registrar.ErrNameReserved {
-				continue
-			}
-			return "", err
-		}
-		return name, nil
-	}
-
-	name = "/" + stringid.TruncateID(id)
-	if err := daemon.nameIndex.Reserve(name, id); err != nil {
-		return "", err
-	}
-	return name, nil
-}
-
 func (daemon *Daemon) generateHostname(id string, config *containertypes.Config) {
 	// Generate default hostname
 	if config.Hostname == "" {
@@ -527,54 +334,6 @@ func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint strslice.StrSlice, c
 	return configCmd[0], configCmd[1:]
 }
 
-func (daemon *Daemon) newContainer(name string, config *containertypes.Config, imgID image.ID) (*container.Container, error) {
-	var (
-		id             string
-		err            error
-		noExplicitName = name == ""
-	)
-	id, name, err = daemon.generateIDAndName(name)
-	if err != nil {
-		return nil, err
-	}
-
-	daemon.generateHostname(id, config)
-	entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
-
-	base := daemon.newBaseContainer(id)
-	base.Created = time.Now().UTC()
-	base.Path = entrypoint
-	base.Args = args //FIXME: de-duplicate from config
-	base.Config = config
-	base.HostConfig = &containertypes.HostConfig{}
-	base.ImageID = imgID
-	base.NetworkSettings = &network.Settings{IsAnonymousEndpoint: noExplicitName}
-	base.Name = name
-	base.Driver = daemon.GraphDriverName()
-
-	return base, err
-}
-
-// GetByName returns a container given a name.
-func (daemon *Daemon) GetByName(name string) (*container.Container, error) {
-	if len(name) == 0 {
-		return nil, fmt.Errorf("No container name supplied")
-	}
-	fullName := name
-	if name[0] != '/' {
-		fullName = "/" + name
-	}
-	id, err := daemon.nameIndex.Get(fullName)
-	if err != nil {
-		return nil, fmt.Errorf("Could not find entity for %s", name)
-	}
-	e := daemon.containers.Get(id)
-	if e == nil {
-		return nil, fmt.Errorf("Could not find container for entity id %s", id)
-	}
-	return e, nil
-}
-
 // GetLabels for a container or image id
 func (daemon *Daemon) GetLabels(id string) map[string]string {
 	// TODO: TestCase
@@ -947,22 +706,6 @@ func (daemon *Daemon) Unmount(container *container.Container) error {
 	return nil
 }
 
-func (daemon *Daemon) kill(c *container.Container, sig int) error {
-	return daemon.containerd.Signal(c.ID, sig)
-}
-
-func (daemon *Daemon) subscribeToContainerStats(c *container.Container) chan interface{} {
-	return daemon.statsCollector.collect(c)
-}
-
-func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch chan interface{}) {
-	daemon.statsCollector.unsubscribe(c, ch)
-}
-
-func (daemon *Daemon) changes(container *container.Container) ([]archive.Change, error) {
-	return container.RWLayer.Changes()
-}
-
 func writeDistributionProgress(cancelFunc func(), outStream io.Writer, progressChan <-chan progress.Progress) {
 	progressOutput := streamformatter.NewJSONStreamFormatter().NewProgressOutput(outStream, false)
 	operationCancelled := false

+ 4 - 0
daemon/kill.go

@@ -151,3 +151,7 @@ func (daemon *Daemon) killPossiblyDeadProcess(container *container.Container, si
 	}
 	return err
 }
+
+func (daemon *Daemon) kill(c *container.Container, sig int) error {
+	return daemon.containerd.Signal(c.ID, sig)
+}

+ 108 - 0
daemon/names.go

@@ -0,0 +1,108 @@
+package daemon
+
+import (
+	"fmt"
+
+	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/container"
+	"github.com/docker/docker/pkg/namesgenerator"
+	"github.com/docker/docker/pkg/registrar"
+	"github.com/docker/docker/pkg/stringid"
+	"github.com/docker/docker/utils"
+)
+
+var (
+	validContainerNameChars   = utils.RestrictedNameChars
+	validContainerNamePattern = utils.RestrictedNamePattern
+)
+
+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 == "" {
+		name, err := daemon.generateNewName(container.ID)
+		if err != nil {
+			return err
+		}
+		container.Name = name
+
+		if err := container.ToDiskLocking(); err != nil {
+			logrus.Errorf("Error saving container name to disk: %v", err)
+		}
+	}
+	return daemon.nameIndex.Reserve(container.Name, container.ID)
+}
+
+func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
+	var (
+		err error
+		id  = stringid.GenerateNonCryptoID()
+	)
+
+	if name == "" {
+		if name, err = daemon.generateNewName(id); err != nil {
+			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) {
+	if !validContainerNamePattern.MatchString(name) {
+		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
+	}
+	if name[0] != '/' {
+		name = "/" + name
+	}
+
+	if err := daemon.nameIndex.Reserve(name, id); err != nil {
+		if err == registrar.ErrNameReserved {
+			id, err := daemon.nameIndex.Get(name)
+			if err != nil {
+				logrus.Errorf("got unexpected error while looking up reserved name: %v", err)
+				return "", err
+			}
+			return "", fmt.Errorf("Conflict. The 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)
+		}
+		return "", fmt.Errorf("error reserving name: %s, error: %v", name, err)
+	}
+	return name, nil
+}
+
+func (daemon *Daemon) releaseName(name string) {
+	daemon.nameIndex.Release(name)
+}
+
+func (daemon *Daemon) generateNewName(id string) (string, error) {
+	var name string
+	for i := 0; i < 6; i++ {
+		name = namesgenerator.GetRandomName(i)
+		if name[0] != '/' {
+			name = "/" + name
+		}
+
+		if err := daemon.nameIndex.Reserve(name, id); err != nil {
+			if err == registrar.ErrNameReserved {
+				continue
+			}
+			return "", err
+		}
+		return name, nil
+	}
+
+	name = "/" + stringid.TruncateID(id)
+	if err := daemon.nameIndex.Reserve(name, id); err != nil {
+		return "", err
+	}
+	return name, nil
+}

+ 9 - 0
daemon/stats.go

@@ -8,6 +8,7 @@ import (
 	"golang.org/x/net/context"
 
 	"github.com/docker/docker/api/types/backend"
+	"github.com/docker/docker/container"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types/versions"
@@ -121,3 +122,11 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
 		}
 	}
 }
+
+func (daemon *Daemon) subscribeToContainerStats(c *container.Container) chan interface{} {
+	return daemon.statsCollector.collect(c)
+}
+
+func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch chan interface{}) {
+	daemon.statsCollector.unsubscribe(c, ch)
+}