4f0d95fa |
package container // import "github.com/docker/docker/container" |
6bb0d181 |
import ( |
ff3ea4c9 |
"fmt" |
67912303 |
"os"
"path/filepath"
|
cfc404a3 |
"github.com/docker/docker/api/types" |
91e197d6 |
containertypes "github.com/docker/docker/api/types/container" |
c0217180 |
swarmtypes "github.com/docker/docker/api/types/swarm" |
bd4e8aa6 |
"github.com/docker/docker/pkg/system" |
6bb0d181 |
)
|
67d282a5 |
const ( |
bd4e8aa6 |
containerSecretMountPath = `C:\ProgramData\Docker\secrets`
containerInternalSecretMountPath = `C:\ProgramData\Docker\internal\secrets` |
e0d533b1 |
containerInternalConfigsDirPath = `C:\ProgramData\Docker\internal\configs` |
ed74ee12 |
// DefaultStopTimeout is the timeout (in seconds) for the shutdown call on a container
DefaultStopTimeout = 30 |
67d282a5 |
)
|
7120976d |
// UnmountIpcMount unmounts Ipc related mounts. |
6bb0d181 |
// This is a NOOP on windows. |
77bc327e |
func (container *Container) UnmountIpcMount() error { |
7120976d |
return nil |
6bb0d181 |
}
// IpcMounts returns the list of Ipc related mounts. |
94d70d83 |
func (container *Container) IpcMounts() []Mount { |
6bb0d181 |
return nil
}
|
bd4e8aa6 |
// CreateSecretSymlinks creates symlinks to files in the secret mount.
func (container *Container) CreateSecretSymlinks() error {
for _, r := range container.SecretReferences {
if r.File == nil {
continue
}
resolvedPath, _, err := container.ResolvePath(getSecretTargetPath(r))
if err != nil {
return err
} |
ed10ac6e |
if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil { |
bd4e8aa6 |
return err
}
if err := os.Symlink(filepath.Join(containerInternalSecretMountPath, r.SecretID), resolvedPath); err != nil {
return err
}
}
|
72c1d7f4 |
return nil
}
|
bd4e8aa6 |
// SecretMounts returns the mount for the secret path.
// All secrets are stored in a single mount on Windows. Target symlinks are
// created for each secret, pointing to the files in this mount. |
eaa51928 |
func (container *Container) SecretMounts() ([]Mount, error) { |
bd4e8aa6 |
var mounts []Mount
if len(container.SecretReferences) > 0 { |
eaa51928 |
src, err := container.SecretMountPath()
if err != nil {
return nil, err
} |
bd4e8aa6 |
mounts = append(mounts, Mount{ |
eaa51928 |
Source: src, |
bd4e8aa6 |
Destination: containerInternalSecretMountPath,
Writable: false,
})
}
|
eaa51928 |
return mounts, nil |
bd4e8aa6 |
}
|
72c1d7f4 |
// UnmountSecrets unmounts the fs for secrets
func (container *Container) UnmountSecrets() error { |
eaa51928 |
p, err := container.SecretMountPath()
if err != nil {
return err
}
return os.RemoveAll(p) |
72c1d7f4 |
}
|
e0d533b1 |
// CreateConfigSymlinks creates symlinks to files in the config mount.
func (container *Container) CreateConfigSymlinks() error {
for _, configRef := range container.ConfigReferences {
if configRef.File == nil {
continue
}
resolvedPath, _, err := container.ResolvePath(configRef.File.Name)
if err != nil {
return err
} |
ed10ac6e |
if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil { |
e0d533b1 |
return err
}
if err := os.Symlink(filepath.Join(containerInternalConfigsDirPath, configRef.ConfigID), resolvedPath); err != nil {
return err
}
}
return nil
}
// ConfigMounts returns the mount for configs. |
c0217180 |
// TODO: Right now Windows doesn't really have a "secure" storage for secrets,
// however some configs may contain secrets. Once secure storage is worked out,
// configs and secret handling should be merged.
func (container *Container) ConfigMounts() []Mount { |
e0d533b1 |
var mounts []Mount
if len(container.ConfigReferences) > 0 {
mounts = append(mounts, Mount{ |
c0217180 |
Source: container.ConfigsDirPath(), |
e0d533b1 |
Destination: containerInternalConfigsDirPath,
Writable: false,
})
}
|
c0217180 |
return mounts |
e0d533b1 |
}
|
9a2d0bc3 |
// DetachAndUnmount unmounts all volumes.
// On Windows it only delegates to `UnmountVolumes` since there is nothing to
// force unmount.
func (container *Container) DetachAndUnmount(volumeEventLog func(name, action string, attributes map[string]string)) error {
return container.UnmountVolumes(volumeEventLog) |
6bb0d181 |
}
// TmpfsMounts returns the list of tmpfs mounts |
18768fdc |
func (container *Container) TmpfsMounts() ([]Mount, error) { |
756f6cef |
var mounts []Mount |
18768fdc |
return mounts, nil |
6bb0d181 |
}
|
eed4c7b7 |
// UpdateContainer updates configuration of a container. Callers must hold a Lock on the Container. |
5849a553 |
func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfig) error { |
ff3ea4c9 |
resources := hostConfig.Resources |
e5070663 |
if resources.CPUShares != 0 ||
resources.Memory != 0 ||
resources.NanoCPUs != 0 ||
resources.CgroupParent != "" ||
resources.BlkioWeight != 0 ||
len(resources.BlkioWeightDevice) != 0 ||
len(resources.BlkioDeviceReadBps) != 0 ||
len(resources.BlkioDeviceWriteBps) != 0 ||
len(resources.BlkioDeviceReadIOps) != 0 ||
len(resources.BlkioDeviceWriteIOps) != 0 ||
resources.CPUPeriod != 0 ||
resources.CPUQuota != 0 ||
resources.CPURealtimePeriod != 0 ||
resources.CPURealtimeRuntime != 0 ||
resources.CpusetCpus != "" ||
resources.CpusetMems != "" ||
len(resources.Devices) != 0 ||
len(resources.DeviceCgroupRules) != 0 ||
resources.KernelMemory != 0 ||
resources.MemoryReservation != 0 ||
resources.MemorySwap != 0 ||
resources.MemorySwappiness != nil ||
resources.OomKillDisable != nil || |
74eb258f |
(resources.PidsLimit != nil && *resources.PidsLimit != 0) || |
e5070663 |
len(resources.Ulimits) != 0 ||
resources.CPUCount != 0 ||
resources.CPUPercent != 0 ||
resources.IOMaximumIOps != 0 ||
resources.IOMaximumBandwidth != 0 {
return fmt.Errorf("resource updating isn't supported on Windows") |
ff3ea4c9 |
}
// update HostConfig of container
if hostConfig.RestartPolicy.Name != "" { |
4754c64a |
if container.HostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
return fmt.Errorf("Restart policy cannot be updated because AutoRemove is enabled for the container")
} |
ff3ea4c9 |
container.HostConfig.RestartPolicy = hostConfig.RestartPolicy
} |
8799c4fc |
return nil
}
|
e8026d8a |
// BuildHostnameFile writes the container's hostname file.
func (container *Container) BuildHostnameFile() error {
return nil
}
|
cfc404a3 |
// GetMountPoints gives a platform specific transformation to types.MountPoint. Callers must hold a Container lock.
func (container *Container) GetMountPoints() []types.MountPoint {
mountPoints := make([]types.MountPoint, 0, len(container.MountPoints))
for _, m := range container.MountPoints {
mountPoints = append(mountPoints, types.MountPoint{
Type: m.Type,
Name: m.Name,
Source: m.Path(),
Destination: m.Destination,
Driver: m.Driver,
RW: m.RW,
})
}
return mountPoints
} |
c0217180 |
func (container *Container) ConfigsDirPath() string {
return filepath.Join(container.Root, "configs")
}
// ConfigFilePath returns the path to the on-disk location of a config.
func (container *Container) ConfigFilePath(configRef swarmtypes.ConfigReference) string {
return filepath.Join(container.ConfigsDirPath(), configRef.ConfigID)
} |