Signed-off-by: David Calavera <david.calavera@gmail.com>
| ... | ... |
@@ -142,7 +142,7 @@ func (daemon *Daemon) containerStatPath(container *Container, path string) (stat |
| 142 | 142 |
} |
| 143 | 143 |
defer daemon.Unmount(container) |
| 144 | 144 |
|
| 145 |
- err = container.mountVolumes() |
|
| 145 |
+ err = daemon.mountVolumes(container) |
|
| 146 | 146 |
defer container.unmountVolumes(true) |
| 147 | 147 |
if err != nil {
|
| 148 | 148 |
return nil, err |
| ... | ... |
@@ -184,7 +184,7 @@ func (daemon *Daemon) containerArchivePath(container *Container, path string) (c |
| 184 | 184 |
} |
| 185 | 185 |
}() |
| 186 | 186 |
|
| 187 |
- if err = container.mountVolumes(); err != nil {
|
|
| 187 |
+ if err = daemon.mountVolumes(container); err != nil {
|
|
| 188 | 188 |
return nil, nil, err |
| 189 | 189 |
} |
| 190 | 190 |
|
| ... | ... |
@@ -239,7 +239,7 @@ func (daemon *Daemon) containerExtractToDir(container *Container, path string, n |
| 239 | 239 |
} |
| 240 | 240 |
defer daemon.Unmount(container) |
| 241 | 241 |
|
| 242 |
- err = container.mountVolumes() |
|
| 242 |
+ err = daemon.mountVolumes(container) |
|
| 243 | 243 |
defer container.unmountVolumes(true) |
| 244 | 244 |
if err != nil {
|
| 245 | 245 |
return err |
| ... | ... |
@@ -348,7 +348,7 @@ func (daemon *Daemon) containerCopy(container *Container, resource string) (rc i |
| 348 | 348 |
} |
| 349 | 349 |
}() |
| 350 | 350 |
|
| 351 |
- if err := container.mountVolumes(); err != nil {
|
|
| 351 |
+ if err := daemon.mountVolumes(container); err != nil {
|
|
| 352 | 352 |
return nil, err |
| 353 | 353 |
} |
| 354 | 354 |
|
| ... | ... |
@@ -498,8 +498,8 @@ func (container *Container) shouldRestart() bool {
|
| 498 | 498 |
(container.hostConfig.RestartPolicy.Name == "on-failure" && container.ExitCode != 0) |
| 499 | 499 |
} |
| 500 | 500 |
|
| 501 |
-func (container *Container) mountVolumes() error {
|
|
| 502 |
- mounts, err := container.setupMounts() |
|
| 501 |
+func (daemon *Daemon) mountVolumes(container *Container) error {
|
|
| 502 |
+ mounts, err := daemon.setupMounts(container) |
|
| 503 | 503 |
if err != nil {
|
| 504 | 504 |
return err |
| 505 | 505 |
} |
| ... | ... |
@@ -744,14 +744,14 @@ func (daemon *Daemon) updateNetworkSettings(container *Container, n libnetwork.N |
| 744 | 744 |
return nil |
| 745 | 745 |
} |
| 746 | 746 |
|
| 747 |
-func (container *Container) updateEndpointNetworkSettings(n libnetwork.Network, ep libnetwork.Endpoint) error {
|
|
| 747 |
+func (daemon *Daemon) updateEndpointNetworkSettings(container *Container, n libnetwork.Network, ep libnetwork.Endpoint) error {
|
|
| 748 | 748 |
networkSettings, err := container.buildEndpointInfo(n, ep, container.NetworkSettings) |
| 749 | 749 |
if err != nil {
|
| 750 | 750 |
return err |
| 751 | 751 |
} |
| 752 | 752 |
|
| 753 | 753 |
if container.hostConfig.NetworkMode == runconfig.NetworkMode("bridge") {
|
| 754 |
- networkSettings.Bridge = container.daemon.configStore.Bridge.Iface |
|
| 754 |
+ networkSettings.Bridge = daemon.configStore.Bridge.Iface |
|
| 755 | 755 |
} |
| 756 | 756 |
|
| 757 | 757 |
return nil |
| ... | ... |
@@ -1006,7 +1006,7 @@ func (daemon *Daemon) connectToNetwork(container *Container, idOrName string, up |
| 1006 | 1006 |
} |
| 1007 | 1007 |
}() |
| 1008 | 1008 |
|
| 1009 |
- if err := container.updateEndpointNetworkSettings(n, ep); err != nil {
|
|
| 1009 |
+ if err := daemon.updateEndpointNetworkSettings(container, n, ep); err != nil {
|
|
| 1010 | 1010 |
return err |
| 1011 | 1011 |
} |
| 1012 | 1012 |
|
| ... | ... |
@@ -1075,13 +1075,13 @@ func (daemon *Daemon) initializeNetworking(container *Container) error {
|
| 1075 | 1075 |
|
| 1076 | 1076 |
// called from the libcontainer pre-start hook to set the network |
| 1077 | 1077 |
// namespace configuration linkage to the libnetwork "sandbox" entity |
| 1078 |
-func (daemon *Daemon) setNetworkNamespaceKey(containerId string, pid int) error {
|
|
| 1078 |
+func (daemon *Daemon) setNetworkNamespaceKey(containerID string, pid int) error {
|
|
| 1079 | 1079 |
path := fmt.Sprintf("/proc/%d/ns/net", pid)
|
| 1080 | 1080 |
var sandbox libnetwork.Sandbox |
| 1081 |
- search := libnetwork.SandboxContainerWalker(&sandbox, containerId) |
|
| 1081 |
+ search := libnetwork.SandboxContainerWalker(&sandbox, containerID) |
|
| 1082 | 1082 |
daemon.netController.WalkSandboxes(search) |
| 1083 | 1083 |
if sandbox == nil {
|
| 1084 |
- return derr.ErrorCodeNoSandbox.WithArgs(containerId) |
|
| 1084 |
+ return derr.ErrorCodeNoSandbox.WithArgs(containerID) |
|
| 1085 | 1085 |
} |
| 1086 | 1086 |
|
| 1087 | 1087 |
return sandbox.SetKey(path) |
| ... | ... |
@@ -1126,16 +1126,16 @@ func (container *Container) setupWorkingDirectory() error {
|
| 1126 | 1126 |
return nil |
| 1127 | 1127 |
} |
| 1128 | 1128 |
|
| 1129 |
-func (daemon *Daemon) getNetworkedContainer(containerId, connectedContainerId string) (*Container, error) {
|
|
| 1130 |
- nc, err := daemon.Get(connectedContainerId) |
|
| 1129 |
+func (daemon *Daemon) getNetworkedContainer(containerID, connectedContainerID string) (*Container, error) {
|
|
| 1130 |
+ nc, err := daemon.Get(connectedContainerID) |
|
| 1131 | 1131 |
if err != nil {
|
| 1132 | 1132 |
return nil, err |
| 1133 | 1133 |
} |
| 1134 |
- if containerId == nc.ID {
|
|
| 1134 |
+ if containerID == nc.ID {
|
|
| 1135 | 1135 |
return nil, derr.ErrorCodeJoinSelf |
| 1136 | 1136 |
} |
| 1137 | 1137 |
if !nc.IsRunning() {
|
| 1138 |
- return nil, derr.ErrorCodeJoinRunning.WithArgs(connectedContainerId) |
|
| 1138 |
+ return nil, derr.ErrorCodeJoinRunning.WithArgs(connectedContainerID) |
|
| 1139 | 1139 |
} |
| 1140 | 1140 |
return nc, nil |
| 1141 | 1141 |
} |
| ... | ... |
@@ -149,7 +149,7 @@ func (daemon *Daemon) getSize(container *Container) (int64, int64) {
|
| 149 | 149 |
} |
| 150 | 150 |
|
| 151 | 151 |
// setNetworkNamespaceKey is a no-op on Windows. |
| 152 |
-func (daemon *Daemon) setNetworkNamespaceKey(containerId string, pid int) error {
|
|
| 152 |
+func (daemon *Daemon) setNetworkNamespaceKey(containerID string, pid int) error {
|
|
| 153 | 153 |
return nil |
| 154 | 154 |
} |
| 155 | 155 |
|
| ... | ... |
@@ -119,7 +119,7 @@ func (daemon *Daemon) create(params *ContainerCreateConfig) (retC *Container, re |
| 119 | 119 |
} |
| 120 | 120 |
defer daemon.Unmount(container) |
| 121 | 121 |
|
| 122 |
- if err := createContainerPlatformSpecificSettings(container, params.Config, params.HostConfig, img); err != nil {
|
|
| 122 |
+ if err := daemon.createContainerPlatformSpecificSettings(container, params.Config, params.HostConfig, img); err != nil {
|
|
| 123 | 123 |
return nil, err |
| 124 | 124 |
} |
| 125 | 125 |
|
| ... | ... |
@@ -15,7 +15,7 @@ import ( |
| 15 | 15 |
) |
| 16 | 16 |
|
| 17 | 17 |
// createContainerPlatformSpecificSettings performs platform specific container create functionality |
| 18 |
-func createContainerPlatformSpecificSettings(container *Container, config *runconfig.Config, hostConfig *runconfig.HostConfig, img *image.Image) error {
|
|
| 18 |
+func (daemon *Daemon) createContainerPlatformSpecificSettings(container *Container, config *runconfig.Config, hostConfig *runconfig.HostConfig, img *image.Image) error {
|
|
| 19 | 19 |
for spec := range config.Volumes {
|
| 20 | 20 |
name := stringid.GenerateNonCryptoID() |
| 21 | 21 |
destination := filepath.Clean(spec) |
| ... | ... |
@@ -45,7 +45,7 @@ func createContainerPlatformSpecificSettings(container *Container, config *runco |
| 45 | 45 |
} |
| 46 | 46 |
} |
| 47 | 47 |
|
| 48 |
- v, err := container.daemon.createVolume(name, volumeDriver, nil) |
|
| 48 |
+ v, err := daemon.createVolume(name, volumeDriver, nil) |
|
| 49 | 49 |
if err != nil {
|
| 50 | 50 |
return err |
| 51 | 51 |
} |
| ... | ... |
@@ -10,7 +10,7 @@ import ( |
| 10 | 10 |
) |
| 11 | 11 |
|
| 12 | 12 |
// createContainerPlatformSpecificSettings performs platform specific container create functionality |
| 13 |
-func createContainerPlatformSpecificSettings(container *Container, config *runconfig.Config, hostConfig *runconfig.HostConfig, img *image.Image) error {
|
|
| 13 |
+func (daemon *Daemon) createContainerPlatformSpecificSettings(container *Container, config *runconfig.Config, hostConfig *runconfig.HostConfig, img *image.Image) error {
|
|
| 14 | 14 |
for spec := range config.Volumes {
|
| 15 | 15 |
|
| 16 | 16 |
mp, err := volume.ParseMountSpec(spec, hostConfig.VolumeDriver) |
| ... | ... |
@@ -41,7 +41,7 @@ func createContainerPlatformSpecificSettings(container *Container, config *runco |
| 41 | 41 |
|
| 42 | 42 |
// Create the volume in the volume driver. If it doesn't exist, |
| 43 | 43 |
// a new one will be created. |
| 44 |
- v, err := container.daemon.createVolume(mp.Name, volumeDriver, nil) |
|
| 44 |
+ v, err := daemon.createVolume(mp.Name, volumeDriver, nil) |
|
| 45 | 45 |
if err != nil {
|
| 46 | 46 |
return err |
| 47 | 47 |
} |
| ... | ... |
@@ -194,7 +194,7 @@ func (daemon *Daemon) load(id string) (*Container, error) {
|
| 194 | 194 |
|
| 195 | 195 |
// Register makes a container object usable by the daemon as <container.ID> |
| 196 | 196 |
func (daemon *Daemon) Register(container *Container) error {
|
| 197 |
- if container.daemon != nil || daemon.Exists(container.ID) {
|
|
| 197 |
+ if daemon.Exists(container.ID) {
|
|
| 198 | 198 |
return fmt.Errorf("Container is already loaded")
|
| 199 | 199 |
} |
| 200 | 200 |
if err := validateID(container.ID); err != nil {
|
| ... | ... |
@@ -204,8 +204,6 @@ func (daemon *Daemon) Register(container *Container) error {
|
| 204 | 204 |
return err |
| 205 | 205 |
} |
| 206 | 206 |
|
| 207 |
- container.daemon = daemon |
|
| 208 |
- |
|
| 209 | 207 |
// Attach to stdout and stderr |
| 210 | 208 |
container.stderr = new(broadcaster.Unbuffered) |
| 211 | 209 |
container.stdout = new(broadcaster.Unbuffered) |
| ... | ... |
@@ -954,7 +952,8 @@ func (daemon *Daemon) Unmount(container *Container) error {
|
| 954 | 954 |
return daemon.driver.Put(container.ID) |
| 955 | 955 |
} |
| 956 | 956 |
|
| 957 |
-func (daemon *Daemon) run(c *Container, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (execdriver.ExitStatus, error) {
|
|
| 957 |
+// Run uses the execution driver to run a given container |
|
| 958 |
+func (daemon *Daemon) Run(c *Container, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (execdriver.ExitStatus, error) {
|
|
| 958 | 959 |
hooks := execdriver.Hooks{
|
| 959 | 960 |
Start: startCallback, |
| 960 | 961 |
} |
| ... | ... |
@@ -1303,6 +1302,12 @@ func (daemon *Daemon) SearchRegistryForImages(term string, |
| 1303 | 1303 |
return daemon.RegistryService.Search(term, authConfig, headers) |
| 1304 | 1304 |
} |
| 1305 | 1305 |
|
| 1306 |
+// IsShuttingDown tells whether the daemon is shutting down or not |
|
| 1307 |
+func (daemon *Daemon) IsShuttingDown() bool {
|
|
| 1308 |
+ return daemon.shutdown |
|
| 1309 |
+} |
|
| 1310 |
+ |
|
| 1311 |
+// GetContainerStats collects all the stats published by a container |
|
| 1306 | 1312 |
func (daemon *Daemon) GetContainerStats(container *Container) (*execdriver.ResourceStats, error) {
|
| 1307 | 1313 |
stats, err := daemon.stats(container) |
| 1308 | 1314 |
if err != nil {
|
| ... | ... |
@@ -331,7 +331,7 @@ func (d *Daemon) containerExecIds() map[string]struct{} {
|
| 331 | 331 |
return ids |
| 332 | 332 |
} |
| 333 | 333 |
|
| 334 |
-func (daemon *Daemon) containerExec(container *Container, ec *ExecConfig) error {
|
|
| 334 |
+func (d *Daemon) containerExec(container *Container, ec *ExecConfig) error {
|
|
| 335 | 335 |
container.Lock() |
| 336 | 336 |
defer container.Unlock() |
| 337 | 337 |
|
| ... | ... |
@@ -350,7 +350,7 @@ func (daemon *Daemon) containerExec(container *Container, ec *ExecConfig) error |
| 350 | 350 |
|
| 351 | 351 |
// We use a callback here instead of a goroutine and an chan for |
| 352 | 352 |
// synchronization purposes |
| 353 |
- cErr := promise.Go(func() error { return daemon.monitorExec(container, ec, callback) })
|
|
| 353 |
+ cErr := promise.Go(func() error { return d.monitorExec(container, ec, callback) })
|
|
| 354 | 354 |
|
| 355 | 355 |
// Exec should not return until the process is actually running |
| 356 | 356 |
select {
|
| ... | ... |
@@ -362,13 +362,13 @@ func (daemon *Daemon) containerExec(container *Container, ec *ExecConfig) error |
| 362 | 362 |
return nil |
| 363 | 363 |
} |
| 364 | 364 |
|
| 365 |
-func (daemon *Daemon) monitorExec(container *Container, ExecConfig *ExecConfig, callback execdriver.DriverCallback) error {
|
|
| 365 |
+func (d *Daemon) monitorExec(container *Container, ExecConfig *ExecConfig, callback execdriver.DriverCallback) error {
|
|
| 366 | 366 |
var ( |
| 367 | 367 |
err error |
| 368 | 368 |
exitCode int |
| 369 | 369 |
) |
| 370 | 370 |
pipes := execdriver.NewPipes(ExecConfig.streamConfig.stdin, ExecConfig.streamConfig.stdout, ExecConfig.streamConfig.stderr, ExecConfig.OpenStdin) |
| 371 |
- exitCode, err = daemon.Exec(container, ExecConfig, pipes, callback) |
|
| 371 |
+ exitCode, err = d.Exec(container, ExecConfig, pipes, callback) |
|
| 372 | 372 |
if err != nil {
|
| 373 | 373 |
logrus.Errorf("Error running command in existing container %s: %s", container.ID, err)
|
| 374 | 374 |
} |
| ... | ... |
@@ -25,6 +25,10 @@ type containerSupervisor interface {
|
| 25 | 25 |
Cleanup(*Container) |
| 26 | 26 |
// StartLogging starts the logging driver for the container |
| 27 | 27 |
StartLogging(*Container) error |
| 28 |
+ // Run starts a container |
|
| 29 |
+ Run(c *Container, pipes *execdriver.Pipes, startCallback execdriver.DriverCallback) (execdriver.ExitStatus, error) |
|
| 30 |
+ // IsShuttingDown tells whether the supervisor is shutting down or not |
|
| 31 |
+ IsShuttingDown() bool |
|
| 28 | 32 |
} |
| 29 | 33 |
|
| 30 | 34 |
// containerMonitor monitors the execution of a container's main process. |
| ... | ... |
@@ -156,7 +160,7 @@ func (m *containerMonitor) Start() error {
|
| 156 | 156 |
|
| 157 | 157 |
m.lastStartTime = time.Now() |
| 158 | 158 |
|
| 159 |
- if exitStatus, err = m.container.daemon.run(m.container, pipes, m.callback); err != nil {
|
|
| 159 |
+ if exitStatus, err = m.supervisor.Run(m.container, pipes, m.callback); err != nil {
|
|
| 160 | 160 |
// if we receive an internal error from the initial start of a container then lets |
| 161 | 161 |
// return it instead of entering the restart loop |
| 162 | 162 |
if m.container.RestartCount == 0 {
|
| ... | ... |
@@ -236,7 +240,7 @@ func (m *containerMonitor) shouldRestart(exitCode int) bool {
|
| 236 | 236 |
|
| 237 | 237 |
// do not restart if the user or docker has requested that this container be stopped |
| 238 | 238 |
if m.shouldStop {
|
| 239 |
- m.container.HasBeenManuallyStopped = !m.container.daemon.shutdown |
|
| 239 |
+ m.container.HasBeenManuallyStopped = !m.supervisor.IsShuttingDown() |
|
| 240 | 240 |
return false |
| 241 | 241 |
} |
| 242 | 242 |
|
| ... | ... |
@@ -26,7 +26,7 @@ func (daemon *Daemon) removeMountPoints(container *Container, rm bool) error {
|
| 26 | 26 |
if m.Volume == nil {
|
| 27 | 27 |
continue |
| 28 | 28 |
} |
| 29 |
- container.daemon.volumes.Decrement(m.Volume) |
|
| 29 |
+ daemon.volumes.Decrement(m.Volume) |
|
| 30 | 30 |
if rm {
|
| 31 | 31 |
err := daemon.volumes.Remove(m.Volume) |
| 32 | 32 |
// ErrVolumeInUse is ignored because having this |
| ... | ... |
@@ -6,7 +6,7 @@ import "time" |
| 6 | 6 |
// for a registered container at the specified interval. The collector allows |
| 7 | 7 |
// non-running containers to be added and will start processing stats when |
| 8 | 8 |
// they are started. |
| 9 |
-func newStatsCollector(interval time.Duration) *statsCollector {
|
|
| 9 |
+func (daemon *Daemon) newStatsCollector(interval time.Duration) *statsCollector {
|
|
| 10 | 10 |
return &statsCollector{}
|
| 11 | 11 |
} |
| 12 | 12 |
|
| ... | ... |
@@ -58,7 +58,7 @@ func copyOwnership(source, destination string) error {
|
| 58 | 58 |
// setupMounts iterates through each of the mount points for a container and |
| 59 | 59 |
// calls Setup() on each. It also looks to see if is a network mount such as |
| 60 | 60 |
// /etc/resolv.conf, and if it is not, appends it to the array of mounts. |
| 61 |
-func (container *Container) setupMounts() ([]execdriver.Mount, error) {
|
|
| 61 |
+func (daemon *Daemon) setupMounts(container *Container) ([]execdriver.Mount, error) {
|
|
| 62 | 62 |
var mounts []execdriver.Mount |
| 63 | 63 |
for _, m := range container.MountPoints {
|
| 64 | 64 |
path, err := m.Setup() |
| ... | ... |
@@ -79,7 +79,7 @@ func (container *Container) setupMounts() ([]execdriver.Mount, error) {
|
| 79 | 79 |
// if we are going to mount any of the network files from container |
| 80 | 80 |
// metadata, the ownership must be set properly for potential container |
| 81 | 81 |
// remapped root (user namespaces) |
| 82 |
- rootUID, rootGID := container.daemon.GetRemappedUIDGID() |
|
| 82 |
+ rootUID, rootGID := daemon.GetRemappedUIDGID() |
|
| 83 | 83 |
for _, mount := range netMounts {
|
| 84 | 84 |
if err := os.Chown(mount.Source, rootUID, rootGID); err != nil {
|
| 85 | 85 |
return nil, err |
| ... | ... |
@@ -3,17 +3,18 @@ |
| 3 | 3 |
package daemon |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
+ "sort" |
|
| 7 |
+ |
|
| 6 | 8 |
"github.com/docker/docker/daemon/execdriver" |
| 7 | 9 |
derr "github.com/docker/docker/errors" |
| 8 | 10 |
"github.com/docker/docker/volume" |
| 9 |
- "sort" |
|
| 10 | 11 |
) |
| 11 | 12 |
|
| 12 | 13 |
// setupMounts configures the mount points for a container by appending each |
| 13 | 14 |
// of the configured mounts on the container to the execdriver mount structure |
| 14 | 15 |
// which will ultimately be passed into the exec driver during container creation. |
| 15 | 16 |
// It also ensures each of the mounts are lexographically sorted. |
| 16 |
-func (container *Container) setupMounts() ([]execdriver.Mount, error) {
|
|
| 17 |
+func (daemon *Daemon) setupMounts(container *Container) ([]execdriver.Mount, error) {
|
|
| 17 | 18 |
var mnts []execdriver.Mount |
| 18 | 19 |
for _, mount := range container.MountPoints { // type is volume.MountPoint
|
| 19 | 20 |
// If there is no source, take it from the volume path |