Merge pull request #29692 from yongtang/29492-daemon-shm-size
Add daemon option `--default-shm-size`
This commit is contained in:
commit
354bd4aadd
20 changed files with 199 additions and 64 deletions
|
@ -106,7 +106,7 @@ type containerOptions struct {
|
|||
stopSignal string
|
||||
stopTimeout int
|
||||
isolation string
|
||||
shmSize string
|
||||
shmSize opts.MemBytes
|
||||
noHealthcheck bool
|
||||
healthCmd string
|
||||
healthInterval time.Duration
|
||||
|
@ -270,7 +270,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
|
|||
flags.StringVar(&copts.ipcMode, "ipc", "", "IPC namespace to use")
|
||||
flags.StringVar(&copts.isolation, "isolation", "", "Container isolation technology")
|
||||
flags.StringVar(&copts.pidMode, "pid", "", "PID namespace to use")
|
||||
flags.StringVar(&copts.shmSize, "shm-size", "", "Size of /dev/shm, default value is 64MB")
|
||||
flags.Var(&copts.shmSize, "shm-size", "Size of /dev/shm")
|
||||
flags.StringVar(&copts.utsMode, "uts", "", "UTS namespace to use")
|
||||
flags.StringVar(&copts.runtime, "runtime", "", "Runtime to use for this container")
|
||||
|
||||
|
@ -349,14 +349,6 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*container.Config, *c
|
|||
return nil, nil, nil, fmt.Errorf("invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
|
||||
}
|
||||
|
||||
var shmSize int64
|
||||
if copts.shmSize != "" {
|
||||
shmSize, err = units.RAMInBytes(copts.shmSize)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO FIXME units.RAMInBytes should have a uint64 version
|
||||
var maxIOBandwidth int64
|
||||
if copts.ioMaxBandwidth != "" {
|
||||
|
@ -629,7 +621,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*container.Config, *c
|
|||
LogConfig: container.LogConfig{Type: copts.loggingDriver, Config: loggingOpts},
|
||||
VolumeDriver: copts.volumeDriver,
|
||||
Isolation: container.Isolation(copts.isolation),
|
||||
ShmSize: shmSize,
|
||||
ShmSize: copts.shmSize.Value(),
|
||||
Resources: resources,
|
||||
Tmpfs: tmpfs,
|
||||
Sysctls: copts.sysctls.GetAll(),
|
||||
|
|
|
@ -411,8 +411,9 @@ func TestParseModes(t *testing.T) {
|
|||
t.Fatalf("Expected a valid UTSMode, got %v", hostconfig.UTSMode)
|
||||
}
|
||||
// shm-size ko
|
||||
if _, _, _, err = parseRun([]string{"--shm-size=a128m", "img", "cmd"}); err == nil || err.Error() != "invalid size: 'a128m'" {
|
||||
t.Fatalf("Expected an error with message 'invalid size: a128m', got %v", err)
|
||||
expectedErr := `invalid argument "a128m" for --shm-size=a128m: invalid size: 'a128m'`
|
||||
if _, _, _, err = parseRun([]string{"--shm-size=a128m", "img", "cmd"}); err == nil || err.Error() != expectedErr {
|
||||
t.Fatalf("Expected an error with message '%v', got %v", expectedErr, err)
|
||||
}
|
||||
// shm-size ok
|
||||
_, hostconfig, _, err = parseRun([]string{"--shm-size=128m", "img", "cmd"})
|
||||
|
|
|
@ -41,7 +41,7 @@ type buildOptions struct {
|
|||
ulimits *opts.UlimitOpt
|
||||
memory string
|
||||
memorySwap string
|
||||
shmSize string
|
||||
shmSize opts.MemBytes
|
||||
cpuShares int64
|
||||
cpuPeriod int64
|
||||
cpuQuota int64
|
||||
|
@ -89,7 +89,7 @@ func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command {
|
|||
flags.StringVarP(&options.dockerfileName, "file", "f", "", "Name of the Dockerfile (Default is 'PATH/Dockerfile')")
|
||||
flags.StringVarP(&options.memory, "memory", "m", "", "Memory limit")
|
||||
flags.StringVar(&options.memorySwap, "memory-swap", "", "Swap limit equal to memory plus swap: '-1' to enable unlimited swap")
|
||||
flags.StringVar(&options.shmSize, "shm-size", "", "Size of /dev/shm, default value is 64MB")
|
||||
flags.Var(&options.shmSize, "shm-size", "Size of /dev/shm")
|
||||
flags.Int64VarP(&options.cpuShares, "cpu-shares", "c", 0, "CPU shares (relative weight)")
|
||||
flags.Int64Var(&options.cpuPeriod, "cpu-period", 0, "Limit the CPU CFS (Completely Fair Scheduler) period")
|
||||
flags.Int64Var(&options.cpuQuota, "cpu-quota", 0, "Limit the CPU CFS (Completely Fair Scheduler) quota")
|
||||
|
@ -274,14 +274,6 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
|
|||
}
|
||||
}
|
||||
|
||||
var shmSize int64
|
||||
if options.shmSize != "" {
|
||||
shmSize, err = units.RAMInBytes(options.shmSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
authConfigs, _ := dockerCli.GetAllCredentials()
|
||||
buildOptions := types.ImageBuildOptions{
|
||||
Memory: memory,
|
||||
|
@ -300,7 +292,7 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
|
|||
CPUPeriod: options.cpuPeriod,
|
||||
CgroupParent: options.cgroupParent,
|
||||
Dockerfile: relDockerfile,
|
||||
ShmSize: shmSize,
|
||||
ShmSize: options.shmSize.Value(),
|
||||
Ulimits: options.ulimits.GetList(),
|
||||
BuildArgs: runconfigopts.ConvertKVStringsToMapWithNil(options.buildArgs.GetAll()),
|
||||
AuthConfigs: authConfigs,
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/docker/docker/opts"
|
||||
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||
"github.com/docker/go-connections/nat"
|
||||
units "github.com/docker/go-units"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -19,26 +18,6 @@ type int64Value interface {
|
|||
Value() int64
|
||||
}
|
||||
|
||||
type memBytes int64
|
||||
|
||||
func (m *memBytes) String() string {
|
||||
return units.BytesSize(float64(m.Value()))
|
||||
}
|
||||
|
||||
func (m *memBytes) Set(value string) error {
|
||||
val, err := units.RAMInBytes(value)
|
||||
*m = memBytes(val)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *memBytes) Type() string {
|
||||
return "bytes"
|
||||
}
|
||||
|
||||
func (m *memBytes) Value() int64 {
|
||||
return int64(*m)
|
||||
}
|
||||
|
||||
// PositiveDurationOpt is an option type for time.Duration that uses a pointer.
|
||||
// It bahave similarly to DurationOpt but only allows positive duration values.
|
||||
type PositiveDurationOpt struct {
|
||||
|
@ -149,9 +128,9 @@ type updateOptions struct {
|
|||
|
||||
type resourceOptions struct {
|
||||
limitCPU opts.NanoCPUs
|
||||
limitMemBytes memBytes
|
||||
limitMemBytes opts.MemBytes
|
||||
resCPU opts.NanoCPUs
|
||||
resMemBytes memBytes
|
||||
resMemBytes opts.MemBytes
|
||||
}
|
||||
|
||||
func (r *resourceOptions) ToResourceRequirements() *swarm.ResourceRequirements {
|
||||
|
|
|
@ -11,12 +11,12 @@ import (
|
|||
)
|
||||
|
||||
func TestMemBytesString(t *testing.T) {
|
||||
var mem memBytes = 1048576
|
||||
var mem opts.MemBytes = 1048576
|
||||
assert.Equal(t, mem.String(), "1 MiB")
|
||||
}
|
||||
|
||||
func TestMemBytesSetAndValue(t *testing.T) {
|
||||
var mem memBytes
|
||||
var mem opts.MemBytes
|
||||
assert.NilError(t, mem.Set("5kb"))
|
||||
assert.Equal(t, mem.Value(), int64(5120))
|
||||
}
|
||||
|
|
|
@ -22,8 +22,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// DefaultSHMSize is the default size (64MB) of the SHM which will be mounted in the container
|
||||
DefaultSHMSize int64 = 67108864
|
||||
containerSecretMountPath = "/run/secrets"
|
||||
)
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ var (
|
|||
defaultPidFile = "/var/run/docker.pid"
|
||||
defaultGraph = "/var/lib/docker"
|
||||
defaultExecRoot = "/var/run/docker"
|
||||
defaultShmSize = int64(67108864)
|
||||
)
|
||||
|
||||
// Config defines the configuration of a docker daemon.
|
||||
|
@ -36,6 +37,7 @@ type Config struct {
|
|||
Init bool `json:"init,omitempty"`
|
||||
InitPath string `json:"init-path,omitempty"`
|
||||
SeccompProfile string `json:"seccomp-profile,omitempty"`
|
||||
ShmSize opts.MemBytes `json:"default-shm-size,omitempty"`
|
||||
}
|
||||
|
||||
// bridgeConfig stores all the bridge driver specific
|
||||
|
@ -66,6 +68,9 @@ func (config *Config) InstallFlags(flags *pflag.FlagSet) {
|
|||
|
||||
config.Ulimits = make(map[string]*units.Ulimit)
|
||||
|
||||
// Set default value for `--default-shm-size`
|
||||
config.ShmSize = opts.MemBytes(defaultShmSize)
|
||||
|
||||
// Then platform-specific install flags
|
||||
flags.BoolVar(&config.EnableSelinuxSupport, "selinux-enabled", false, "Enable selinux support")
|
||||
flags.Var(opts.NewUlimitOpt(&config.Ulimits), "default-ulimit", "Default ulimits for containers")
|
||||
|
@ -89,6 +94,7 @@ func (config *Config) InstallFlags(flags *pflag.FlagSet) {
|
|||
flags.Int64Var(&config.CPURealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds")
|
||||
flags.Int64Var(&config.CPURealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds")
|
||||
flags.StringVar(&config.SeccompProfile, "seccomp-profile", "", "Path to seccomp profile")
|
||||
flags.Var(&config.ShmSize, "default-shm-size", "Default shm size for containers")
|
||||
|
||||
config.attachExperimentalFlags(flags)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,12 @@ package daemon
|
|||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/pkg/testutil/assert"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func TestDaemonConfigurationMerge(t *testing.T) {
|
||||
|
@ -78,3 +83,52 @@ func TestDaemonConfigurationMerge(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDaemonParseShmSize(t *testing.T) {
|
||||
if runtime.GOOS == "solaris" {
|
||||
t.Skip("ShmSize not supported on Solaris\n")
|
||||
}
|
||||
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
|
||||
|
||||
config := &Config{}
|
||||
config.InstallFlags(flags)
|
||||
// By default `--default-shm-size=64M`
|
||||
expectedValue := 64 * 1024 * 1024
|
||||
if config.ShmSize.Value() != int64(expectedValue) {
|
||||
t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value())
|
||||
}
|
||||
assert.NilError(t, flags.Set("default-shm-size", "128M"))
|
||||
expectedValue = 128 * 1024 * 1024
|
||||
if config.ShmSize.Value() != int64(expectedValue) {
|
||||
t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDaemonConfigurationMergeShmSize(t *testing.T) {
|
||||
if runtime.GOOS == "solaris" {
|
||||
t.Skip("ShmSize not supported on Solaris\n")
|
||||
}
|
||||
f, err := ioutil.TempFile("", "docker-config-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
configFile := f.Name()
|
||||
|
||||
f.Write([]byte(`
|
||||
{
|
||||
"default-shm-size": "1g"
|
||||
}`))
|
||||
|
||||
f.Close()
|
||||
|
||||
c := &Config{}
|
||||
cc, err := MergeDaemonConfigurations(c, nil, configFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expectedValue := 1 * 1024 * 1024 * 1024
|
||||
if cc.ShmSize.Value() != int64(expectedValue) {
|
||||
t.Fatalf("expected default shm size %d, got %d", expectedValue, cc.ShmSize.Value())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ func (daemon *Daemon) setupIpcDirs(c *container.Container) error {
|
|||
return err
|
||||
}
|
||||
|
||||
shmSize := container.DefaultSHMSize
|
||||
shmSize := int64(daemon.configStore.ShmSize)
|
||||
if c.HostConfig.ShmSize != 0 {
|
||||
shmSize = c.HostConfig.ShmSize
|
||||
}
|
||||
|
|
|
@ -256,7 +256,10 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf
|
|||
hostConfig.MemorySwap = hostConfig.Memory * 2
|
||||
}
|
||||
if hostConfig.ShmSize == 0 {
|
||||
hostConfig.ShmSize = container.DefaultSHMSize
|
||||
hostConfig.ShmSize = defaultShmSize
|
||||
if daemon.configStore != nil {
|
||||
hostConfig.ShmSize = int64(daemon.configStore.ShmSize)
|
||||
}
|
||||
}
|
||||
var err error
|
||||
opts, err := daemon.generateSecurityOpt(hostConfig.IpcMode, hostConfig.PidMode, hostConfig.Privileged)
|
||||
|
@ -576,6 +579,10 @@ func (daemon *Daemon) platformReload(config *Config) map[string]string {
|
|||
daemon.configStore.DefaultRuntime = config.DefaultRuntime
|
||||
}
|
||||
|
||||
if config.IsValueSet("default-shm-size") {
|
||||
daemon.configStore.ShmSize = config.ShmSize
|
||||
}
|
||||
|
||||
// Update attributes
|
||||
var runtimeList bytes.Buffer
|
||||
for name, rt := range daemon.configStore.Runtimes {
|
||||
|
@ -588,6 +595,7 @@ func (daemon *Daemon) platformReload(config *Config) map[string]string {
|
|||
return map[string]string{
|
||||
"runtimes": runtimeList.String(),
|
||||
"default-runtime": daemon.configStore.DefaultRuntime,
|
||||
"default-shm-size": fmt.Sprintf("%d", daemon.configStore.ShmSize),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ Options:
|
|||
-q, --quiet Suppress the build output and print image ID on success
|
||||
--rm Remove intermediate containers after a successful build (default true)
|
||||
--security-opt value Security Options (default [])
|
||||
--shm-size string Size of /dev/shm, default value is 64MB.
|
||||
--shm-size bytes Size of /dev/shm
|
||||
The format is `<number><unit>`. `number` must be greater than `0`.
|
||||
Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes),
|
||||
or `g` (gigabytes). If you omit the unit, the system uses bytes.
|
||||
|
|
|
@ -107,7 +107,7 @@ Options:
|
|||
--rm Automatically remove the container when it exits
|
||||
--runtime string Runtime to use for this container
|
||||
--security-opt value Security Options (default [])
|
||||
--shm-size string Size of /dev/shm, default value is 64MB.
|
||||
--shm-size bytes Size of /dev/shm
|
||||
The format is `<number><unit>`. `number` must be greater than `0`.
|
||||
Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes),
|
||||
or `g` (gigabytes). If you omit the unit, the system uses bytes.
|
||||
|
|
|
@ -37,6 +37,7 @@ Options:
|
|||
--default-gateway value Container default gateway IPv4 address
|
||||
--default-gateway-v6 value Container default gateway IPv6 address
|
||||
--default-runtime string Default OCI runtime for containers (default "runc")
|
||||
--default-shm-size bytes Set the default shm size for containers (default 64 MiB)
|
||||
--default-ulimit value Default ulimits for containers (default [])
|
||||
--disable-legacy-registry Disable contacting legacy registries
|
||||
--dns value DNS server to use (default [])
|
||||
|
@ -1161,6 +1162,7 @@ This is a full example of the allowed configuration options on Linux:
|
|||
"cluster-advertise": "",
|
||||
"max-concurrent-downloads": 3,
|
||||
"max-concurrent-uploads": 5,
|
||||
"default-shm-size": "64M",
|
||||
"shutdown-timeout": 15,
|
||||
"debug": true,
|
||||
"hosts": [],
|
||||
|
|
|
@ -117,7 +117,7 @@ Options:
|
|||
--rm Automatically remove the container when it exits
|
||||
--runtime string Runtime to use for this container
|
||||
--security-opt value Security Options (default [])
|
||||
--shm-size string Size of /dev/shm, default value is 64MB.
|
||||
--shm-size bytes Size of /dev/shm
|
||||
The format is `<number><unit>`. `number` must be greater than `0`.
|
||||
Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes),
|
||||
or `g` (gigabytes). If you omit the unit, the system uses bytes.
|
||||
|
|
|
@ -39,7 +39,7 @@ Options:
|
|||
--hostname string Container hostname
|
||||
-l, --label list Service labels (default [])
|
||||
--limit-cpu decimal Limit CPUs (default 0.000)
|
||||
--limit-memory bytes Limit Memory (default 0 B)
|
||||
--limit-memory bytes Limit Memory
|
||||
--log-driver string Logging driver for service
|
||||
--log-opt list Logging driver options (default [])
|
||||
--mode string Service mode (replicated or global) (default "replicated")
|
||||
|
@ -51,7 +51,7 @@ Options:
|
|||
--read-only Mount the container's root filesystem as read only
|
||||
--replicas uint Number of tasks
|
||||
--reserve-cpu decimal Reserve CPUs (default 0.000)
|
||||
--reserve-memory bytes Reserve Memory (default 0 B)
|
||||
--reserve-memory bytes Reserve Memory
|
||||
--restart-condition string Restart when condition is met (none, on-failure, or any)
|
||||
--restart-delay duration Delay between restart attempts (ns|us|ms|s|m|h)
|
||||
--restart-max-attempts uint Maximum number of restarts before giving up
|
||||
|
|
|
@ -50,7 +50,7 @@ Options:
|
|||
--label-add list Add or update a service label (default [])
|
||||
--label-rm list Remove a label by its key (default [])
|
||||
--limit-cpu decimal Limit CPUs (default 0.000)
|
||||
--limit-memory bytes Limit Memory (default 0 B)
|
||||
--limit-memory bytes Limit Memory
|
||||
--log-driver string Logging driver for service
|
||||
--log-opt list Logging driver options (default [])
|
||||
--mount-add mount Add or update a mount on a service
|
||||
|
@ -61,7 +61,7 @@ Options:
|
|||
--read-only Mount the container's root filesystem as read only
|
||||
--replicas uint Number of tasks
|
||||
--reserve-cpu decimal Reserve CPUs (default 0.000)
|
||||
--reserve-memory bytes Reserve Memory (default 0 B)
|
||||
--reserve-memory bytes Reserve Memory
|
||||
--restart-condition string Restart when condition is met (none, on-failure, or any)
|
||||
--restart-delay duration Delay between restart attempts (ns|us|ms|s|m|h)
|
||||
--restart-max-attempts uint Maximum number of restarts before giving up
|
||||
|
|
|
@ -2879,3 +2879,60 @@ func (s *DockerDaemonSuite) TestRestartPolicyWithLiveRestore(c *check.C) {
|
|||
out, err = s.d.Cmd("stop", id)
|
||||
c.Assert(err, check.IsNil, check.Commentf("output: %s", out))
|
||||
}
|
||||
|
||||
func (s *DockerDaemonSuite) TestShmSize(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
size := 67108864 * 2
|
||||
pattern := regexp.MustCompile(fmt.Sprintf("shm on /dev/shm type tmpfs(.*)size=%dk", size/1024))
|
||||
|
||||
s.d.StartWithBusybox(c, "--default-shm-size", fmt.Sprintf("%v", size))
|
||||
|
||||
name := "shm1"
|
||||
out, err := s.d.Cmd("run", "--name", name, "busybox", "mount")
|
||||
c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
||||
c.Assert(pattern.MatchString(out), checker.True)
|
||||
out, err = s.d.Cmd("inspect", "--format", "{{.HostConfig.ShmSize}}", name)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
||||
c.Assert(strings.TrimSpace(out), check.Equals, fmt.Sprintf("%v", size))
|
||||
}
|
||||
|
||||
func (s *DockerDaemonSuite) TestShmSizeReload(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
|
||||
configPath, err := ioutil.TempDir("", "test-daemon-shm-size-reload-config")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("could not create temp file for config reload"))
|
||||
defer os.RemoveAll(configPath) // clean up
|
||||
configFile := filepath.Join(configPath, "config.json")
|
||||
|
||||
size := 67108864 * 2
|
||||
configData := []byte(fmt.Sprintf(`{"default-shm-size": "%dM"}`, size/1024/1024))
|
||||
c.Assert(ioutil.WriteFile(configFile, configData, 0666), checker.IsNil, check.Commentf("could not write temp file for config reload"))
|
||||
pattern := regexp.MustCompile(fmt.Sprintf("shm on /dev/shm type tmpfs(.*)size=%dk", size/1024))
|
||||
|
||||
s.d.StartWithBusybox(c, "--config-file", configFile)
|
||||
|
||||
name := "shm1"
|
||||
out, err := s.d.Cmd("run", "--name", name, "busybox", "mount")
|
||||
c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
||||
c.Assert(pattern.MatchString(out), checker.True)
|
||||
out, err = s.d.Cmd("inspect", "--format", "{{.HostConfig.ShmSize}}", name)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
||||
c.Assert(strings.TrimSpace(out), check.Equals, fmt.Sprintf("%v", size))
|
||||
|
||||
size = 67108864 * 3
|
||||
configData = []byte(fmt.Sprintf(`{"default-shm-size": "%dM"}`, size/1024/1024))
|
||||
c.Assert(ioutil.WriteFile(configFile, configData, 0666), checker.IsNil, check.Commentf("could not write temp file for config reload"))
|
||||
pattern = regexp.MustCompile(fmt.Sprintf("shm on /dev/shm type tmpfs(.*)size=%dk", size/1024))
|
||||
|
||||
err = s.d.ReloadConfig()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error reloading daemon config"))
|
||||
|
||||
name = "shm2"
|
||||
out, err = s.d.Cmd("run", "--name", name, "busybox", "mount")
|
||||
c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
||||
c.Assert(pattern.MatchString(out), checker.True)
|
||||
out, err = s.d.Cmd("inspect", "--format", "{{.HostConfig.ShmSize}}", name)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
||||
c.Assert(strings.TrimSpace(out), check.Equals, fmt.Sprintf("%v", size))
|
||||
}
|
||||
|
|
|
@ -427,7 +427,7 @@ func (s *DockerDaemonSuite) TestDaemonEvents(c *check.C) {
|
|||
out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s (cluster-advertise=, cluster-store=, cluster-store-opts={}, debug=true, default-runtime=runc, insecure-registries=[], labels=[\"bar=foo\"], live-restore=false, max-concurrent-downloads=1, max-concurrent-uploads=5, name=%s, registry-mirrors=[], runtimes=runc:{docker-runc []}, shutdown-timeout=10)", daemonID, daemonName))
|
||||
c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s (cluster-advertise=, cluster-store=, cluster-store-opts={}, debug=true, default-runtime=runc, default-shm-size=67108864, insecure-registries=[], labels=[\"bar=foo\"], live-restore=false, max-concurrent-downloads=1, max-concurrent-uploads=5, name=%s, registry-mirrors=[], runtimes=runc:{docker-runc []}, shutdown-timeout=10)", daemonID, daemonName))
|
||||
}
|
||||
|
||||
func (s *DockerDaemonSuite) TestDaemonEventsWithFilters(c *check.C) {
|
||||
|
|
|
@ -21,6 +21,7 @@ dockerd - Enable daemon mode
|
|||
[**--default-gateway**[=*DEFAULT-GATEWAY*]]
|
||||
[**--default-gateway-v6**[=*DEFAULT-GATEWAY-V6*]]
|
||||
[**--default-runtime**[=*runc*]]
|
||||
[**--default-shm-size**[=*64MiB*]]
|
||||
[**--default-ulimit**[=*[]*]]
|
||||
[**--disable-legacy-registry**]
|
||||
[**--dns**[=*[]*]]
|
||||
|
@ -164,6 +165,9 @@ $ sudo dockerd --add-runtime runc=runc --add-runtime custom=/usr/local/bin/my-ru
|
|||
**--default-runtime**="runc"
|
||||
Set default runtime if there're more than one specified by `--add-runtime`.
|
||||
|
||||
**--default-shm-size**=*64MiB*
|
||||
Set the daemon-wide default shm size for containers. Default is `64MiB`.
|
||||
|
||||
**--default-ulimit**=[]
|
||||
Default ulimits for containers.
|
||||
|
||||
|
|
42
opts/opts.go
42
opts/opts.go
|
@ -9,6 +9,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
units "github.com/docker/go-units"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -402,3 +403,44 @@ func ValidateLink(val string) (string, error) {
|
|||
_, _, err := ParseLink(val)
|
||||
return val, err
|
||||
}
|
||||
|
||||
// MemBytes is a type for human readable memory bytes (like 128M, 2g, etc)
|
||||
type MemBytes int64
|
||||
|
||||
// String returns the string format of the human readable memory bytes
|
||||
func (m *MemBytes) String() string {
|
||||
// NOTE: In spf13/pflag/flag.go, "0" is considered as "zero value" while "0 B" is not.
|
||||
// We return "0" in case value is 0 here so that the default value is hidden.
|
||||
// (Sometimes "default 0 B" is actually misleading)
|
||||
if m.Value() != 0 {
|
||||
return units.BytesSize(float64(m.Value()))
|
||||
}
|
||||
return "0"
|
||||
}
|
||||
|
||||
// Set sets the value of the MemBytes by passing a string
|
||||
func (m *MemBytes) Set(value string) error {
|
||||
val, err := units.RAMInBytes(value)
|
||||
*m = MemBytes(val)
|
||||
return err
|
||||
}
|
||||
|
||||
// Type returns the type
|
||||
func (m *MemBytes) Type() string {
|
||||
return "bytes"
|
||||
}
|
||||
|
||||
// Value returns the value in int64
|
||||
func (m *MemBytes) Value() int64 {
|
||||
return int64(*m)
|
||||
}
|
||||
|
||||
// UnmarshalJSON is the customized unmarshaler for MemBytes
|
||||
func (m *MemBytes) UnmarshalJSON(s []byte) error {
|
||||
if len(s) <= 2 || s[0] != '"' || s[len(s)-1] != '"' {
|
||||
return fmt.Errorf("invalid size: %q", s)
|
||||
}
|
||||
val, err := units.RAMInBytes(string(s[1 : len(s)-1]))
|
||||
*m = MemBytes(val)
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue