Merge pull request #16228 from duglin/ContextualizeEvents
Add context.RequestID to event stream Upstream-commit: de4164043546d2b9ee3bf323dbc41f4979c84480 Component: engine
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/chrootarchive"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
@@ -20,8 +21,8 @@ var ErrExtractPointNotDirectory = errors.New("extraction point is not a director
|
||||
|
||||
// ContainerCopy performs a deprecated operation of archiving the resource at
|
||||
// the specified path in the conatiner identified by the given name.
|
||||
func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, error) {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerCopy(ctx context.Context, name string, res string) (io.ReadCloser, error) {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -30,30 +31,30 @@ func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, err
|
||||
res = res[1:]
|
||||
}
|
||||
|
||||
return container.copy(res)
|
||||
return container.copy(ctx, res)
|
||||
}
|
||||
|
||||
// ContainerStatPath stats the filesystem resource at the specified path in the
|
||||
// container identified by the given name.
|
||||
func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.ContainerPathStat, err error) {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerStatPath(ctx context.Context, name string, path string) (stat *types.ContainerPathStat, err error) {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return container.StatPath(path)
|
||||
return container.StatPath(ctx, path)
|
||||
}
|
||||
|
||||
// ContainerArchivePath creates an archive of the filesystem resource at the
|
||||
// specified path in the container identified by the given name. Returns a
|
||||
// tar archive of the resource and whether it was a directory or a single file.
|
||||
func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerArchivePath(ctx context.Context, name string, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return container.ArchivePath(path)
|
||||
return container.ArchivePath(ctx, path)
|
||||
}
|
||||
|
||||
// ContainerExtractToDir extracts the given archive to the specified location
|
||||
@@ -62,13 +63,13 @@ func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io
|
||||
// be ErrExtractPointNotDirectory. If noOverwriteDirNonDir is true then it will
|
||||
// be an error if unpacking the given content would cause an existing directory
|
||||
// to be replaced with a non-directory and vice versa.
|
||||
func (daemon *Daemon) ContainerExtractToDir(name, path string, noOverwriteDirNonDir bool, content io.Reader) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerExtractToDir(ctx context.Context, name, path string, noOverwriteDirNonDir bool, content io.Reader) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return container.ExtractToDir(path, noOverwriteDirNonDir, content)
|
||||
return container.ExtractToDir(ctx, path, noOverwriteDirNonDir, content)
|
||||
}
|
||||
|
||||
// resolvePath resolves the given path in the container to a resource on the
|
||||
@@ -133,14 +134,14 @@ func (container *Container) statPath(resolvedPath, absPath string) (stat *types.
|
||||
|
||||
// StatPath stats the filesystem resource at the specified path in this
|
||||
// container. Returns stat info about the resource.
|
||||
func (container *Container) StatPath(path string) (stat *types.ContainerPathStat, err error) {
|
||||
func (container *Container) StatPath(ctx context.Context, path string) (stat *types.ContainerPathStat, err error) {
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
if err = container.Mount(); err != nil {
|
||||
if err = container.Mount(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer container.Unmount()
|
||||
defer container.Unmount(ctx)
|
||||
|
||||
err = container.mountVolumes()
|
||||
defer container.unmountVolumes(true)
|
||||
@@ -159,7 +160,7 @@ func (container *Container) StatPath(path string) (stat *types.ContainerPathStat
|
||||
// ArchivePath creates an archive of the filesystem resource at the specified
|
||||
// path in this container. Returns a tar archive of the resource and stat info
|
||||
// about the resource.
|
||||
func (container *Container) ArchivePath(path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
|
||||
func (container *Container) ArchivePath(ctx context.Context, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
|
||||
container.Lock()
|
||||
|
||||
defer func() {
|
||||
@@ -171,7 +172,7 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
|
||||
}
|
||||
}()
|
||||
|
||||
if err = container.Mount(); err != nil {
|
||||
if err = container.Mount(ctx); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@@ -180,7 +181,7 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
|
||||
// unmount any volumes
|
||||
container.unmountVolumes(true)
|
||||
// unmount the container's rootfs
|
||||
container.Unmount()
|
||||
container.Unmount(ctx)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -214,12 +215,12 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
|
||||
content = ioutils.NewReadCloserWrapper(data, func() error {
|
||||
err := data.Close()
|
||||
container.unmountVolumes(true)
|
||||
container.Unmount()
|
||||
container.Unmount(ctx)
|
||||
container.Unlock()
|
||||
return err
|
||||
})
|
||||
|
||||
container.logEvent("archive-path")
|
||||
container.logEvent(ctx, "archive-path")
|
||||
|
||||
return content, stat, nil
|
||||
}
|
||||
@@ -230,14 +231,14 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
|
||||
// noOverwriteDirNonDir is true then it will be an error if unpacking the
|
||||
// given content would cause an existing directory to be replaced with a non-
|
||||
// directory and vice versa.
|
||||
func (container *Container) ExtractToDir(path string, noOverwriteDirNonDir bool, content io.Reader) (err error) {
|
||||
func (container *Container) ExtractToDir(ctx context.Context, path string, noOverwriteDirNonDir bool, content io.Reader) (err error) {
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
if err = container.Mount(); err != nil {
|
||||
if err = container.Mount(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
defer container.Unmount()
|
||||
defer container.Unmount(ctx)
|
||||
|
||||
err = container.mountVolumes()
|
||||
defer container.unmountVolumes(true)
|
||||
@@ -318,7 +319,7 @@ func (container *Container) ExtractToDir(path string, noOverwriteDirNonDir bool,
|
||||
return err
|
||||
}
|
||||
|
||||
container.logEvent("extract-to-dir")
|
||||
container.logEvent(ctx, "extract-to-dir")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package daemon
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
)
|
||||
|
||||
@@ -15,8 +16,8 @@ type ContainerAttachWithLogsConfig struct {
|
||||
}
|
||||
|
||||
// ContainerAttachWithLogs attaches to logs according to the config passed in. See ContainerAttachWithLogsConfig.
|
||||
func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerAttachWithLogsConfig) error {
|
||||
container, err := daemon.Get(prefixOrName)
|
||||
func (daemon *Daemon) ContainerAttachWithLogs(ctx context.Context, prefixOrName string, c *ContainerAttachWithLogsConfig) error {
|
||||
container, err := daemon.Get(ctx, prefixOrName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -43,7 +44,7 @@ func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerA
|
||||
stderr = errStream
|
||||
}
|
||||
|
||||
return container.attachWithLogs(stdin, stdout, stderr, c.Logs, c.Stream)
|
||||
return container.attachWithLogs(ctx, stdin, stdout, stderr, c.Logs, c.Stream)
|
||||
}
|
||||
|
||||
// ContainerWsAttachWithLogsConfig attach with websockets, since all
|
||||
@@ -55,10 +56,10 @@ type ContainerWsAttachWithLogsConfig struct {
|
||||
}
|
||||
|
||||
// ContainerWsAttachWithLogs websocket connection
|
||||
func (daemon *Daemon) ContainerWsAttachWithLogs(prefixOrName string, c *ContainerWsAttachWithLogsConfig) error {
|
||||
container, err := daemon.Get(prefixOrName)
|
||||
func (daemon *Daemon) ContainerWsAttachWithLogs(ctx context.Context, prefixOrName string, c *ContainerWsAttachWithLogsConfig) error {
|
||||
container, err := daemon.Get(ctx, prefixOrName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return container.attachWithLogs(c.InStream, c.OutStream, c.ErrStream, c.Logs, c.Stream)
|
||||
return container.attachWithLogs(ctx, c.InStream, c.OutStream, c.ErrStream, c.Logs, c.Stream)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package daemon
|
||||
|
||||
import "github.com/docker/docker/pkg/archive"
|
||||
import (
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
)
|
||||
|
||||
// ContainerChanges returns a list of container fs changes
|
||||
func (daemon *Daemon) ContainerChanges(name string) ([]archive.Change, error) {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerChanges(ctx context.Context, name string) ([]archive.Change, error) {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/runconfig"
|
||||
)
|
||||
@@ -18,10 +19,10 @@ type ContainerCommitConfig struct {
|
||||
|
||||
// Commit creates a new filesystem image from the current state of a container.
|
||||
// The image can optionally be tagged into a repository.
|
||||
func (daemon *Daemon) Commit(container *Container, c *ContainerCommitConfig) (*image.Image, error) {
|
||||
func (daemon *Daemon) Commit(ctx context.Context, container *Container, c *ContainerCommitConfig) (*image.Image, error) {
|
||||
if c.Pause && !container.isPaused() {
|
||||
container.pause()
|
||||
defer container.unpause()
|
||||
container.pause(ctx)
|
||||
defer container.unpause(ctx)
|
||||
}
|
||||
|
||||
rwTar, err := container.exportContainerRw()
|
||||
@@ -46,6 +47,6 @@ func (daemon *Daemon) Commit(container *Container, c *ContainerCommitConfig) (*i
|
||||
return img, err
|
||||
}
|
||||
}
|
||||
container.logEvent("commit")
|
||||
container.logEvent(ctx, "commit")
|
||||
return img, nil
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/daemon/logger"
|
||||
"github.com/docker/docker/daemon/logger/jsonfilelog"
|
||||
@@ -170,9 +171,10 @@ func (container *Container) writeHostConfig() error {
|
||||
return ioutil.WriteFile(pth, data, 0666)
|
||||
}
|
||||
|
||||
func (container *Container) logEvent(action string) {
|
||||
func (container *Container) logEvent(ctx context.Context, action string) {
|
||||
d := container.daemon
|
||||
d.EventsService.Log(
|
||||
ctx,
|
||||
action,
|
||||
container.ID,
|
||||
container.Config.Image,
|
||||
@@ -238,7 +240,7 @@ func (container *Container) exportContainerRw() (archive.Archive, error) {
|
||||
// container needs, such as storage and networking, as well as links
|
||||
// between containers. The container is left waiting for a signal to
|
||||
// begin running.
|
||||
func (container *Container) Start() (err error) {
|
||||
func (container *Container) Start(ctx context.Context) (err error) {
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
@@ -260,12 +262,12 @@ func (container *Container) Start() (err error) {
|
||||
container.ExitCode = 128
|
||||
}
|
||||
container.toDisk()
|
||||
container.cleanup()
|
||||
container.logEvent("die")
|
||||
container.cleanup(ctx)
|
||||
container.logEvent(ctx, "die")
|
||||
}
|
||||
}()
|
||||
|
||||
if err := container.Mount(); err != nil {
|
||||
if err := container.Mount(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -273,10 +275,10 @@ func (container *Container) Start() (err error) {
|
||||
// backwards API compatibility.
|
||||
container.hostConfig = runconfig.SetDefaultNetModeIfBlank(container.hostConfig)
|
||||
|
||||
if err := container.initializeNetworking(); err != nil {
|
||||
if err := container.initializeNetworking(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
linkedEnv, err := container.setupLinkedContainers()
|
||||
linkedEnv, err := container.setupLinkedContainers(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -284,7 +286,7 @@ func (container *Container) Start() (err error) {
|
||||
return err
|
||||
}
|
||||
env := container.createDaemonEnvironment(linkedEnv)
|
||||
if err := populateCommand(container, env); err != nil {
|
||||
if err := populateCommand(ctx, container, env); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -301,7 +303,7 @@ func (container *Container) Start() (err error) {
|
||||
mounts = append(mounts, container.ipcMounts()...)
|
||||
|
||||
container.command.Mounts = mounts
|
||||
return container.waitForStart()
|
||||
return container.waitForStart(ctx)
|
||||
}
|
||||
|
||||
// streamConfig.StdinPipe returns a WriteCloser which can be used to feed data
|
||||
@@ -334,14 +336,14 @@ func (container *Container) isNetworkAllocated() bool {
|
||||
|
||||
// cleanup releases any network resources allocated to the container along with any rules
|
||||
// around how containers are linked together. It also unmounts the container's root filesystem.
|
||||
func (container *Container) cleanup() {
|
||||
func (container *Container) cleanup(ctx context.Context) {
|
||||
container.releaseNetwork()
|
||||
|
||||
if err := container.unmountIpcMounts(); err != nil {
|
||||
logrus.Errorf("%s: Failed to umount ipc filesystems: %v", container.ID, err)
|
||||
}
|
||||
|
||||
if err := container.Unmount(); err != nil {
|
||||
if err := container.Unmount(ctx); err != nil {
|
||||
logrus.Errorf("%s: Failed to umount filesystem: %v", container.ID, err)
|
||||
}
|
||||
|
||||
@@ -357,7 +359,7 @@ func (container *Container) cleanup() {
|
||||
// to send the signal. An error is returned if the container is paused
|
||||
// or not running, or if there is a problem returned from the
|
||||
// underlying kill command.
|
||||
func (container *Container) killSig(sig int) error {
|
||||
func (container *Container) killSig(ctx context.Context, sig int) error {
|
||||
logrus.Debugf("Sending %d to %s", sig, container.ID)
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
@@ -385,13 +387,13 @@ func (container *Container) killSig(sig int) error {
|
||||
if err := container.daemon.kill(container, sig); err != nil {
|
||||
return err
|
||||
}
|
||||
container.logEvent("kill")
|
||||
container.logEvent(ctx, "kill")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Wrapper aroung killSig() suppressing "no such process" error.
|
||||
func (container *Container) killPossiblyDeadProcess(sig int) error {
|
||||
err := container.killSig(sig)
|
||||
func (container *Container) killPossiblyDeadProcess(ctx context.Context, sig int) error {
|
||||
err := container.killSig(ctx, sig)
|
||||
if err == syscall.ESRCH {
|
||||
logrus.Debugf("Cannot kill process (pid=%d) with signal %d: no such process.", container.getPID(), sig)
|
||||
return nil
|
||||
@@ -399,7 +401,7 @@ func (container *Container) killPossiblyDeadProcess(sig int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (container *Container) pause() error {
|
||||
func (container *Container) pause(ctx context.Context) error {
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
@@ -417,11 +419,11 @@ func (container *Container) pause() error {
|
||||
return err
|
||||
}
|
||||
container.Paused = true
|
||||
container.logEvent("pause")
|
||||
container.logEvent(ctx, "pause")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) unpause() error {
|
||||
func (container *Container) unpause(ctx context.Context) error {
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
@@ -439,18 +441,18 @@ func (container *Container) unpause() error {
|
||||
return err
|
||||
}
|
||||
container.Paused = false
|
||||
container.logEvent("unpause")
|
||||
container.logEvent(ctx, "unpause")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Kill forcefully terminates a container.
|
||||
func (container *Container) Kill() error {
|
||||
func (container *Container) Kill(ctx context.Context) error {
|
||||
if !container.IsRunning() {
|
||||
return derr.ErrorCodeNotRunning.WithArgs(container.ID)
|
||||
}
|
||||
|
||||
// 1. Send SIGKILL
|
||||
if err := container.killPossiblyDeadProcess(int(syscall.SIGKILL)); err != nil {
|
||||
if err := container.killPossiblyDeadProcess(ctx, int(syscall.SIGKILL)); err != nil {
|
||||
// While normally we might "return err" here we're not going to
|
||||
// because if we can't stop the container by this point then
|
||||
// its probably because its already stopped. Meaning, between
|
||||
@@ -484,15 +486,15 @@ func (container *Container) Kill() error {
|
||||
// process to exit. If a negative duration is given, Stop will wait
|
||||
// for the initial signal forever. If the container is not running Stop returns
|
||||
// immediately.
|
||||
func (container *Container) Stop(seconds int) error {
|
||||
func (container *Container) Stop(ctx context.Context, seconds int) error {
|
||||
if !container.IsRunning() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 1. Send a SIGTERM
|
||||
if err := container.killPossiblyDeadProcess(container.stopSignal()); err != nil {
|
||||
if err := container.killPossiblyDeadProcess(ctx, container.stopSignal()); err != nil {
|
||||
logrus.Infof("Failed to send SIGTERM to the process, force killing")
|
||||
if err := container.killPossiblyDeadProcess(9); err != nil {
|
||||
if err := container.killPossiblyDeadProcess(ctx, 9); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -501,13 +503,13 @@ func (container *Container) Stop(seconds int) error {
|
||||
if _, err := container.WaitStop(time.Duration(seconds) * time.Second); err != nil {
|
||||
logrus.Infof("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.ID, seconds)
|
||||
// 3. If it doesn't, then send SIGKILL
|
||||
if err := container.Kill(); err != nil {
|
||||
if err := container.Kill(ctx); err != nil {
|
||||
container.WaitStop(-1 * time.Second)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
container.logEvent("stop")
|
||||
container.logEvent(ctx, "stop")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -515,61 +517,61 @@ func (container *Container) Stop(seconds int) error {
|
||||
// container. When stopping, wait for the given duration in seconds to
|
||||
// gracefully stop, before forcefully terminating the container. If
|
||||
// given a negative duration, wait forever for a graceful stop.
|
||||
func (container *Container) Restart(seconds int) error {
|
||||
func (container *Container) Restart(ctx context.Context, seconds int) error {
|
||||
// Avoid unnecessarily unmounting and then directly mounting
|
||||
// the container when the container stops and then starts
|
||||
// again
|
||||
if err := container.Mount(); err == nil {
|
||||
defer container.Unmount()
|
||||
if err := container.Mount(ctx); err == nil {
|
||||
defer container.Unmount(ctx)
|
||||
}
|
||||
|
||||
if err := container.Stop(seconds); err != nil {
|
||||
if err := container.Stop(ctx, seconds); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := container.Start(); err != nil {
|
||||
if err := container.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container.logEvent("restart")
|
||||
container.logEvent(ctx, "restart")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resize changes the TTY of the process running inside the container
|
||||
// to the given height and width. The container must be running.
|
||||
func (container *Container) Resize(h, w int) error {
|
||||
func (container *Container) Resize(ctx context.Context, h, w int) error {
|
||||
if !container.IsRunning() {
|
||||
return derr.ErrorCodeNotRunning.WithArgs(container.ID)
|
||||
}
|
||||
if err := container.command.ProcessConfig.Terminal.Resize(h, w); err != nil {
|
||||
return err
|
||||
}
|
||||
container.logEvent("resize")
|
||||
container.logEvent(ctx, "resize")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) export() (archive.Archive, error) {
|
||||
if err := container.Mount(); err != nil {
|
||||
func (container *Container) export(ctx context.Context) (archive.Archive, error) {
|
||||
if err := container.Mount(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
archive, err := archive.Tar(container.basefs, archive.Uncompressed)
|
||||
if err != nil {
|
||||
container.Unmount()
|
||||
container.Unmount(ctx)
|
||||
return nil, err
|
||||
}
|
||||
arch := ioutils.NewReadCloserWrapper(archive, func() error {
|
||||
err := archive.Close()
|
||||
container.Unmount()
|
||||
container.Unmount(ctx)
|
||||
return err
|
||||
})
|
||||
container.logEvent("export")
|
||||
container.logEvent(ctx, "export")
|
||||
return arch, err
|
||||
}
|
||||
|
||||
// Mount sets container.basefs
|
||||
func (container *Container) Mount() error {
|
||||
return container.daemon.Mount(container)
|
||||
func (container *Container) Mount(ctx context.Context) error {
|
||||
return container.daemon.Mount(ctx, container)
|
||||
}
|
||||
|
||||
func (container *Container) changes() ([]archive.Change, error) {
|
||||
@@ -578,7 +580,7 @@ func (container *Container) changes() ([]archive.Change, error) {
|
||||
return container.daemon.changes(container)
|
||||
}
|
||||
|
||||
func (container *Container) getImage() (*image.Image, error) {
|
||||
func (container *Container) getImage(ctx context.Context) (*image.Image, error) {
|
||||
if container.daemon == nil {
|
||||
return nil, derr.ErrorCodeImageUnregContainer
|
||||
}
|
||||
@@ -587,7 +589,7 @@ func (container *Container) getImage() (*image.Image, error) {
|
||||
|
||||
// Unmount asks the daemon to release the layered filesystems that are
|
||||
// mounted by the container.
|
||||
func (container *Container) Unmount() error {
|
||||
func (container *Container) Unmount(ctx context.Context) error {
|
||||
return container.daemon.unmount(container)
|
||||
}
|
||||
|
||||
@@ -612,7 +614,7 @@ func validateID(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) copy(resource string) (rc io.ReadCloser, err error) {
|
||||
func (container *Container) copy(ctx context.Context, resource string) (rc io.ReadCloser, err error) {
|
||||
container.Lock()
|
||||
|
||||
defer func() {
|
||||
@@ -624,7 +626,7 @@ func (container *Container) copy(resource string) (rc io.ReadCloser, err error)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := container.Mount(); err != nil {
|
||||
if err := container.Mount(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -633,7 +635,7 @@ func (container *Container) copy(resource string) (rc io.ReadCloser, err error)
|
||||
// unmount any volumes
|
||||
container.unmountVolumes(true)
|
||||
// unmount the container's rootfs
|
||||
container.Unmount()
|
||||
container.Unmount(ctx)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -669,11 +671,11 @@ func (container *Container) copy(resource string) (rc io.ReadCloser, err error)
|
||||
reader := ioutils.NewReadCloserWrapper(archive, func() error {
|
||||
err := archive.Close()
|
||||
container.unmountVolumes(true)
|
||||
container.Unmount()
|
||||
container.Unmount(ctx)
|
||||
container.Unlock()
|
||||
return err
|
||||
})
|
||||
container.logEvent("copy")
|
||||
container.logEvent(ctx, "copy")
|
||||
return reader, nil
|
||||
}
|
||||
|
||||
@@ -752,14 +754,14 @@ func (container *Container) startLogging() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) waitForStart() error {
|
||||
func (container *Container) waitForStart(ctx context.Context) error {
|
||||
container.monitor = newContainerMonitor(container, container.hostConfig.RestartPolicy)
|
||||
|
||||
// block until we either receive an error from the initial start of the container's
|
||||
// process or until the process is running in the container
|
||||
select {
|
||||
case <-container.monitor.startSignal:
|
||||
case err := <-promise.Go(container.monitor.Start):
|
||||
case err := <-promise.Go(func() error { return container.monitor.Start(ctx) }):
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -790,11 +792,11 @@ func (container *Container) getExecIDs() []string {
|
||||
return container.execCommands.List()
|
||||
}
|
||||
|
||||
func (container *Container) exec(ExecConfig *ExecConfig) error {
|
||||
func (container *Container) exec(ctx context.Context, ExecConfig *ExecConfig) error {
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
callback := func(processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
|
||||
callback := func(ctx context.Context, processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
|
||||
if processConfig.Tty {
|
||||
// The callback is called after the process Start()
|
||||
// so we are in the parent process. In TTY mode, stdin/out/err is the PtySlave
|
||||
@@ -809,7 +811,7 @@ func (container *Container) exec(ExecConfig *ExecConfig) error {
|
||||
|
||||
// We use a callback here instead of a goroutine and an chan for
|
||||
// synchronization purposes
|
||||
cErr := promise.Go(func() error { return container.monitorExec(ExecConfig, callback) })
|
||||
cErr := promise.Go(func() error { return container.monitorExec(ctx, ExecConfig, callback) })
|
||||
|
||||
// Exec should not return until the process is actually running
|
||||
select {
|
||||
@@ -821,13 +823,13 @@ func (container *Container) exec(ExecConfig *ExecConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) monitorExec(ExecConfig *ExecConfig, callback execdriver.DriverCallback) error {
|
||||
func (container *Container) monitorExec(ctx context.Context, ExecConfig *ExecConfig, callback execdriver.DriverCallback) error {
|
||||
var (
|
||||
err error
|
||||
exitCode int
|
||||
)
|
||||
pipes := execdriver.NewPipes(ExecConfig.streamConfig.stdin, ExecConfig.streamConfig.stdout, ExecConfig.streamConfig.stderr, ExecConfig.OpenStdin)
|
||||
exitCode, err = container.daemon.Exec(container, ExecConfig, pipes, callback)
|
||||
exitCode, err = container.daemon.Exec(ctx, container, ExecConfig, pipes, callback)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error running command in existing container %s: %s", container.ID, err)
|
||||
}
|
||||
@@ -860,7 +862,7 @@ func (container *Container) Attach(stdin io.ReadCloser, stdout io.Writer, stderr
|
||||
return attach(&container.streamConfig, container.Config.OpenStdin, container.Config.StdinOnce, container.Config.Tty, stdin, stdout, stderr)
|
||||
}
|
||||
|
||||
func (container *Container) attachWithLogs(stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error {
|
||||
func (container *Container) attachWithLogs(ctx context.Context, stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error {
|
||||
if logs {
|
||||
logDriver, err := container.getLogger()
|
||||
if err != nil {
|
||||
@@ -892,7 +894,7 @@ func (container *Container) attachWithLogs(stdin io.ReadCloser, stdout, stderr i
|
||||
}
|
||||
}
|
||||
|
||||
container.logEvent("attach")
|
||||
container.logEvent(ctx, "attach")
|
||||
|
||||
//stream
|
||||
if stream {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/daemon/links"
|
||||
"github.com/docker/docker/daemon/network"
|
||||
@@ -77,12 +78,12 @@ func killProcessDirectly(container *Container) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) setupLinkedContainers() ([]string, error) {
|
||||
func (container *Container) setupLinkedContainers(ctx context.Context) ([]string, error) {
|
||||
var (
|
||||
env []string
|
||||
daemon = container.daemon
|
||||
)
|
||||
children, err := daemon.children(container.Name)
|
||||
children, err := daemon.children(ctx, container.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -175,7 +176,7 @@ func getDevicesFromPath(deviceMapping runconfig.DeviceMapping) (devs []*configs.
|
||||
return devs, derr.ErrorCodeDeviceInfo.WithArgs(deviceMapping.PathOnHost, err)
|
||||
}
|
||||
|
||||
func populateCommand(c *Container, env []string) error {
|
||||
func populateCommand(ctx context.Context, c *Container, env []string) error {
|
||||
var en *execdriver.Network
|
||||
if !c.Config.NetworkDisabled {
|
||||
en = &execdriver.Network{}
|
||||
@@ -185,7 +186,7 @@ func populateCommand(c *Container, env []string) error {
|
||||
|
||||
parts := strings.SplitN(string(c.hostConfig.NetworkMode), ":", 2)
|
||||
if parts[0] == "container" {
|
||||
nc, err := c.getNetworkedContainer()
|
||||
nc, err := c.getNetworkedContainer(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -206,7 +207,7 @@ func populateCommand(c *Container, env []string) error {
|
||||
}
|
||||
|
||||
if c.hostConfig.IpcMode.IsContainer() {
|
||||
ic, err := c.getIpcContainer()
|
||||
ic, err := c.getIpcContainer(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -349,18 +350,18 @@ func mergeDevices(defaultDevices, userDevices []*configs.Device) []*configs.Devi
|
||||
}
|
||||
|
||||
// GetSize returns the real size & virtual size of the container.
|
||||
func (container *Container) getSize() (int64, int64) {
|
||||
func (container *Container) getSize(ctx context.Context) (int64, int64) {
|
||||
var (
|
||||
sizeRw, sizeRootfs int64
|
||||
err error
|
||||
driver = container.daemon.driver
|
||||
)
|
||||
|
||||
if err := container.Mount(); err != nil {
|
||||
if err := container.Mount(ctx); err != nil {
|
||||
logrus.Errorf("Failed to compute size of container rootfs %s: %s", container.ID, err)
|
||||
return sizeRw, sizeRootfs
|
||||
}
|
||||
defer container.Unmount()
|
||||
defer container.Unmount(ctx)
|
||||
|
||||
initID := fmt.Sprintf("%s-init", container.ID)
|
||||
sizeRw, err = driver.DiffSize(container.ID, initID)
|
||||
@@ -412,7 +413,7 @@ func (container *Container) buildHostnameFile() error {
|
||||
return ioutil.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644)
|
||||
}
|
||||
|
||||
func (container *Container) buildSandboxOptions() ([]libnetwork.SandboxOption, error) {
|
||||
func (container *Container) buildSandboxOptions(ctx context.Context) ([]libnetwork.SandboxOption, error) {
|
||||
var (
|
||||
sboxOptions []libnetwork.SandboxOption
|
||||
err error
|
||||
@@ -489,7 +490,7 @@ func (container *Container) buildSandboxOptions() ([]libnetwork.SandboxOption, e
|
||||
|
||||
var childEndpoints, parentEndpoints []string
|
||||
|
||||
children, err := container.daemon.children(container.Name)
|
||||
children, err := container.daemon.children(ctx, container.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -520,7 +521,7 @@ func (container *Container) buildSandboxOptions() ([]libnetwork.SandboxOption, e
|
||||
continue
|
||||
}
|
||||
|
||||
c, err := container.daemon.Get(ref.ParentID)
|
||||
c, err := container.daemon.Get(ctx, ref.ParentID)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
@@ -679,7 +680,7 @@ func (container *Container) updateSandboxNetworkSettings(sb libnetwork.Sandbox)
|
||||
|
||||
// UpdateNetwork is used to update the container's network (e.g. when linked containers
|
||||
// get removed/unlinked).
|
||||
func (container *Container) updateNetwork() error {
|
||||
func (container *Container) updateNetwork(ctx context.Context) error {
|
||||
ctrl := container.daemon.netController
|
||||
sid := container.NetworkSettings.SandboxID
|
||||
|
||||
@@ -688,7 +689,7 @@ func (container *Container) updateNetwork() error {
|
||||
return derr.ErrorCodeNoSandbox.WithArgs(sid, err)
|
||||
}
|
||||
|
||||
options, err := container.buildSandboxOptions()
|
||||
options, err := container.buildSandboxOptions(ctx)
|
||||
if err != nil {
|
||||
return derr.ErrorCodeNetworkUpdate.WithArgs(err)
|
||||
}
|
||||
@@ -812,7 +813,7 @@ func createNetwork(controller libnetwork.NetworkController, dnet string, driver
|
||||
return controller.NewNetwork(driver, dnet, createOptions...)
|
||||
}
|
||||
|
||||
func (container *Container) secondaryNetworkRequired(primaryNetworkType string) bool {
|
||||
func (container *Container) secondaryNetworkRequired(ctx context.Context, primaryNetworkType string) bool {
|
||||
switch primaryNetworkType {
|
||||
case "bridge", "none", "host", "container":
|
||||
return false
|
||||
@@ -831,7 +832,7 @@ func (container *Container) secondaryNetworkRequired(primaryNetworkType string)
|
||||
return false
|
||||
}
|
||||
|
||||
func (container *Container) allocateNetwork() error {
|
||||
func (container *Container) allocateNetwork(ctx context.Context) error {
|
||||
mode := container.hostConfig.NetworkMode
|
||||
controller := container.daemon.netController
|
||||
if container.Config.NetworkDisabled || mode.IsContainer() {
|
||||
@@ -865,21 +866,21 @@ func (container *Container) allocateNetwork() error {
|
||||
service = strings.Replace(service, "/", "", -1)
|
||||
}
|
||||
|
||||
if container.secondaryNetworkRequired(networkDriver) {
|
||||
if container.secondaryNetworkRequired(ctx, networkDriver) {
|
||||
// Configure Bridge as secondary network for port binding purposes
|
||||
if err := container.configureNetwork("bridge", service, "bridge", false); err != nil {
|
||||
if err := container.configureNetwork(ctx, "bridge", service, "bridge", false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := container.configureNetwork(networkName, service, networkDriver, mode.IsDefault()); err != nil {
|
||||
if err := container.configureNetwork(ctx, networkName, service, networkDriver, mode.IsDefault()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return container.writeHostConfig()
|
||||
}
|
||||
|
||||
func (container *Container) configureNetwork(networkName, service, networkDriver string, canCreateNetwork bool) error {
|
||||
func (container *Container) configureNetwork(ctx context.Context, networkName, service, networkDriver string, canCreateNetwork bool) error {
|
||||
controller := container.daemon.netController
|
||||
|
||||
n, err := controller.NetworkByName(networkName)
|
||||
@@ -923,7 +924,7 @@ func (container *Container) configureNetwork(networkName, service, networkDriver
|
||||
return false
|
||||
})
|
||||
if sb == nil {
|
||||
options, err := container.buildSandboxOptions()
|
||||
options, err := container.buildSandboxOptions(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -946,12 +947,12 @@ func (container *Container) configureNetwork(networkName, service, networkDriver
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) initializeNetworking() error {
|
||||
func (container *Container) initializeNetworking(ctx context.Context) error {
|
||||
var err error
|
||||
|
||||
if container.hostConfig.NetworkMode.IsContainer() {
|
||||
// we need to get the hosts files from the container to join
|
||||
nc, err := container.getNetworkedContainer()
|
||||
nc, err := container.getNetworkedContainer(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -977,7 +978,7 @@ func (container *Container) initializeNetworking() error {
|
||||
|
||||
}
|
||||
|
||||
if err := container.allocateNetwork(); err != nil {
|
||||
if err := container.allocateNetwork(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -998,9 +999,9 @@ func (container *Container) setNetworkNamespaceKey(pid int) error {
|
||||
return sandbox.SetKey(path)
|
||||
}
|
||||
|
||||
func (container *Container) getIpcContainer() (*Container, error) {
|
||||
func (container *Container) getIpcContainer(ctx context.Context) (*Container, error) {
|
||||
containerID := container.hostConfig.IpcMode.Container()
|
||||
c, err := container.daemon.Get(containerID)
|
||||
c, err := container.daemon.Get(ctx, containerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1036,14 +1037,14 @@ func (container *Container) setupWorkingDirectory() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) getNetworkedContainer() (*Container, error) {
|
||||
func (container *Container) getNetworkedContainer(ctx context.Context) (*Container, error) {
|
||||
parts := strings.SplitN(string(container.hostConfig.NetworkMode), ":", 2)
|
||||
switch parts[0] {
|
||||
case "container":
|
||||
if len(parts) != 2 {
|
||||
return nil, derr.ErrorCodeParseContainer
|
||||
}
|
||||
nc, err := container.daemon.Get(parts[1])
|
||||
nc, err := container.daemon.Get(ctx, parts[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ package daemon
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
derr "github.com/docker/docker/errors"
|
||||
)
|
||||
@@ -25,7 +26,7 @@ func killProcessDirectly(container *Container) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) setupLinkedContainers() ([]string, error) {
|
||||
func (container *Container) setupLinkedContainers(ctx context.Context) ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -34,7 +35,7 @@ func (container *Container) createDaemonEnvironment(linkedEnv []string) []string
|
||||
return container.Config.Env
|
||||
}
|
||||
|
||||
func (container *Container) initializeNetworking() error {
|
||||
func (container *Container) initializeNetworking(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -42,7 +43,7 @@ func (container *Container) setupWorkingDirectory() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func populateCommand(c *Container, env []string) error {
|
||||
func populateCommand(ctx context.Context, c *Container, env []string) error {
|
||||
en := &execdriver.Network{
|
||||
Interface: nil,
|
||||
}
|
||||
@@ -135,7 +136,7 @@ func populateCommand(c *Container, env []string) error {
|
||||
}
|
||||
|
||||
// GetSize returns real size & virtual size
|
||||
func (container *Container) getSize() (int64, int64) {
|
||||
func (container *Container) getSize(ctx context.Context) (int64, int64) {
|
||||
// TODO Windows
|
||||
return 0, 0
|
||||
}
|
||||
@@ -150,7 +151,7 @@ func (container *Container) allocateNetwork() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (container *Container) updateNetwork() error {
|
||||
func (container *Container) updateNetwork(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/graph/tags"
|
||||
"github.com/docker/docker/image"
|
||||
@@ -15,21 +16,21 @@ import (
|
||||
)
|
||||
|
||||
// ContainerCreate takes configs and creates a container.
|
||||
func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hostConfig *runconfig.HostConfig, adjustCPUShares bool) (*Container, []string, error) {
|
||||
func (daemon *Daemon) ContainerCreate(ctx context.Context, name string, config *runconfig.Config, hostConfig *runconfig.HostConfig, adjustCPUShares bool) (*Container, []string, error) {
|
||||
if config == nil {
|
||||
return nil, nil, derr.ErrorCodeEmptyConfig
|
||||
}
|
||||
|
||||
warnings, err := daemon.verifyContainerSettings(hostConfig, config)
|
||||
warnings, err := daemon.verifyContainerSettings(ctx, hostConfig, config)
|
||||
if err != nil {
|
||||
return nil, warnings, err
|
||||
}
|
||||
|
||||
daemon.adaptContainerSettings(hostConfig, adjustCPUShares)
|
||||
|
||||
container, buildWarnings, err := daemon.Create(config, hostConfig, name)
|
||||
container, buildWarnings, err := daemon.Create(ctx, config, hostConfig, name)
|
||||
if err != nil {
|
||||
if daemon.Graph().IsNotExist(err, config.Image) {
|
||||
if daemon.Graph(ctx).IsNotExist(err, config.Image) {
|
||||
if strings.Contains(config.Image, "@") {
|
||||
return nil, warnings, derr.ErrorCodeNoSuchImageHash.WithArgs(config.Image)
|
||||
}
|
||||
@@ -48,7 +49,7 @@ func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hos
|
||||
}
|
||||
|
||||
// Create creates a new container from the given configuration with a given name.
|
||||
func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.HostConfig, name string) (retC *Container, retS []string, retErr error) {
|
||||
func (daemon *Daemon) Create(ctx context.Context, config *runconfig.Config, hostConfig *runconfig.HostConfig, name string) (retC *Container, retS []string, retErr error) {
|
||||
var (
|
||||
container *Container
|
||||
warnings []string
|
||||
@@ -76,29 +77,29 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
|
||||
hostConfig = &runconfig.HostConfig{}
|
||||
}
|
||||
if hostConfig.SecurityOpt == nil {
|
||||
hostConfig.SecurityOpt, err = daemon.generateSecurityOpt(hostConfig.IpcMode, hostConfig.PidMode)
|
||||
hostConfig.SecurityOpt, err = daemon.generateSecurityOpt(ctx, hostConfig.IpcMode, hostConfig.PidMode)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
if container, err = daemon.newContainer(name, config, imgID); err != nil {
|
||||
if container, err = daemon.newContainer(ctx, name, config, imgID); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
if err := daemon.rm(container, false); err != nil {
|
||||
if err := daemon.rm(ctx, container, false); err != nil {
|
||||
logrus.Errorf("Clean up Error! Cannot destroy container %s: %v", container.ID, err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err := daemon.Register(container); err != nil {
|
||||
if err := daemon.Register(ctx, container); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := daemon.createRootfs(container); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := daemon.setHostConfig(container, hostConfig); err != nil {
|
||||
if err := daemon.setHostConfig(ctx, container, hostConfig); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer func() {
|
||||
@@ -108,10 +109,10 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
|
||||
}
|
||||
}
|
||||
}()
|
||||
if err := container.Mount(); err != nil {
|
||||
if err := container.Mount(ctx); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer container.Unmount()
|
||||
defer container.Unmount(ctx)
|
||||
|
||||
if err := createContainerPlatformSpecificSettings(container, config, hostConfig, img); err != nil {
|
||||
return nil, nil, err
|
||||
@@ -121,16 +122,16 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
|
||||
logrus.Errorf("Error saving new container to disk: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
container.logEvent("create")
|
||||
container.logEvent(ctx, "create")
|
||||
return container, warnings, nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) generateSecurityOpt(ipcMode runconfig.IpcMode, pidMode runconfig.PidMode) ([]string, error) {
|
||||
func (daemon *Daemon) generateSecurityOpt(ctx context.Context, ipcMode runconfig.IpcMode, pidMode runconfig.PidMode) ([]string, error) {
|
||||
if ipcMode.IsHost() || pidMode.IsHost() {
|
||||
return label.DisableSecOpt(), nil
|
||||
}
|
||||
if ipcContainer := ipcMode.Container(); ipcContainer != "" {
|
||||
c, err := daemon.Get(ipcContainer)
|
||||
c, err := daemon.Get(ctx, ipcContainer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -142,7 +143,7 @@ func (daemon *Daemon) generateSecurityOpt(ipcMode runconfig.IpcMode, pidMode run
|
||||
|
||||
// VolumeCreate creates a volume with the specified name, driver, and opts
|
||||
// This is called directly from the remote API
|
||||
func (daemon *Daemon) VolumeCreate(name, driverName string, opts map[string]string) (*types.Volume, error) {
|
||||
func (daemon *Daemon) VolumeCreate(ctx context.Context, name, driverName string, opts map[string]string) (*types.Volume, error) {
|
||||
if name == "" {
|
||||
name = stringid.GenerateNonCryptoID()
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/events"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/daemon/execdriver/execdrivers"
|
||||
@@ -127,14 +128,14 @@ type Daemon struct {
|
||||
// - 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) Get(prefixOrName string) (*Container, error) {
|
||||
func (daemon *Daemon) Get(ctx context.Context, prefixOrName string) (*Container, error) {
|
||||
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 {
|
||||
if containerByName, _ := daemon.GetByName(ctx, prefixOrName); containerByName != nil {
|
||||
// prefix is an exact match to a full container Name
|
||||
return containerByName, nil
|
||||
}
|
||||
@@ -152,8 +153,8 @@ func (daemon *Daemon) Get(prefixOrName string) (*Container, error) {
|
||||
|
||||
// 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.Get(id)
|
||||
func (daemon *Daemon) Exists(ctx context.Context, id string) bool {
|
||||
c, _ := daemon.Get(ctx, id)
|
||||
return c != nil
|
||||
}
|
||||
|
||||
@@ -178,8 +179,8 @@ func (daemon *Daemon) load(id string) (*Container, error) {
|
||||
}
|
||||
|
||||
// Register makes a container object usable by the daemon as <container.ID>
|
||||
func (daemon *Daemon) Register(container *Container) error {
|
||||
if container.daemon != nil || daemon.Exists(container.ID) {
|
||||
func (daemon *Daemon) Register(ctx context.Context, container *Container) error {
|
||||
if container.daemon != nil || daemon.Exists(ctx, container.ID) {
|
||||
return fmt.Errorf("Container is already loaded")
|
||||
}
|
||||
if err := validateID(container.ID); err != nil {
|
||||
@@ -217,10 +218,7 @@ func (daemon *Daemon) Register(container *Container) error {
|
||||
}
|
||||
daemon.execDriver.Terminate(cmd)
|
||||
|
||||
if err := container.unmountIpcMounts(); err != nil {
|
||||
logrus.Errorf("%s: Failed to umount ipc filesystems: %v", container.ID, err)
|
||||
}
|
||||
if err := container.Unmount(); err != nil {
|
||||
if err := container.Unmount(ctx); err != nil {
|
||||
logrus.Debugf("unmount error %s", err)
|
||||
}
|
||||
if err := container.toDiskLocking(); err != nil {
|
||||
@@ -254,7 +252,7 @@ func (daemon *Daemon) ensureName(container *Container) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) restore() error {
|
||||
func (daemon *Daemon) restore(ctx context.Context) error {
|
||||
type cr struct {
|
||||
container *Container
|
||||
registered bool
|
||||
@@ -324,7 +322,7 @@ func (daemon *Daemon) restore() error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := daemon.Register(container); err != nil {
|
||||
if err := daemon.Register(ctx, container); err != nil {
|
||||
logrus.Errorf("Failed to register container %s: %s", container.ID, err)
|
||||
// The container register failed should not be started.
|
||||
return
|
||||
@@ -335,7 +333,7 @@ func (daemon *Daemon) restore() error {
|
||||
if daemon.configStore.AutoRestart && container.shouldRestart() {
|
||||
logrus.Debugf("Starting container %s", container.ID)
|
||||
|
||||
if err := container.Start(); err != nil {
|
||||
if err := container.Start(ctx); err != nil {
|
||||
logrus.Errorf("Failed to start container %s: %s", container.ID, err)
|
||||
}
|
||||
}
|
||||
@@ -365,7 +363,7 @@ func (daemon *Daemon) mergeAndVerifyConfig(config *runconfig.Config, img *image.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
|
||||
func (daemon *Daemon) generateIDAndName(ctx context.Context, name string) (string, string, error) {
|
||||
var (
|
||||
err error
|
||||
id = stringid.GenerateNonCryptoID()
|
||||
@@ -378,14 +376,14 @@ func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
|
||||
return id, name, nil
|
||||
}
|
||||
|
||||
if name, err = daemon.reserveName(id, name); err != nil {
|
||||
if name, err = daemon.reserveName(ctx, id, name); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
return id, name, nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) reserveName(id, name string) (string, error) {
|
||||
func (daemon *Daemon) reserveName(ctx context.Context, id, name string) (string, error) {
|
||||
if !validContainerNamePattern.MatchString(name) {
|
||||
return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
|
||||
}
|
||||
@@ -399,7 +397,7 @@ func (daemon *Daemon) reserveName(id, name string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
conflictingContainer, err := daemon.GetByName(name)
|
||||
conflictingContainer, err := daemon.GetByName(ctx, name)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "Could not find entity") {
|
||||
return "", err
|
||||
@@ -469,12 +467,12 @@ func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *stringutils.StrSlic
|
||||
return entrypoint, args
|
||||
}
|
||||
|
||||
func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID string) (*Container, error) {
|
||||
func (daemon *Daemon) newContainer(ctx context.Context, name string, config *runconfig.Config, imgID string) (*Container, error) {
|
||||
var (
|
||||
id string
|
||||
err error
|
||||
)
|
||||
id, name, err = daemon.generateIDAndName(name)
|
||||
id, name, err = daemon.generateIDAndName(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -511,7 +509,7 @@ func GetFullContainerName(name string) (string, error) {
|
||||
}
|
||||
|
||||
// GetByName returns a container given a name.
|
||||
func (daemon *Daemon) GetByName(name string) (*Container, error) {
|
||||
func (daemon *Daemon) GetByName(ctx context.Context, name string) (*Container, error) {
|
||||
fullName, err := GetFullContainerName(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -530,7 +528,7 @@ func (daemon *Daemon) GetByName(name string) (*Container, error) {
|
||||
// children returns all child containers of the container with the
|
||||
// given name. The containers are returned as a map from the container
|
||||
// name to a pointer to Container.
|
||||
func (daemon *Daemon) children(name string) (map[string]*Container, error) {
|
||||
func (daemon *Daemon) children(ctx context.Context, name string) (map[string]*Container, error) {
|
||||
name, err := GetFullContainerName(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -538,7 +536,7 @@ func (daemon *Daemon) children(name string) (map[string]*Container, error) {
|
||||
children := make(map[string]*Container)
|
||||
|
||||
err = daemon.containerGraphDB.Walk(name, func(p string, e *graphdb.Entity) error {
|
||||
c, err := daemon.Get(e.ID())
|
||||
c, err := daemon.Get(ctx, e.ID())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -574,7 +572,7 @@ func (daemon *Daemon) registerLink(parent, child *Container, alias string) error
|
||||
|
||||
// NewDaemon sets up everything for the daemon to be able to service
|
||||
// requests from the webserver.
|
||||
func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemon, err error) {
|
||||
func NewDaemon(ctx context.Context, config *Config, registryService *registry.Service) (daemon *Daemon, err error) {
|
||||
setDefaultMtu(config)
|
||||
|
||||
// Ensure we have compatible configuration options
|
||||
@@ -642,7 +640,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
|
||||
// Ensure the graph driver is shutdown at a later point
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err := d.Shutdown(); err != nil {
|
||||
if err := d.Shutdown(ctx); err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
}
|
||||
@@ -776,7 +774,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
|
||||
|
||||
go d.execCommandGC()
|
||||
|
||||
if err := d.restore(); err != nil {
|
||||
if err := d.restore(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -784,12 +782,12 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
|
||||
}
|
||||
|
||||
// Shutdown stops the daemon.
|
||||
func (daemon *Daemon) Shutdown() error {
|
||||
func (daemon *Daemon) Shutdown(ctx context.Context) error {
|
||||
daemon.shutdown = true
|
||||
if daemon.containers != nil {
|
||||
group := sync.WaitGroup{}
|
||||
logrus.Debug("starting clean shutdown of all containers...")
|
||||
for _, container := range daemon.List() {
|
||||
for _, container := range daemon.List(ctx) {
|
||||
c := container
|
||||
if c.IsRunning() {
|
||||
logrus.Debugf("stopping %s", c.ID)
|
||||
@@ -812,7 +810,7 @@ func (daemon *Daemon) Shutdown() error {
|
||||
logrus.Debugf("sending SIGTERM to container %s with error: %v", c.ID, err)
|
||||
return
|
||||
}
|
||||
if err := c.unpause(); err != nil {
|
||||
if err := c.unpause(ctx); err != nil {
|
||||
logrus.Debugf("Failed to unpause container %s with error: %v", c.ID, err)
|
||||
return
|
||||
}
|
||||
@@ -827,7 +825,7 @@ func (daemon *Daemon) Shutdown() error {
|
||||
}
|
||||
} else {
|
||||
// If container failed to exit in 10 seconds of SIGTERM, then using the force
|
||||
if err := c.Stop(10); err != nil {
|
||||
if err := c.Stop(ctx, 10); err != nil {
|
||||
logrus.Errorf("Stop container %s with error: %v", c.ID, err)
|
||||
}
|
||||
}
|
||||
@@ -865,7 +863,7 @@ func (daemon *Daemon) Shutdown() error {
|
||||
|
||||
// Mount sets container.basefs
|
||||
// (is it not set coming in? why is it unset?)
|
||||
func (daemon *Daemon) Mount(container *Container) error {
|
||||
func (daemon *Daemon) Mount(ctx context.Context, container *Container) error {
|
||||
dir, err := daemon.driver.Get(container.ID, container.getMountLabel())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting container %s from driver %s: %s", container.ID, daemon.driver, err)
|
||||
@@ -890,14 +888,14 @@ func (daemon *Daemon) unmount(container *Container) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) run(c *Container, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (execdriver.ExitStatus, error) {
|
||||
func (daemon *Daemon) run(ctx context.Context, c *Container, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (execdriver.ExitStatus, error) {
|
||||
hooks := execdriver.Hooks{
|
||||
Start: startCallback,
|
||||
}
|
||||
hooks.PreStart = append(hooks.PreStart, func(processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
|
||||
hooks.PreStart = append(hooks.PreStart, func(ctx context.Context, processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
|
||||
return c.setNetworkNamespaceKey(pid)
|
||||
})
|
||||
return daemon.execDriver.Run(c.command, pipes, hooks)
|
||||
return daemon.execDriver.Run(ctx, c.command, pipes, hooks)
|
||||
}
|
||||
|
||||
func (daemon *Daemon) kill(c *Container, sig int) error {
|
||||
@@ -964,12 +962,12 @@ func (daemon *Daemon) createRootfs(container *Container) error {
|
||||
// which need direct access to daemon.graph.
|
||||
// Once the tests switch to using engine and jobs, this method
|
||||
// can go away.
|
||||
func (daemon *Daemon) Graph() *graph.Graph {
|
||||
func (daemon *Daemon) Graph(ctx context.Context) *graph.Graph {
|
||||
return daemon.graph
|
||||
}
|
||||
|
||||
// Repositories returns all repositories.
|
||||
func (daemon *Daemon) Repositories() *graph.TagStore {
|
||||
func (daemon *Daemon) Repositories(ctx context.Context) *graph.TagStore {
|
||||
return daemon.repositories
|
||||
}
|
||||
|
||||
@@ -983,13 +981,13 @@ func (daemon *Daemon) systemInitPath() string {
|
||||
|
||||
// GraphDriver returns the currently used driver for processing
|
||||
// container layers.
|
||||
func (daemon *Daemon) GraphDriver() graphdriver.Driver {
|
||||
func (daemon *Daemon) GraphDriver(ctx context.Context) graphdriver.Driver {
|
||||
return daemon.driver
|
||||
}
|
||||
|
||||
// ExecutionDriver returns the currently used driver for creating and
|
||||
// starting execs in a container.
|
||||
func (daemon *Daemon) ExecutionDriver() execdriver.Driver {
|
||||
func (daemon *Daemon) ExecutionDriver(ctx context.Context) execdriver.Driver {
|
||||
return daemon.execDriver
|
||||
}
|
||||
|
||||
@@ -1001,9 +999,9 @@ func (daemon *Daemon) containerGraph() *graphdb.Database {
|
||||
// of the image with imgID, that had the same config when it was
|
||||
// created. nil is returned if a child cannot be found. An error is
|
||||
// returned if the parent image cannot be found.
|
||||
func (daemon *Daemon) ImageGetCached(imgID string, config *runconfig.Config) (*image.Image, error) {
|
||||
func (daemon *Daemon) ImageGetCached(ctx context.Context, imgID string, config *runconfig.Config) (*image.Image, error) {
|
||||
// Retrieve all images
|
||||
images := daemon.Graph().Map()
|
||||
images := daemon.Graph(ctx).Map()
|
||||
|
||||
// Store the tree in a map of map (map[parentId][childId])
|
||||
imageMap := make(map[string]map[string]struct{})
|
||||
@@ -1039,7 +1037,7 @@ func tempDir(rootDir string) (string, error) {
|
||||
return tmpDir, system.MkdirAll(tmpDir, 0700)
|
||||
}
|
||||
|
||||
func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
func (daemon *Daemon) setHostConfig(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
container.Lock()
|
||||
if err := parseSecurityOpt(container, hostConfig); err != nil {
|
||||
container.Unlock()
|
||||
@@ -1049,14 +1047,14 @@ func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.
|
||||
|
||||
// Do not lock while creating volumes since this could be calling out to external plugins
|
||||
// Don't want to block other actions, like `docker ps` because we're waiting on an external plugin
|
||||
if err := daemon.registerMountPoints(container, hostConfig); err != nil {
|
||||
if err := daemon.registerMountPoints(ctx, container, hostConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
// Register any links from the host config before starting the container
|
||||
if err := daemon.registerLinks(container, hostConfig); err != nil {
|
||||
if err := daemon.registerLinks(ctx, container, hostConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1094,7 +1092,7 @@ func getDefaultRouteMtu() (int, error) {
|
||||
|
||||
// verifyContainerSettings performs validation of the hostconfig and config
|
||||
// structures.
|
||||
func (daemon *Daemon) verifyContainerSettings(hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
|
||||
func (daemon *Daemon) verifyContainerSettings(ctx context.Context, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
|
||||
|
||||
// First perform verification of settings common across all platforms.
|
||||
if config != nil {
|
||||
@@ -1131,7 +1129,7 @@ func (daemon *Daemon) verifyContainerSettings(hostConfig *runconfig.HostConfig,
|
||||
}
|
||||
|
||||
// Now do platform-specific verification
|
||||
return verifyPlatformContainerSettings(daemon, hostConfig, config)
|
||||
return verifyPlatformContainerSettings(ctx, daemon, hostConfig, config)
|
||||
}
|
||||
|
||||
func configureVolumes(config *Config) (*store.VolumeStore, error) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/pkg/graphdb"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/truncindex"
|
||||
@@ -92,32 +93,34 @@ func TestGet(t *testing.T) {
|
||||
containerGraphDB: graph,
|
||||
}
|
||||
|
||||
if container, _ := daemon.Get("3cdbd1aa394fd68559fd1441d6eff2ab7c1e6363582c82febfaa8045df3bd8de"); container != c2 {
|
||||
ctx := context.Background()
|
||||
|
||||
if container, _ := daemon.Get(ctx, "3cdbd1aa394fd68559fd1441d6eff2ab7c1e6363582c82febfaa8045df3bd8de"); container != c2 {
|
||||
t.Fatal("Should explicitly match full container IDs")
|
||||
}
|
||||
|
||||
if container, _ := daemon.Get("75fb0b8009"); container != c4 {
|
||||
if container, _ := daemon.Get(ctx, "75fb0b8009"); container != c4 {
|
||||
t.Fatal("Should match a partial ID")
|
||||
}
|
||||
|
||||
if container, _ := daemon.Get("drunk_hawking"); container != c2 {
|
||||
if container, _ := daemon.Get(ctx, "drunk_hawking"); container != c2 {
|
||||
t.Fatal("Should match a full name")
|
||||
}
|
||||
|
||||
// c3.Name is a partial match for both c3.ID and c2.ID
|
||||
if c, _ := daemon.Get("3cdbd1aa"); c != c3 {
|
||||
if c, _ := daemon.Get(ctx, "3cdbd1aa"); c != c3 {
|
||||
t.Fatal("Should match a full name even though it collides with another container's ID")
|
||||
}
|
||||
|
||||
if container, _ := daemon.Get("d22d69a2b896"); container != c5 {
|
||||
if container, _ := daemon.Get(ctx, "d22d69a2b896"); container != c5 {
|
||||
t.Fatal("Should match a container where the provided prefix is an exact match to the it's name, and is also a prefix for it's ID")
|
||||
}
|
||||
|
||||
if _, err := daemon.Get("3cdbd1"); err == nil {
|
||||
if _, err := daemon.Get(ctx, "3cdbd1"); err == nil {
|
||||
t.Fatal("Should return an error when provided a prefix that partially matches multiple container ID's")
|
||||
}
|
||||
|
||||
if _, err := daemon.Get("nothing"); err == nil {
|
||||
if _, err := daemon.Get(ctx, "nothing"); err == nil {
|
||||
t.Fatal("Should return an error when provided a prefix that is neither a name or a partial match to an ID")
|
||||
}
|
||||
|
||||
@@ -486,13 +489,15 @@ func TestRemoveLocalVolumesFollowingSymlinks(t *testing.T) {
|
||||
t.Fatalf("Expected 1 volume mounted, was 0\n")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
m := c.MountPoints["/vol1"]
|
||||
_, err = daemon.VolumeCreate(m.Name, m.Driver, nil)
|
||||
_, err = daemon.VolumeCreate(ctx, m.Name, m.Driver, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := daemon.VolumeRm(m.Name); err != nil {
|
||||
if err := daemon.VolumeRm(ctx, m.Name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/autogen/dockerversion"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/graphdriver"
|
||||
"github.com/docker/docker/pkg/fileutils"
|
||||
"github.com/docker/docker/pkg/parsers"
|
||||
@@ -117,12 +118,12 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a
|
||||
|
||||
// verifyPlatformContainerSettings performs platform-specific validation of the
|
||||
// hostconfig and config structures.
|
||||
func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
|
||||
func verifyPlatformContainerSettings(ctx context.Context, daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
|
||||
warnings := []string{}
|
||||
sysInfo := sysinfo.New(true)
|
||||
|
||||
if hostConfig.LxcConf.Len() > 0 && !strings.Contains(daemon.ExecutionDriver().Name(), "lxc") {
|
||||
return warnings, fmt.Errorf("Cannot use --lxc-conf with execdriver: %s", daemon.ExecutionDriver().Name())
|
||||
if hostConfig.LxcConf.Len() > 0 && !strings.Contains(daemon.ExecutionDriver(ctx).Name(), "lxc") {
|
||||
return warnings, fmt.Errorf("Cannot use --lxc-conf with execdriver: %s", daemon.ExecutionDriver(ctx).Name())
|
||||
}
|
||||
|
||||
// memory subsystem checks and adjustments
|
||||
@@ -495,12 +496,12 @@ func setupInitLayer(initLayer string) error {
|
||||
|
||||
// NetworkAPIRouter implements a feature for server-experimental,
|
||||
// directly calling into libnetwork.
|
||||
func (daemon *Daemon) NetworkAPIRouter() func(w http.ResponseWriter, req *http.Request) {
|
||||
func (daemon *Daemon) NetworkAPIRouter(ctx context.Context) func(w http.ResponseWriter, req *http.Request) {
|
||||
return nwapi.NewHTTPHandler(daemon.netController)
|
||||
}
|
||||
|
||||
// registerLinks writes the links to a file.
|
||||
func (daemon *Daemon) registerLinks(container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
func (daemon *Daemon) registerLinks(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
if hostConfig == nil || hostConfig.Links == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -510,14 +511,14 @@ func (daemon *Daemon) registerLinks(container *Container, hostConfig *runconfig.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
child, err := daemon.Get(name)
|
||||
child, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
//An error from daemon.Get() means this name could not be found
|
||||
return fmt.Errorf("Could not get container for %s", name)
|
||||
}
|
||||
for child.hostConfig.NetworkMode.IsContainer() {
|
||||
parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2)
|
||||
child, err = daemon.Get(parts[1])
|
||||
child, err = daemon.Get(ctx, parts[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not get container for %s", parts[1])
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/graphdriver"
|
||||
// register the windows graph driver
|
||||
_ "github.com/docker/docker/daemon/graphdriver/windows"
|
||||
@@ -47,7 +48,7 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a
|
||||
|
||||
// verifyPlatformContainerSettings performs platform-specific validation of the
|
||||
// hostconfig and config structures.
|
||||
func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
|
||||
func verifyPlatformContainerSettings(ctx context.Context, daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -104,7 +105,7 @@ func initNetworkController(config *Config) (libnetwork.NetworkController, error)
|
||||
|
||||
// registerLinks sets up links between containers and writes the
|
||||
// configuration out for persistence.
|
||||
func (daemon *Daemon) registerLinks(container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
func (daemon *Daemon) registerLinks(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
// TODO Windows. Factored out for network modes. There may be more
|
||||
// refactoring required here.
|
||||
|
||||
@@ -117,7 +118,7 @@ func (daemon *Daemon) registerLinks(container *Container, hostConfig *runconfig.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
child, err := daemon.Get(name)
|
||||
child, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
//An error from daemon.Get() means this name could not be found
|
||||
return fmt.Errorf("Could not get container for %s", name)
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/volume/store"
|
||||
@@ -19,8 +21,8 @@ type ContainerRmConfig struct {
|
||||
// is returned if the container is not found, or if the remove
|
||||
// fails. If the remove succeeds, the container name is released, and
|
||||
// network links are removed.
|
||||
func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerRm(ctx context.Context, name string, config *ContainerRmConfig) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -43,9 +45,9 @@ func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error
|
||||
return err
|
||||
}
|
||||
|
||||
parentContainer, _ := daemon.Get(pe.ID())
|
||||
parentContainer, _ := daemon.Get(ctx, pe.ID())
|
||||
if parentContainer != nil {
|
||||
if err := parentContainer.updateNetwork(); err != nil {
|
||||
if err := parentContainer.updateNetwork(ctx); err != nil {
|
||||
logrus.Debugf("Could not update network to remove link %s: %v", n, err)
|
||||
}
|
||||
}
|
||||
@@ -53,7 +55,7 @@ func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := daemon.rm(container, config.ForceRemove); err != nil {
|
||||
if err := daemon.rm(ctx, container, config.ForceRemove); err != nil {
|
||||
// return derr.ErrorCodeCantDestroy.WithArgs(name, utils.GetErrorMessage(err))
|
||||
return err
|
||||
}
|
||||
@@ -66,12 +68,12 @@ func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error
|
||||
}
|
||||
|
||||
// Destroy unregisters a container from the daemon and cleanly removes its contents from the filesystem.
|
||||
func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
|
||||
func (daemon *Daemon) rm(ctx context.Context, container *Container, forceRemove bool) (err error) {
|
||||
if container.IsRunning() {
|
||||
if !forceRemove {
|
||||
return derr.ErrorCodeRmRunning
|
||||
}
|
||||
if err := container.Kill(); err != nil {
|
||||
if err := container.Kill(ctx); err != nil {
|
||||
return derr.ErrorCodeRmFailed.WithArgs(err)
|
||||
}
|
||||
}
|
||||
@@ -92,7 +94,7 @@ func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
|
||||
|
||||
defer container.resetRemovalInProgress()
|
||||
|
||||
if err = container.Stop(3); err != nil {
|
||||
if err = container.Stop(ctx, 3); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -113,7 +115,7 @@ func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
|
||||
daemon.idIndex.Delete(container.ID)
|
||||
daemon.containers.Delete(container.ID)
|
||||
os.RemoveAll(container.root)
|
||||
container.logEvent("destroy")
|
||||
container.logEvent(ctx, "destroy")
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -142,14 +144,14 @@ func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
|
||||
daemon.idIndex.Delete(container.ID)
|
||||
daemon.containers.Delete(container.ID)
|
||||
|
||||
container.logEvent("destroy")
|
||||
container.logEvent(ctx, "destroy")
|
||||
return nil
|
||||
}
|
||||
|
||||
// VolumeRm removes the volume with the given name.
|
||||
// If the volume is referenced by a container it is not removed
|
||||
// This is called directly from the remote API
|
||||
func (daemon *Daemon) VolumeRm(name string) error {
|
||||
func (daemon *Daemon) VolumeRm(ctx context.Context, name string) error {
|
||||
v, err := daemon.volumes.Get(name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/docker/docker/pkg/pubsub"
|
||||
)
|
||||
@@ -44,9 +46,9 @@ func (e *Events) Evict(l chan interface{}) {
|
||||
|
||||
// Log broadcasts event to listeners. Each listener has 100 millisecond for
|
||||
// receiving event or it will be skipped.
|
||||
func (e *Events) Log(action, id, from string) {
|
||||
func (e *Events) Log(ctx context.Context, action, id, from string) {
|
||||
now := time.Now().UTC()
|
||||
jm := &jsonmessage.JSONMessage{Status: action, ID: id, From: from, Time: now.Unix(), TimeNano: now.UnixNano()}
|
||||
jm := &jsonmessage.JSONMessage{RequestID: ctx.RequestID(), Status: action, ID: id, From: from, Time: now.Unix(), TimeNano: now.UnixNano()}
|
||||
e.mu.Lock()
|
||||
if len(e.events) == cap(e.events) {
|
||||
// discard oldest event
|
||||
|
||||
@@ -5,10 +5,12 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
)
|
||||
|
||||
func TestEventsLog(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
e := New()
|
||||
_, l1 := e.Subscribe()
|
||||
_, l2 := e.Subscribe()
|
||||
@@ -18,7 +20,7 @@ func TestEventsLog(t *testing.T) {
|
||||
if count != 2 {
|
||||
t.Fatalf("Must be 2 subscribers, got %d", count)
|
||||
}
|
||||
e.Log("test", "cont", "image")
|
||||
e.Log(ctx, "test", "cont", "image")
|
||||
select {
|
||||
case msg := <-l1:
|
||||
jmsg, ok := msg.(*jsonmessage.JSONMessage)
|
||||
@@ -64,13 +66,14 @@ func TestEventsLog(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEventsLogTimeout(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
e := New()
|
||||
_, l := e.Subscribe()
|
||||
defer e.Evict(l)
|
||||
|
||||
c := make(chan struct{})
|
||||
go func() {
|
||||
e.Log("test", "cont", "image")
|
||||
e.Log(ctx, "test", "cont", "image")
|
||||
close(c)
|
||||
}()
|
||||
|
||||
@@ -82,13 +85,14 @@ func TestEventsLogTimeout(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLogEvents(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
e := New()
|
||||
|
||||
for i := 0; i < eventsLimit+16; i++ {
|
||||
action := fmt.Sprintf("action_%d", i)
|
||||
id := fmt.Sprintf("cont_%d", i)
|
||||
from := fmt.Sprintf("image_%d", i)
|
||||
e.Log(action, id, from)
|
||||
e.Log(ctx, action, id, from)
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
current, l := e.Subscribe()
|
||||
@@ -97,7 +101,7 @@ func TestLogEvents(t *testing.T) {
|
||||
action := fmt.Sprintf("action_%d", num)
|
||||
id := fmt.Sprintf("cont_%d", num)
|
||||
from := fmt.Sprintf("image_%d", num)
|
||||
e.Log(action, id, from)
|
||||
e.Log(ctx, action, id, from)
|
||||
}
|
||||
if len(e.events) != eventsLimit {
|
||||
t.Fatalf("Must be %d events, got %d", eventsLimit, len(e.events))
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/pkg/broadcastwriter"
|
||||
@@ -117,8 +118,8 @@ func (d *Daemon) unregisterExecCommand(ExecConfig *ExecConfig) {
|
||||
d.execCommands.Delete(ExecConfig.ID)
|
||||
}
|
||||
|
||||
func (d *Daemon) getActiveContainer(name string) (*Container, error) {
|
||||
container, err := d.Get(name)
|
||||
func (d *Daemon) getActiveContainer(ctx context.Context, name string) (*Container, error) {
|
||||
container, err := d.Get(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -133,13 +134,13 @@ func (d *Daemon) getActiveContainer(name string) (*Container, error) {
|
||||
}
|
||||
|
||||
// ContainerExecCreate sets up an exec in a running container.
|
||||
func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, error) {
|
||||
func (d *Daemon) ContainerExecCreate(ctx context.Context, config *runconfig.ExecConfig) (string, error) {
|
||||
// Not all drivers support Exec (LXC for example)
|
||||
if err := checkExecSupport(d.execDriver.Name()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
container, err := d.getActiveContainer(config.Container)
|
||||
container, err := d.getActiveContainer(ctx, config.Container)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -174,14 +175,14 @@ func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, erro
|
||||
|
||||
d.registerExecCommand(ExecConfig)
|
||||
|
||||
container.logEvent("exec_create: " + ExecConfig.ProcessConfig.Entrypoint + " " + strings.Join(ExecConfig.ProcessConfig.Arguments, " "))
|
||||
container.logEvent(ctx, "exec_create: "+ExecConfig.ProcessConfig.Entrypoint+" "+strings.Join(ExecConfig.ProcessConfig.Arguments, " "))
|
||||
|
||||
return ExecConfig.ID, nil
|
||||
}
|
||||
|
||||
// ContainerExecStart starts a previously set up exec instance. The
|
||||
// std streams are set up.
|
||||
func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error {
|
||||
func (d *Daemon) ContainerExecStart(ctx context.Context, execName string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error {
|
||||
var (
|
||||
cStdin io.ReadCloser
|
||||
cStdout, cStderr io.Writer
|
||||
@@ -207,7 +208,7 @@ func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout
|
||||
logrus.Debugf("starting exec command %s in container %s", ExecConfig.ID, ExecConfig.Container.ID)
|
||||
container := ExecConfig.Container
|
||||
|
||||
container.logEvent("exec_start: " + ExecConfig.ProcessConfig.Entrypoint + " " + strings.Join(ExecConfig.ProcessConfig.Arguments, " "))
|
||||
container.logEvent(ctx, "exec_start: "+ExecConfig.ProcessConfig.Entrypoint+" "+strings.Join(ExecConfig.ProcessConfig.Arguments, " "))
|
||||
|
||||
if ExecConfig.OpenStdin {
|
||||
r, w := io.Pipe()
|
||||
@@ -243,7 +244,7 @@ func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout
|
||||
// the exitStatus) even after the cmd is done running.
|
||||
|
||||
go func() {
|
||||
if err := container.exec(ExecConfig); err != nil {
|
||||
if err := container.exec(ctx, ExecConfig); err != nil {
|
||||
execErr <- derr.ErrorCodeExecCantRun.WithArgs(execName, container.ID, err)
|
||||
}
|
||||
}()
|
||||
@@ -267,11 +268,11 @@ func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout
|
||||
}
|
||||
|
||||
// Exec calls the underlying exec driver to run
|
||||
func (d *Daemon) Exec(c *Container, ExecConfig *ExecConfig, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (int, error) {
|
||||
func (d *Daemon) Exec(ctx context.Context, c *Container, ExecConfig *ExecConfig, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (int, error) {
|
||||
hooks := execdriver.Hooks{
|
||||
Start: startCallback,
|
||||
}
|
||||
exitStatus, err := d.execDriver.Exec(c.command, ExecConfig.ProcessConfig, pipes, hooks)
|
||||
exitStatus, err := d.execDriver.Exec(ctx, c.command, ExecConfig.ProcessConfig, pipes, hooks)
|
||||
|
||||
// On err, make sure we don't leave ExitCode at zero
|
||||
if err != nil && exitStatus == 0 {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
// TODO Windows: Factor out ulimit
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/pkg/ulimit"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
@@ -29,7 +30,7 @@ var (
|
||||
// through PreStart, Start and PostStop events.
|
||||
// Callbacks are provided a processConfig pointer and the pid of the child.
|
||||
// The channel will be used to notify the OOM events.
|
||||
type DriverCallback func(processConfig *ProcessConfig, pid int, chOOM <-chan struct{}) error
|
||||
type DriverCallback func(ctx context.Context, processConfig *ProcessConfig, pid int, chOOM <-chan struct{}) error
|
||||
|
||||
// Hooks is a struct containing function pointers to callbacks
|
||||
// used by any execdriver implementation exploiting hooks capabilities
|
||||
@@ -69,11 +70,11 @@ type ExitStatus struct {
|
||||
type Driver interface {
|
||||
// Run executes the process, blocks until the process exits and returns
|
||||
// the exit code. It's the last stage on Docker side for running a container.
|
||||
Run(c *Command, pipes *Pipes, hooks Hooks) (ExitStatus, error)
|
||||
Run(ctx context.Context, c *Command, pipes *Pipes, hooks Hooks) (ExitStatus, error)
|
||||
|
||||
// Exec executes the process in an existing container, blocks until the
|
||||
// process exits and returns the exit code.
|
||||
Exec(c *Command, processConfig *ProcessConfig, pipes *Pipes, hooks Hooks) (int, error)
|
||||
Exec(ctx context.Context, c *Command, processConfig *ProcessConfig, pipes *Pipes, hooks Hooks) (int, error)
|
||||
|
||||
// Kill sends signals to process in container.
|
||||
Kill(c *Command, sig int) error
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
sysinfo "github.com/docker/docker/pkg/system"
|
||||
@@ -125,7 +126,7 @@ func killNetNsProc(proc *os.Process) {
|
||||
|
||||
// Run implements the exec driver Driver interface,
|
||||
// it calls 'exec.Cmd' to launch lxc commands to run a container.
|
||||
func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
|
||||
func (d *Driver) Run(ctx context.Context, c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
|
||||
var (
|
||||
term execdriver.Terminal
|
||||
err error
|
||||
@@ -329,7 +330,7 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
|
||||
|
||||
if hooks.Start != nil {
|
||||
logrus.Debugf("Invoking startCallback")
|
||||
hooks.Start(&c.ProcessConfig, pid, oomKillNotification)
|
||||
hooks.Start(ctx, &c.ProcessConfig, pid, oomKillNotification)
|
||||
|
||||
}
|
||||
|
||||
@@ -871,7 +872,7 @@ func (t *TtyConsole) Close() error {
|
||||
|
||||
// Exec implements the exec driver Driver interface,
|
||||
// it is not implemented by lxc.
|
||||
func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
|
||||
func (d *Driver) Exec(ctx context.Context, c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
|
||||
return -1, ErrExec
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/opencontainers/runc/libcontainer/apparmor"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
@@ -18,7 +19,7 @@ import (
|
||||
|
||||
// createContainer populates and configures the container type with the
|
||||
// data provided by the execdriver.Command
|
||||
func (d *Driver) createContainer(c *execdriver.Command, hooks execdriver.Hooks) (*configs.Config, error) {
|
||||
func (d *Driver) createContainer(ctx context.Context, c *execdriver.Command, hooks execdriver.Hooks) (*configs.Config, error) {
|
||||
container := execdriver.InitContainer(c)
|
||||
|
||||
if err := d.createIpc(container, c); err != nil {
|
||||
@@ -33,7 +34,7 @@ func (d *Driver) createContainer(c *execdriver.Command, hooks execdriver.Hooks)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := d.createNetwork(container, c, hooks); err != nil {
|
||||
if err := d.createNetwork(ctx, container, c, hooks); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ func generateIfaceName() (string, error) {
|
||||
return "", errors.New("Failed to find name for new interface")
|
||||
}
|
||||
|
||||
func (d *Driver) createNetwork(container *configs.Config, c *execdriver.Command, hooks execdriver.Hooks) error {
|
||||
func (d *Driver) createNetwork(ctx context.Context, container *configs.Config, c *execdriver.Command, hooks execdriver.Hooks) error {
|
||||
if c.Network == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -150,7 +151,7 @@ func (d *Driver) createNetwork(container *configs.Config, c *execdriver.Command,
|
||||
// non-blocking and return the correct result when read.
|
||||
chOOM := make(chan struct{})
|
||||
close(chOOM)
|
||||
if err := fnHook(&c.ProcessConfig, s.Pid, chOOM); err != nil {
|
||||
if err := fnHook(ctx, &c.ProcessConfig, s.Pid, chOOM); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/pkg/parsers"
|
||||
"github.com/docker/docker/pkg/pools"
|
||||
@@ -131,9 +132,9 @@ type execOutput struct {
|
||||
|
||||
// Run implements the exec driver Driver interface,
|
||||
// it calls libcontainer APIs to run a container.
|
||||
func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
|
||||
func (d *Driver) Run(ctx context.Context, c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
|
||||
// take the Command and populate the libcontainer.Config from it
|
||||
container, err := d.createContainer(c, hooks)
|
||||
container, err := d.createContainer(ctx, c, hooks)
|
||||
if err != nil {
|
||||
return execdriver.ExitStatus{ExitCode: -1}, err
|
||||
}
|
||||
@@ -174,7 +175,7 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
|
||||
p.Wait()
|
||||
return execdriver.ExitStatus{ExitCode: -1}, err
|
||||
}
|
||||
hooks.Start(&c.ProcessConfig, pid, oom)
|
||||
hooks.Start(ctx, &c.ProcessConfig, pid, oom)
|
||||
}
|
||||
|
||||
waitF := p.Wait
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
// Blank import 'nsenter' so that init in that package will call c
|
||||
@@ -19,7 +20,7 @@ import (
|
||||
|
||||
// Exec implements the exec driver Driver interface,
|
||||
// it calls libcontainer APIs to execute a container.
|
||||
func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
|
||||
func (d *Driver) Exec(ctx context.Context, c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
|
||||
active := d.activeContainers[c.ID]
|
||||
if active == nil {
|
||||
return -1, fmt.Errorf("No active container exists with ID %s", c.ID)
|
||||
@@ -57,7 +58,7 @@ func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessCo
|
||||
// non-blocking and return the correct result when read.
|
||||
chOOM := make(chan struct{})
|
||||
close(chOOM)
|
||||
hooks.Start(&c.ProcessConfig, pid, chOOM)
|
||||
hooks.Start(ctx, &c.ProcessConfig, pid, chOOM)
|
||||
}
|
||||
|
||||
ps, err := p.Wait()
|
||||
|
||||
@@ -7,12 +7,13 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/microsoft/hcsshim"
|
||||
)
|
||||
|
||||
// Exec implements the exec driver Driver interface.
|
||||
func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
|
||||
func (d *Driver) Exec(ctx context.Context, c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
|
||||
|
||||
var (
|
||||
term execdriver.Terminal
|
||||
@@ -74,7 +75,7 @@ func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessCo
|
||||
// non-blocking and return the correct result when read.
|
||||
chOOM := make(chan struct{})
|
||||
close(chOOM)
|
||||
hooks.Start(&c.ProcessConfig, int(pid), chOOM)
|
||||
hooks.Start(ctx, &c.ProcessConfig, int(pid), chOOM)
|
||||
}
|
||||
|
||||
if exitCode, err = hcsshim.WaitForProcessInComputeSystem(c.ID, pid); err != nil {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/microsoft/hcsshim"
|
||||
)
|
||||
@@ -79,7 +80,7 @@ type containerInit struct {
|
||||
const defaultOwner = "docker"
|
||||
|
||||
// Run implements the exec driver Driver interface
|
||||
func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
|
||||
func (d *Driver) Run(ctx context.Context, c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
|
||||
|
||||
var (
|
||||
term execdriver.Terminal
|
||||
@@ -298,7 +299,7 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
|
||||
// non-blocking and return the correct result when read.
|
||||
chOOM := make(chan struct{})
|
||||
close(chOOM)
|
||||
hooks.Start(&c.ProcessConfig, int(pid), chOOM)
|
||||
hooks.Start(ctx, &c.ProcessConfig, int(pid), chOOM)
|
||||
}
|
||||
|
||||
var exitCode int32
|
||||
|
||||
@@ -3,18 +3,19 @@ package daemon
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
)
|
||||
|
||||
// ContainerExport writes the contents of the container to the given
|
||||
// writer. An error is returned if the container cannot be found.
|
||||
func (daemon *Daemon) ContainerExport(name string, out io.Writer) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerExport(ctx context.Context, name string, out io.Writer) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := container.export()
|
||||
data, err := container.export(ctx)
|
||||
if err != nil {
|
||||
return derr.ErrorCodeExportFailed.WithArgs(name, err)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/graph/tags"
|
||||
"github.com/docker/docker/image"
|
||||
@@ -50,10 +51,10 @@ import (
|
||||
// FIXME: remove ImageDelete's dependency on Daemon, then move to the graph
|
||||
// package. This would require that we no longer need the daemon to determine
|
||||
// whether images are being used by a stopped or running container.
|
||||
func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.ImageDelete, error) {
|
||||
func (daemon *Daemon) ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDelete, error) {
|
||||
records := []types.ImageDelete{}
|
||||
|
||||
img, err := daemon.Repositories().LookupImage(imageRef)
|
||||
img, err := daemon.Repositories(ctx).LookupImage(imageRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -64,8 +65,8 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
|
||||
// first. We can only remove this reference if either force is
|
||||
// true, there are multiple repository references to this
|
||||
// image, or there are no containers using the given reference.
|
||||
if !(force || daemon.imageHasMultipleRepositoryReferences(img.ID)) {
|
||||
if container := daemon.getContainerUsingImage(img.ID); container != nil {
|
||||
if !(force || daemon.imageHasMultipleRepositoryReferences(ctx, img.ID)) {
|
||||
if container := daemon.getContainerUsingImage(ctx, img.ID); container != nil {
|
||||
// If we removed the repository reference then
|
||||
// this image would remain "dangling" and since
|
||||
// we really want to avoid that the client must
|
||||
@@ -74,14 +75,14 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
|
||||
}
|
||||
}
|
||||
|
||||
parsedRef, err := daemon.removeImageRef(imageRef)
|
||||
parsedRef, err := daemon.removeImageRef(ctx, imageRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
untaggedRecord := types.ImageDelete{Untagged: parsedRef}
|
||||
|
||||
daemon.EventsService.Log("untag", img.ID, "")
|
||||
daemon.EventsService.Log(ctx, "untag", img.ID, "")
|
||||
records = append(records, untaggedRecord)
|
||||
|
||||
removedRepositoryRef = true
|
||||
@@ -90,21 +91,21 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
|
||||
// repository reference to the image then we will want to
|
||||
// remove that reference.
|
||||
// FIXME: Is this the behavior we want?
|
||||
repoRefs := daemon.Repositories().ByID()[img.ID]
|
||||
repoRefs := daemon.Repositories(ctx).ByID()[img.ID]
|
||||
if len(repoRefs) == 1 {
|
||||
parsedRef, err := daemon.removeImageRef(repoRefs[0])
|
||||
parsedRef, err := daemon.removeImageRef(ctx, repoRefs[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
untaggedRecord := types.ImageDelete{Untagged: parsedRef}
|
||||
|
||||
daemon.EventsService.Log("untag", img.ID, "")
|
||||
daemon.EventsService.Log(ctx, "untag", img.ID, "")
|
||||
records = append(records, untaggedRecord)
|
||||
}
|
||||
}
|
||||
|
||||
return records, daemon.imageDeleteHelper(img, &records, force, prune, removedRepositoryRef)
|
||||
return records, daemon.imageDeleteHelper(ctx, img, &records, force, prune, removedRepositoryRef)
|
||||
}
|
||||
|
||||
// isImageIDPrefix returns whether the given possiblePrefix is a prefix of the
|
||||
@@ -115,14 +116,14 @@ func isImageIDPrefix(imageID, possiblePrefix string) bool {
|
||||
|
||||
// imageHasMultipleRepositoryReferences returns whether there are multiple
|
||||
// repository references to the given imageID.
|
||||
func (daemon *Daemon) imageHasMultipleRepositoryReferences(imageID string) bool {
|
||||
return len(daemon.Repositories().ByID()[imageID]) > 1
|
||||
func (daemon *Daemon) imageHasMultipleRepositoryReferences(ctx context.Context, imageID string) bool {
|
||||
return len(daemon.Repositories(ctx).ByID()[imageID]) > 1
|
||||
}
|
||||
|
||||
// getContainerUsingImage returns a container that was created using the given
|
||||
// imageID. Returns nil if there is no such container.
|
||||
func (daemon *Daemon) getContainerUsingImage(imageID string) *Container {
|
||||
for _, container := range daemon.List() {
|
||||
func (daemon *Daemon) getContainerUsingImage(ctx context.Context, imageID string) *Container {
|
||||
for _, container := range daemon.List(ctx) {
|
||||
if container.ImageID == imageID {
|
||||
return container
|
||||
}
|
||||
@@ -136,7 +137,7 @@ func (daemon *Daemon) getContainerUsingImage(imageID string) *Container {
|
||||
// repositoryRef must not be an image ID but a repository name followed by an
|
||||
// optional tag or digest reference. If tag or digest is omitted, the default
|
||||
// tag is used. Returns the resolved image reference and an error.
|
||||
func (daemon *Daemon) removeImageRef(repositoryRef string) (string, error) {
|
||||
func (daemon *Daemon) removeImageRef(ctx context.Context, repositoryRef string) (string, error) {
|
||||
repository, ref := parsers.ParseRepositoryTag(repositoryRef)
|
||||
if ref == "" {
|
||||
ref = tags.DefaultTag
|
||||
@@ -145,7 +146,7 @@ func (daemon *Daemon) removeImageRef(repositoryRef string) (string, error) {
|
||||
// Ignore the boolean value returned, as far as we're concerned, this
|
||||
// is an idempotent operation and it's okay if the reference didn't
|
||||
// exist in the first place.
|
||||
_, err := daemon.Repositories().Delete(repository, ref)
|
||||
_, err := daemon.Repositories(ctx).Delete(repository, ref)
|
||||
|
||||
return utils.ImageReference(repository, ref), err
|
||||
}
|
||||
@@ -155,18 +156,18 @@ func (daemon *Daemon) removeImageRef(repositoryRef string) (string, error) {
|
||||
// on the first encountered error. Removed references are logged to this
|
||||
// daemon's event service. An "Untagged" types.ImageDelete is added to the
|
||||
// given list of records.
|
||||
func (daemon *Daemon) removeAllReferencesToImageID(imgID string, records *[]types.ImageDelete) error {
|
||||
imageRefs := daemon.Repositories().ByID()[imgID]
|
||||
func (daemon *Daemon) removeAllReferencesToImageID(ctx context.Context, imgID string, records *[]types.ImageDelete) error {
|
||||
imageRefs := daemon.Repositories(ctx).ByID()[imgID]
|
||||
|
||||
for _, imageRef := range imageRefs {
|
||||
parsedRef, err := daemon.removeImageRef(imageRef)
|
||||
parsedRef, err := daemon.removeImageRef(ctx, imageRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
untaggedRecord := types.ImageDelete{Untagged: parsedRef}
|
||||
|
||||
daemon.EventsService.Log("untag", imgID, "")
|
||||
daemon.EventsService.Log(ctx, "untag", imgID, "")
|
||||
*records = append(*records, untaggedRecord)
|
||||
}
|
||||
|
||||
@@ -203,11 +204,11 @@ func (idc *imageDeleteConflict) Error() string {
|
||||
// conflict is encountered, it will be returned immediately without deleting
|
||||
// the image. If quiet is true, any encountered conflicts will be ignored and
|
||||
// the function will return nil immediately without deleting the image.
|
||||
func (daemon *Daemon) imageDeleteHelper(img *image.Image, records *[]types.ImageDelete, force, prune, quiet bool) error {
|
||||
func (daemon *Daemon) imageDeleteHelper(ctx context.Context, img *image.Image, records *[]types.ImageDelete, force, prune, quiet bool) error {
|
||||
// First, determine if this image has any conflicts. Ignore soft conflicts
|
||||
// if force is true.
|
||||
if conflict := daemon.checkImageDeleteConflict(img, force); conflict != nil {
|
||||
if quiet && !daemon.imageIsDangling(img) {
|
||||
if conflict := daemon.checkImageDeleteConflict(ctx, img, force); conflict != nil {
|
||||
if quiet && !daemon.imageIsDangling(ctx, img) {
|
||||
// Ignore conflicts UNLESS the image is "dangling" in
|
||||
// which case we want the user to know.
|
||||
return nil
|
||||
@@ -219,15 +220,15 @@ func (daemon *Daemon) imageDeleteHelper(img *image.Image, records *[]types.Image
|
||||
}
|
||||
|
||||
// Delete all repository tag/digest references to this image.
|
||||
if err := daemon.removeAllReferencesToImageID(img.ID, records); err != nil {
|
||||
if err := daemon.removeAllReferencesToImageID(ctx, img.ID, records); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := daemon.Graph().Delete(img.ID); err != nil {
|
||||
if err := daemon.Graph(ctx).Delete(img.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
daemon.EventsService.Log("delete", img.ID, "")
|
||||
daemon.EventsService.Log(ctx, "delete", img.ID, "")
|
||||
*records = append(*records, types.ImageDelete{Deleted: img.ID})
|
||||
|
||||
if !prune || img.Parent == "" {
|
||||
@@ -237,14 +238,14 @@ func (daemon *Daemon) imageDeleteHelper(img *image.Image, records *[]types.Image
|
||||
// We need to prune the parent image. This means delete it if there are
|
||||
// no tags/digests referencing it and there are no containers using it (
|
||||
// either running or stopped).
|
||||
parentImg, err := daemon.Graph().Get(img.Parent)
|
||||
parentImg, err := daemon.Graph(ctx).Get(img.Parent)
|
||||
if err != nil {
|
||||
return derr.ErrorCodeImgNoParent.WithArgs(err)
|
||||
}
|
||||
|
||||
// Do not force prunings, but do so quietly (stopping on any encountered
|
||||
// conflicts).
|
||||
return daemon.imageDeleteHelper(parentImg, records, false, true, true)
|
||||
return daemon.imageDeleteHelper(ctx, parentImg, records, false, true, true)
|
||||
}
|
||||
|
||||
// checkImageDeleteConflict determines whether there are any conflicts
|
||||
@@ -253,9 +254,9 @@ func (daemon *Daemon) imageDeleteHelper(img *image.Image, records *[]types.Image
|
||||
// using the image. A soft conflict is any tags/digest referencing the given
|
||||
// image or any stopped container using the image. If ignoreSoftConflicts is
|
||||
// true, this function will not check for soft conflict conditions.
|
||||
func (daemon *Daemon) checkImageDeleteConflict(img *image.Image, ignoreSoftConflicts bool) *imageDeleteConflict {
|
||||
func (daemon *Daemon) checkImageDeleteConflict(ctx context.Context, img *image.Image, ignoreSoftConflicts bool) *imageDeleteConflict {
|
||||
// Check for hard conflicts first.
|
||||
if conflict := daemon.checkImageDeleteHardConflict(img); conflict != nil {
|
||||
if conflict := daemon.checkImageDeleteHardConflict(ctx, img); conflict != nil {
|
||||
return conflict
|
||||
}
|
||||
|
||||
@@ -265,12 +266,12 @@ func (daemon *Daemon) checkImageDeleteConflict(img *image.Image, ignoreSoftConfl
|
||||
return nil
|
||||
}
|
||||
|
||||
return daemon.checkImageDeleteSoftConflict(img)
|
||||
return daemon.checkImageDeleteSoftConflict(ctx, img)
|
||||
}
|
||||
|
||||
func (daemon *Daemon) checkImageDeleteHardConflict(img *image.Image) *imageDeleteConflict {
|
||||
func (daemon *Daemon) checkImageDeleteHardConflict(ctx context.Context, img *image.Image) *imageDeleteConflict {
|
||||
// Check if the image ID is being used by a pull or build.
|
||||
if daemon.Graph().IsHeld(img.ID) {
|
||||
if daemon.Graph(ctx).IsHeld(img.ID) {
|
||||
return &imageDeleteConflict{
|
||||
hard: true,
|
||||
imgID: img.ID,
|
||||
@@ -279,7 +280,7 @@ func (daemon *Daemon) checkImageDeleteHardConflict(img *image.Image) *imageDelet
|
||||
}
|
||||
|
||||
// Check if the image has any descendent images.
|
||||
if daemon.Graph().HasChildren(img) {
|
||||
if daemon.Graph(ctx).HasChildren(img) {
|
||||
return &imageDeleteConflict{
|
||||
hard: true,
|
||||
imgID: img.ID,
|
||||
@@ -288,7 +289,7 @@ func (daemon *Daemon) checkImageDeleteHardConflict(img *image.Image) *imageDelet
|
||||
}
|
||||
|
||||
// Check if any running container is using the image.
|
||||
for _, container := range daemon.List() {
|
||||
for _, container := range daemon.List(ctx) {
|
||||
if !container.IsRunning() {
|
||||
// Skip this until we check for soft conflicts later.
|
||||
continue
|
||||
@@ -306,9 +307,9 @@ func (daemon *Daemon) checkImageDeleteHardConflict(img *image.Image) *imageDelet
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) checkImageDeleteSoftConflict(img *image.Image) *imageDeleteConflict {
|
||||
func (daemon *Daemon) checkImageDeleteSoftConflict(ctx context.Context, img *image.Image) *imageDeleteConflict {
|
||||
// Check if any repository tags/digest reference this image.
|
||||
if daemon.Repositories().HasReferences(img) {
|
||||
if daemon.Repositories(ctx).HasReferences(img) {
|
||||
return &imageDeleteConflict{
|
||||
imgID: img.ID,
|
||||
message: "image is referenced in one or more repositories",
|
||||
@@ -316,7 +317,7 @@ func (daemon *Daemon) checkImageDeleteSoftConflict(img *image.Image) *imageDelet
|
||||
}
|
||||
|
||||
// Check if any stopped containers reference this image.
|
||||
for _, container := range daemon.List() {
|
||||
for _, container := range daemon.List(ctx) {
|
||||
if container.IsRunning() {
|
||||
// Skip this as it was checked above in hard conflict conditions.
|
||||
continue
|
||||
@@ -336,6 +337,6 @@ func (daemon *Daemon) checkImageDeleteSoftConflict(img *image.Image) *imageDelet
|
||||
// imageIsDangling returns whether the given image is "dangling" which means
|
||||
// that there are no repository references to the given image and it has no
|
||||
// child images.
|
||||
func (daemon *Daemon) imageIsDangling(img *image.Image) bool {
|
||||
return !(daemon.Repositories().HasReferences(img) || daemon.Graph().HasChildren(img))
|
||||
func (daemon *Daemon) imageIsDangling(ctx context.Context, img *image.Image) bool {
|
||||
return !(daemon.Repositories(ctx).HasReferences(img) || daemon.Graph(ctx).HasChildren(img))
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/autogen/dockerversion"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/pkg/fileutils"
|
||||
"github.com/docker/docker/pkg/parsers/kernel"
|
||||
"github.com/docker/docker/pkg/parsers/operatingsystem"
|
||||
@@ -18,8 +19,8 @@ import (
|
||||
)
|
||||
|
||||
// SystemInfo returns information about the host server the daemon is running on.
|
||||
func (daemon *Daemon) SystemInfo() (*types.Info, error) {
|
||||
images := daemon.Graph().Map()
|
||||
func (daemon *Daemon) SystemInfo(ctx context.Context) (*types.Info, error) {
|
||||
images := daemon.Graph(ctx).Map()
|
||||
var imgcount int
|
||||
if images == nil {
|
||||
imgcount = 0
|
||||
@@ -65,10 +66,10 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
|
||||
|
||||
v := &types.Info{
|
||||
ID: daemon.ID,
|
||||
Containers: len(daemon.List()),
|
||||
Containers: len(daemon.List(ctx)),
|
||||
Images: imgcount,
|
||||
Driver: daemon.GraphDriver().String(),
|
||||
DriverStatus: daemon.GraphDriver().Status(),
|
||||
Driver: daemon.GraphDriver(ctx).String(),
|
||||
DriverStatus: daemon.GraphDriver(ctx).Status(),
|
||||
IPv4Forwarding: !sysInfo.IPv4ForwardingDisabled,
|
||||
BridgeNfIptables: !sysInfo.BridgeNfCallIptablesDisabled,
|
||||
BridgeNfIP6tables: !sysInfo.BridgeNfCallIP6tablesDisabled,
|
||||
@@ -76,7 +77,7 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
|
||||
NFd: fileutils.GetTotalUsedFds(),
|
||||
NGoroutines: runtime.NumGoroutine(),
|
||||
SystemTime: time.Now().Format(time.RFC3339Nano),
|
||||
ExecutionDriver: daemon.ExecutionDriver().Name(),
|
||||
ExecutionDriver: daemon.ExecutionDriver(ctx).Name(),
|
||||
LoggingDriver: daemon.defaultLogConfig.Type,
|
||||
NEventsListener: daemon.EventsService.SubscribersCount(),
|
||||
KernelVersion: kernelVersion,
|
||||
|
||||
@@ -5,13 +5,14 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
)
|
||||
|
||||
// ContainerInspect returns low-level information about a
|
||||
// container. Returns an error if the container cannot be found, or if
|
||||
// there is an error getting the data.
|
||||
func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error) {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerInspect(ctx context.Context, name string) (*types.ContainerJSON, error) {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -19,7 +20,7 @@ func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
base, err := daemon.getInspectData(container)
|
||||
base, err := daemon.getInspectData(ctx, container)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -30,8 +31,8 @@ func (daemon *Daemon) ContainerInspect(name string) (*types.ContainerJSON, error
|
||||
}
|
||||
|
||||
// ContainerInspect120 serializes the master version of a container into a json type.
|
||||
func (daemon *Daemon) ContainerInspect120(name string) (*types.ContainerJSON120, error) {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerInspect120(ctx context.Context, name string) (*types.ContainerJSON120, error) {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -39,7 +40,7 @@ func (daemon *Daemon) ContainerInspect120(name string) (*types.ContainerJSON120,
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
base, err := daemon.getInspectData(container)
|
||||
base, err := daemon.getInspectData(ctx, container)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -53,11 +54,11 @@ func (daemon *Daemon) ContainerInspect120(name string) (*types.ContainerJSON120,
|
||||
return &types.ContainerJSON120{base, mountPoints, config}, nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSONBase, error) {
|
||||
func (daemon *Daemon) getInspectData(ctx context.Context, container *Container) (*types.ContainerJSONBase, error) {
|
||||
// make a copy to play with
|
||||
hostConfig := *container.hostConfig
|
||||
|
||||
if children, err := daemon.children(container.Name); err == nil {
|
||||
if children, err := daemon.children(ctx, container.Name); err == nil {
|
||||
for linkAlias, child := range children {
|
||||
hostConfig.Links = append(hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias))
|
||||
}
|
||||
@@ -120,7 +121,7 @@ func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSON
|
||||
|
||||
// ContainerExecInspect returns low-level information about the exec
|
||||
// command. An error is returned if the exec cannot be found.
|
||||
func (daemon *Daemon) ContainerExecInspect(id string) (*ExecConfig, error) {
|
||||
func (daemon *Daemon) ContainerExecInspect(ctx context.Context, id string) (*ExecConfig, error) {
|
||||
eConfig, err := daemon.getExecConfig(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -130,7 +131,7 @@ func (daemon *Daemon) ContainerExecInspect(id string) (*ExecConfig, error) {
|
||||
|
||||
// VolumeInspect looks up a volume by name. An error is returned if
|
||||
// the volume cannot be found.
|
||||
func (daemon *Daemon) VolumeInspect(name string) (*types.Volume, error) {
|
||||
func (daemon *Daemon) VolumeInspect(ctx context.Context, name string) (*types.Volume, error) {
|
||||
v, err := daemon.volumes.Get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
package daemon
|
||||
|
||||
import "github.com/docker/docker/api/types"
|
||||
import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
)
|
||||
|
||||
// This sets platform-specific fields
|
||||
func setPlatformSpecificContainerFields(container *Container, contJSONBase *types.ContainerJSONBase) *types.ContainerJSONBase {
|
||||
@@ -15,8 +18,8 @@ func setPlatformSpecificContainerFields(container *Container, contJSONBase *type
|
||||
}
|
||||
|
||||
// ContainerInspectPre120 gets containers for pre 1.20 APIs.
|
||||
func (daemon *Daemon) ContainerInspectPre120(name string) (*types.ContainerJSONPre120, error) {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerInspectPre120(ctx context.Context, name string) (*types.ContainerJSONPre120, error) {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -24,7 +27,7 @@ func (daemon *Daemon) ContainerInspectPre120(name string) (*types.ContainerJSONP
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
base, err := daemon.getInspectData(container)
|
||||
base, err := daemon.getInspectData(ctx, container)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package daemon
|
||||
|
||||
import "github.com/docker/docker/api/types"
|
||||
import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
)
|
||||
|
||||
// This sets platform-specific fields
|
||||
func setPlatformSpecificContainerFields(container *Container, contJSONBase *types.ContainerJSONBase) *types.ContainerJSONBase {
|
||||
@@ -12,6 +15,6 @@ func addMountPoints(container *Container) []types.MountPoint {
|
||||
}
|
||||
|
||||
// ContainerInspectPre120 get containers for pre 1.20 APIs.
|
||||
func (daemon *Daemon) ContainerInspectPre120(name string) (*types.ContainerJSON, error) {
|
||||
return daemon.ContainerInspect(name)
|
||||
func (daemon *Daemon) ContainerInspectPre120(ctx context.Context, name string) (*types.ContainerJSON, error) {
|
||||
return daemon.ContainerInspect(ctx, name)
|
||||
}
|
||||
|
||||
@@ -1,25 +1,29 @@
|
||||
package daemon
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
)
|
||||
|
||||
// ContainerKill send signal to the container
|
||||
// If no signal is given (sig 0), then Kill with SIGKILL and wait
|
||||
// for the container to exit.
|
||||
// If a signal is given, then just send it to the container and return.
|
||||
func (daemon *Daemon) ContainerKill(name string, sig uint64) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerKill(ctx context.Context, name string, sig uint64) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait())
|
||||
if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL {
|
||||
if err := container.Kill(); err != nil {
|
||||
if err := container.Kill(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Otherwise, just send the requested signal
|
||||
if err := container.killSig(int(sig)); err != nil {
|
||||
if err := container.killSig(ctx, int(sig)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/pkg/graphdb"
|
||||
@@ -20,7 +21,7 @@ type iterationAction int
|
||||
|
||||
// containerReducer represents a reducer for a container.
|
||||
// Returns the object to serialize by the api.
|
||||
type containerReducer func(*Container, *listContext) (*types.Container, error)
|
||||
type containerReducer func(context.Context, *Container, *listContext) (*types.Container, error)
|
||||
|
||||
const (
|
||||
// includeContainer is the action to include a container in the reducer.
|
||||
@@ -35,7 +36,7 @@ const (
|
||||
var errStopIteration = errors.New("container list iteration stopped")
|
||||
|
||||
// List returns an array of all containers registered in the daemon.
|
||||
func (daemon *Daemon) List() []*Container {
|
||||
func (daemon *Daemon) List(ctx context.Context) []*Container {
|
||||
return daemon.containers.List()
|
||||
}
|
||||
|
||||
@@ -79,21 +80,21 @@ type listContext struct {
|
||||
}
|
||||
|
||||
// Containers returns the list of containers to show given the user's filtering.
|
||||
func (daemon *Daemon) Containers(config *ContainersConfig) ([]*types.Container, error) {
|
||||
return daemon.reduceContainers(config, daemon.transformContainer)
|
||||
func (daemon *Daemon) Containers(ctx context.Context, config *ContainersConfig) ([]*types.Container, error) {
|
||||
return daemon.reduceContainers(ctx, config, daemon.transformContainer)
|
||||
}
|
||||
|
||||
// reduceContainer parses the user filtering and generates the list of containers to return based on a reducer.
|
||||
func (daemon *Daemon) reduceContainers(config *ContainersConfig, reducer containerReducer) ([]*types.Container, error) {
|
||||
func (daemon *Daemon) reduceContainers(ctx context.Context, config *ContainersConfig, reducer containerReducer) ([]*types.Container, error) {
|
||||
containers := []*types.Container{}
|
||||
|
||||
ctx, err := daemon.foldFilter(config)
|
||||
fctx, err := daemon.foldFilter(ctx, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, container := range daemon.List() {
|
||||
t, err := daemon.reducePsContainer(container, ctx, reducer)
|
||||
for _, container := range daemon.List(ctx) {
|
||||
t, err := daemon.reducePsContainer(ctx, container, fctx, reducer)
|
||||
if err != nil {
|
||||
if err != errStopIteration {
|
||||
return nil, err
|
||||
@@ -102,19 +103,19 @@ func (daemon *Daemon) reduceContainers(config *ContainersConfig, reducer contain
|
||||
}
|
||||
if t != nil {
|
||||
containers = append(containers, t)
|
||||
ctx.idx++
|
||||
fctx.idx++
|
||||
}
|
||||
}
|
||||
return containers, nil
|
||||
}
|
||||
|
||||
// reducePsContainer is the basic representation for a container as expected by the ps command.
|
||||
func (daemon *Daemon) reducePsContainer(container *Container, ctx *listContext, reducer containerReducer) (*types.Container, error) {
|
||||
func (daemon *Daemon) reducePsContainer(ctx context.Context, container *Container, lctx *listContext, reducer containerReducer) (*types.Container, error) {
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
// filter containers to return
|
||||
action := includeContainerInList(container, ctx)
|
||||
action := includeContainerInList(container, lctx)
|
||||
switch action {
|
||||
case excludeContainer:
|
||||
return nil, nil
|
||||
@@ -123,11 +124,11 @@ func (daemon *Daemon) reducePsContainer(container *Container, ctx *listContext,
|
||||
}
|
||||
|
||||
// transform internal container struct into api structs
|
||||
return reducer(container, ctx)
|
||||
return reducer(ctx, container, lctx)
|
||||
}
|
||||
|
||||
// foldFilter generates the container filter based in the user's filtering options.
|
||||
func (daemon *Daemon) foldFilter(config *ContainersConfig) (*listContext, error) {
|
||||
func (daemon *Daemon) foldFilter(ctx context.Context, config *ContainersConfig) (*listContext, error) {
|
||||
psFilters, err := filters.FromParam(config.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -159,11 +160,11 @@ func (daemon *Daemon) foldFilter(config *ContainersConfig) (*listContext, error)
|
||||
var ancestorFilter bool
|
||||
if ancestors, ok := psFilters["ancestor"]; ok {
|
||||
ancestorFilter = true
|
||||
byParents := daemon.Graph().ByParent()
|
||||
byParents := daemon.Graph(ctx).ByParent()
|
||||
// The idea is to walk the graph down the most "efficient" way.
|
||||
for _, ancestor := range ancestors {
|
||||
// First, get the imageId of the ancestor filter (yay)
|
||||
image, err := daemon.Repositories().LookupImage(ancestor)
|
||||
image, err := daemon.Repositories(ctx).LookupImage(ancestor)
|
||||
if err != nil {
|
||||
logrus.Warnf("Error while looking up for image %v", ancestor)
|
||||
continue
|
||||
@@ -185,14 +186,14 @@ func (daemon *Daemon) foldFilter(config *ContainersConfig) (*listContext, error)
|
||||
|
||||
var beforeCont, sinceCont *Container
|
||||
if config.Before != "" {
|
||||
beforeCont, err = daemon.Get(config.Before)
|
||||
beforeCont, err = daemon.Get(ctx, config.Before)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if config.Since != "" {
|
||||
sinceCont, err = daemon.Get(config.Since)
|
||||
sinceCont, err = daemon.Get(ctx, config.Since)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -286,13 +287,13 @@ func includeContainerInList(container *Container, ctx *listContext) iterationAct
|
||||
}
|
||||
|
||||
// transformContainer generates the container type expected by the docker ps command.
|
||||
func (daemon *Daemon) transformContainer(container *Container, ctx *listContext) (*types.Container, error) {
|
||||
func (daemon *Daemon) transformContainer(ctx context.Context, container *Container, lctx *listContext) (*types.Container, error) {
|
||||
newC := &types.Container{
|
||||
ID: container.ID,
|
||||
Names: ctx.names[container.ID],
|
||||
Names: lctx.names[container.ID],
|
||||
}
|
||||
|
||||
img, err := daemon.Repositories().LookupImage(container.Config.Image)
|
||||
img, err := daemon.Repositories(ctx).LookupImage(container.Config.Image)
|
||||
if err != nil {
|
||||
// If the image can no longer be found by its original reference,
|
||||
// it makes sense to show the ID instead of a stale reference.
|
||||
@@ -349,8 +350,8 @@ func (daemon *Daemon) transformContainer(container *Container, ctx *listContext)
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.Size {
|
||||
sizeRw, sizeRootFs := container.getSize()
|
||||
if lctx.Size {
|
||||
sizeRw, sizeRootFs := container.getSize(ctx)
|
||||
newC.SizeRw = sizeRw
|
||||
newC.SizeRootFs = sizeRootFs
|
||||
}
|
||||
@@ -361,7 +362,7 @@ func (daemon *Daemon) transformContainer(container *Container, ctx *listContext)
|
||||
|
||||
// Volumes lists known volumes, using the filter to restrict the range
|
||||
// of volumes returned.
|
||||
func (daemon *Daemon) Volumes(filter string) ([]*types.Volume, error) {
|
||||
func (daemon *Daemon) Volumes(ctx context.Context, filter string) ([]*types.Volume, error) {
|
||||
var volumesOut []*types.Volume
|
||||
volFilters, err := filters.FromParam(filter)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/logger"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
@@ -30,7 +31,7 @@ type ContainerLogsConfig struct {
|
||||
|
||||
// ContainerLogs hooks up a container's stdout and stderr streams
|
||||
// configured with the given struct.
|
||||
func (daemon *Daemon) ContainerLogs(container *Container, config *ContainerLogsConfig) error {
|
||||
func (daemon *Daemon) ContainerLogs(ctx context.Context, container *Container, config *ContainerLogsConfig) error {
|
||||
if !(config.UseStdout || config.UseStderr) {
|
||||
return derr.ErrorCodeNeedStream
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/runconfig"
|
||||
@@ -84,9 +85,9 @@ func (m *containerMonitor) ExitOnNext() {
|
||||
|
||||
// Close closes the container's resources such as networking allocations and
|
||||
// unmounts the contatiner's root filesystem
|
||||
func (m *containerMonitor) Close() error {
|
||||
func (m *containerMonitor) Close(ctx context.Context) error {
|
||||
// Cleanup networking and mounts
|
||||
m.container.cleanup()
|
||||
m.container.cleanup(ctx)
|
||||
|
||||
// FIXME: here is race condition between two RUN instructions in Dockerfile
|
||||
// because they share same runconfig and change image. Must be fixed
|
||||
@@ -101,7 +102,7 @@ func (m *containerMonitor) Close() error {
|
||||
}
|
||||
|
||||
// Start starts the containers process and monitors it according to the restart policy
|
||||
func (m *containerMonitor) Start() error {
|
||||
func (m *containerMonitor) Start(ctx context.Context) error {
|
||||
var (
|
||||
err error
|
||||
exitStatus execdriver.ExitStatus
|
||||
@@ -117,7 +118,7 @@ func (m *containerMonitor) Start() error {
|
||||
m.container.setStopped(&exitStatus)
|
||||
defer m.container.Unlock()
|
||||
}
|
||||
m.Close()
|
||||
m.Close(ctx)
|
||||
}()
|
||||
// reset stopped flag
|
||||
if m.container.HasBeenManuallyStopped {
|
||||
@@ -138,11 +139,11 @@ func (m *containerMonitor) Start() error {
|
||||
|
||||
pipes := execdriver.NewPipes(m.container.stdin, m.container.stdout, m.container.stderr, m.container.Config.OpenStdin)
|
||||
|
||||
m.container.logEvent("start")
|
||||
m.container.logEvent(ctx, "start")
|
||||
|
||||
m.lastStartTime = time.Now()
|
||||
|
||||
if exitStatus, err = m.container.daemon.run(m.container, pipes, m.callback); err != nil {
|
||||
if exitStatus, err = m.container.daemon.run(ctx, m.container, pipes, m.callback); err != nil {
|
||||
// if we receive an internal error from the initial start of a container then lets
|
||||
// return it instead of entering the restart loop
|
||||
if m.container.RestartCount == 0 {
|
||||
@@ -162,7 +163,7 @@ func (m *containerMonitor) Start() error {
|
||||
|
||||
if m.shouldRestart(exitStatus.ExitCode) {
|
||||
m.container.setRestarting(&exitStatus)
|
||||
m.container.logEvent("die")
|
||||
m.container.logEvent(ctx, "die")
|
||||
m.resetContainer(true)
|
||||
|
||||
// sleep with a small time increment between each restart to help avoid issues cased by quickly
|
||||
@@ -177,7 +178,7 @@ func (m *containerMonitor) Start() error {
|
||||
continue
|
||||
}
|
||||
|
||||
m.container.logEvent("die")
|
||||
m.container.logEvent(ctx, "die")
|
||||
m.resetContainer(true)
|
||||
return err
|
||||
}
|
||||
@@ -245,11 +246,11 @@ func (m *containerMonitor) shouldRestart(exitCode int) bool {
|
||||
|
||||
// callback ensures that the container's state is properly updated after we
|
||||
// received ack from the execution drivers
|
||||
func (m *containerMonitor) callback(processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
|
||||
func (m *containerMonitor) callback(ctx context.Context, processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
|
||||
go func() {
|
||||
_, ok := <-chOOM
|
||||
if ok {
|
||||
m.container.logEvent("oom")
|
||||
m.container.logEvent(ctx, "oom")
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
)
|
||||
|
||||
// ContainerPause pauses a container
|
||||
func (daemon *Daemon) ContainerPause(name string) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerPause(ctx context.Context, name string) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := container.pause(); err != nil {
|
||||
if err := container.pause(ctx); err != nil {
|
||||
return derr.ErrorCodePauseError.WithArgs(name, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
)
|
||||
|
||||
// ContainerRename changes the name of a container, using the oldName
|
||||
// to find the container. An error is returned if newName is already
|
||||
// reserved.
|
||||
func (daemon *Daemon) ContainerRename(oldName, newName string) error {
|
||||
func (daemon *Daemon) ContainerRename(ctx context.Context, oldName, newName string) error {
|
||||
if oldName == "" || newName == "" {
|
||||
return derr.ErrorCodeEmptyRename
|
||||
}
|
||||
|
||||
container, err := daemon.Get(oldName)
|
||||
container, err := daemon.Get(ctx, oldName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -21,7 +22,7 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
|
||||
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
if newName, err = daemon.reserveName(container.ID, newName); err != nil {
|
||||
if newName, err = daemon.reserveName(ctx, container.ID, newName); err != nil {
|
||||
return derr.ErrorCodeRenameTaken.WithArgs(err)
|
||||
}
|
||||
|
||||
@@ -29,7 +30,7 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
|
||||
|
||||
undo := func() {
|
||||
container.Name = oldName
|
||||
daemon.reserveName(container.ID, oldName)
|
||||
daemon.reserveName(ctx, container.ID, oldName)
|
||||
daemon.containerGraphDB.Delete(newName)
|
||||
}
|
||||
|
||||
@@ -43,6 +44,6 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
container.logEvent("rename")
|
||||
container.logEvent(ctx, "rename")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/context"
|
||||
)
|
||||
|
||||
// ContainerResize changes the size of the TTY of the process running
|
||||
// in the container with the given name to the given height and width.
|
||||
func (daemon *Daemon) ContainerResize(name string, height, width int) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerResize(ctx context.Context, name string, height, width int) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return container.Resize(height, width)
|
||||
return container.Resize(ctx, height, width)
|
||||
}
|
||||
|
||||
// ContainerExecResize changes the size of the TTY of the process
|
||||
// running in the exec with the given name to the given height and
|
||||
// width.
|
||||
func (daemon *Daemon) ContainerExecResize(name string, height, width int) error {
|
||||
func (daemon *Daemon) ContainerExecResize(ctx context.Context, name string, height, width int) error {
|
||||
ExecConfig, err := daemon.getExecConfig(name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
)
|
||||
|
||||
@@ -10,12 +11,12 @@ import (
|
||||
// timeout, ContainerRestart will wait forever until a graceful
|
||||
// stop. Returns an error if the container cannot be found, or if
|
||||
// there is an underlying error at any stage of the restart.
|
||||
func (daemon *Daemon) ContainerRestart(name string, seconds int) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerRestart(ctx context.Context, name string, seconds int) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := container.Restart(seconds); err != nil {
|
||||
if err := container.Restart(ctx, seconds); err != nil {
|
||||
return derr.ErrorCodeCantRestart.WithArgs(name, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -3,14 +3,15 @@ package daemon
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/docker/utils"
|
||||
)
|
||||
|
||||
// ContainerStart starts a container.
|
||||
func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConfig) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerStart(ctx context.Context, name string, hostConfig *runconfig.HostConfig) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -28,7 +29,7 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
|
||||
// This is kept for backward compatibility - hostconfig should be passed when
|
||||
// creating a container, not during start.
|
||||
if hostConfig != nil {
|
||||
if err := daemon.setHostConfig(container, hostConfig); err != nil {
|
||||
if err := daemon.setHostConfig(ctx, container, hostConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -40,11 +41,11 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
|
||||
|
||||
// check if hostConfig is in line with the current system settings.
|
||||
// It may happen cgroups are umounted or the like.
|
||||
if _, err = daemon.verifyContainerSettings(container.hostConfig, nil); err != nil {
|
||||
if _, err = daemon.verifyContainerSettings(ctx, container.hostConfig, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := container.Start(); err != nil {
|
||||
if err := container.Start(ctx); err != nil {
|
||||
return derr.ErrorCodeCantStart.WithArgs(name, utils.GetErrorMessage(err))
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/pkg/version"
|
||||
"github.com/docker/libnetwork/osl"
|
||||
@@ -22,9 +23,9 @@ type ContainerStatsConfig struct {
|
||||
|
||||
// ContainerStats writes information about the container to the stream
|
||||
// given in the config object.
|
||||
func (daemon *Daemon) ContainerStats(prefixOrName string, config *ContainerStatsConfig) error {
|
||||
func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, config *ContainerStatsConfig) error {
|
||||
|
||||
container, err := daemon.Get(prefixOrName)
|
||||
container, err := daemon.Get(ctx, prefixOrName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
)
|
||||
|
||||
@@ -10,15 +11,15 @@ import (
|
||||
// will wait for a graceful termination. An error is returned if the
|
||||
// container is not found, is already stopped, or if there is a
|
||||
// problem stopping the container.
|
||||
func (daemon *Daemon) ContainerStop(name string, seconds int) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerStop(ctx context.Context, name string, seconds int) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !container.IsRunning() {
|
||||
return derr.ErrorCodeStopped
|
||||
}
|
||||
if err := container.Stop(seconds); err != nil {
|
||||
if err := container.Stop(ctx, seconds); err != nil {
|
||||
return derr.ErrorCodeCantStop.WithArgs(name, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
)
|
||||
|
||||
@@ -16,12 +17,12 @@ import (
|
||||
// "-ef" if no args are given. An error is returned if the container
|
||||
// is not found, or is not running, or if there are any problems
|
||||
// running ps, or parsing the output.
|
||||
func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) {
|
||||
func (daemon *Daemon) ContainerTop(ctx context.Context, name string, psArgs string) (*types.ContainerProcessList, error) {
|
||||
if psArgs == "" {
|
||||
psArgs = "-ef"
|
||||
}
|
||||
|
||||
container, err := daemon.Get(name)
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -30,7 +31,7 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
|
||||
return nil, derr.ErrorCodeNotRunning.WithArgs(name)
|
||||
}
|
||||
|
||||
pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID)
|
||||
pids, err := daemon.ExecutionDriver(ctx).GetPidsForContainer(container.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -76,6 +77,6 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
|
||||
}
|
||||
}
|
||||
}
|
||||
container.logEvent("top")
|
||||
container.logEvent(ctx, "top")
|
||||
return procList, nil
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
)
|
||||
|
||||
// ContainerTop is not supported on Windows and returns an error.
|
||||
func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) {
|
||||
func (daemon *Daemon) ContainerTop(ctx context.Context, name string, psArgs string) (*types.ContainerProcessList, error) {
|
||||
return nil, derr.ErrorCodeNoTop
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/context"
|
||||
derr "github.com/docker/docker/errors"
|
||||
)
|
||||
|
||||
// ContainerUnpause unpauses a container
|
||||
func (daemon *Daemon) ContainerUnpause(name string) error {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerUnpause(ctx context.Context, name string) error {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := container.unpause(); err != nil {
|
||||
if err := container.unpause(ctx); err != nil {
|
||||
return derr.ErrorCodeCantUnpause.WithArgs(name, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
@@ -285,7 +286,7 @@ func parseVolumesFrom(spec string) (string, string, error) {
|
||||
// 1. Select the previously configured mount points for the containers, if any.
|
||||
// 2. Select the volumes mounted from another containers. Overrides previously configured mount point destination.
|
||||
// 3. Select the bind mounts set by the client. Overrides previously configured mount point destinations.
|
||||
func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
func (daemon *Daemon) registerMountPoints(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
binds := map[string]bool{}
|
||||
mountPoints := map[string]*mountPoint{}
|
||||
|
||||
@@ -301,7 +302,7 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := daemon.Get(containerID)
|
||||
c, err := daemon.Get(ctx, containerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/context"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/runconfig"
|
||||
)
|
||||
@@ -31,6 +32,6 @@ func (daemon *Daemon) verifyVolumesInfo(container *Container) error {
|
||||
// registerMountPoints initializes the container mount points with the
|
||||
// configured volumes and bind mounts. Windows does not support volumes or
|
||||
// mount points.
|
||||
func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
func (daemon *Daemon) registerMountPoints(ctx context.Context, container *Container, hostConfig *runconfig.HostConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package daemon
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/context"
|
||||
)
|
||||
|
||||
// ContainerWait stops processing until the given container is
|
||||
// stopped. If the container is not found, an error is returned. On a
|
||||
// successful stop, the exit code of the container is returned. On a
|
||||
// timeout, an error is returned. If you want to wait forever, supply
|
||||
// a negative duration for the timeout.
|
||||
func (daemon *Daemon) ContainerWait(name string, timeout time.Duration) (int, error) {
|
||||
container, err := daemon.Get(name)
|
||||
func (daemon *Daemon) ContainerWait(ctx context.Context, name string, timeout time.Duration) (int, error) {
|
||||
container, err := daemon.Get(ctx, name)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user