diff options
-rw-r--r-- | cmd/podman/common/specgen.go | 5 | ||||
-rw-r--r-- | cmd/podman/common/volumes.go | 2 | ||||
-rw-r--r-- | cmd/podman/images/build.go | 10 | ||||
-rw-r--r-- | docs/source/markdown/podman-build.1.md | 15 | ||||
-rw-r--r-- | docs/source/markdown/podman-create.1.md | 19 | ||||
-rw-r--r-- | docs/source/markdown/podman-run.1.md | 17 | ||||
-rw-r--r-- | libpod/container_inspect.go | 2 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 2 | ||||
-rw-r--r-- | libpod/kube.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/play.go | 9 | ||||
-rw-r--r-- | pkg/spec/storage.go | 2 | ||||
-rw-r--r-- | pkg/util/mountOpts.go | 2 | ||||
-rw-r--r-- | pkg/util/utils.go | 23 | ||||
-rw-r--r-- | pkg/util/utils_test.go | 20 |
14 files changed, 81 insertions, 49 deletions
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go index bd3e5fafd..ca1e25be1 100644 --- a/cmd/podman/common/specgen.go +++ b/cmd/podman/common/specgen.go @@ -25,11 +25,8 @@ func getCPULimits(c *ContainerCLIOpts) *specs.LinuxCPU { cpu := &specs.LinuxCPU{} hasLimits := false - const cpuPeriod = 100000 - if c.CPUS > 0 { - quota := int64(c.CPUS * cpuPeriod) - period := uint64(cpuPeriod) + period, quota := util.CoresToPeriodAndQuota(c.CPUS) cpu.Period = &period cpu.Quota = "a diff --git a/cmd/podman/common/volumes.go b/cmd/podman/common/volumes.go index 8ab20ccae..b3c160ddf 100644 --- a/cmd/podman/common/volumes.go +++ b/cmd/podman/common/volumes.go @@ -313,7 +313,7 @@ func getBindMount(args []string) (spec.Mount, error) { } setExec = true newMount.Options = append(newMount.Options, kv[0]) - case "shared", "rshared", "private", "rprivate", "slave", "rslave", "Z", "z": + case "shared", "rshared", "private", "rprivate", "slave", "rslave", "unbindable", "runbindable", "Z", "z": newMount.Options = append(newMount.Options, kv[0]) case "bind-propagation": if len(kv) == 1 { diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index 0ff482cd9..f48d1cd94 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -240,13 +240,9 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil } } - pullPolicy := imagebuildah.PullIfNewer - if c.Flags().Changed("pull") { - if flags.Pull { - pullPolicy = imagebuildah.PullAlways - } else { - pullPolicy = imagebuildah.PullNever - } + pullPolicy := imagebuildah.PullIfMissing + if c.Flags().Changed("pull") && flags.Pull { + pullPolicy = imagebuildah.PullAlways } if flags.PullAlways { pullPolicy = imagebuildah.PullAlways diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md index f1fddb2fc..1e1e1d27e 100644 --- a/docs/source/markdown/podman-build.1.md +++ b/docs/source/markdown/podman-build.1.md @@ -384,16 +384,13 @@ not required for Buildah as it supports only Linux. **--pull** -When the flag is enabled, attempt to pull the latest image from the registries -listed in registries.conf if a local image does not exist or the image is newer -than the one in storage. Raise an error if the image is not in any listed -registry and is not present locally. +When the option is specified or set to "true", pull the image from the first registry +it is found in as listed in registries.conf. Raise an error if not found in the +registries, even if the image is present locally. -If the flag is disabled (with *--pull=false*), do not pull the image from the -registry, unless there is no local image. Raise an error if the image is not -in any registry and is not present locally. - -Defaults to *true*. +If the option is disabled (with *--pull=false*), or not specified, pull the image +from the registry only if the image is not present locally. Raise an error if the image +is not found in the registries. **--pull-always** diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index f823ac565..e243a5842 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -541,7 +541,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and · ro, readonly: true or false (default). - · bind-propagation: shared, slave, private, rshared, rslave, or rprivate(default). See also mount(2). + · bind-propagation: shared, slave, private, unbindable, rshared, rslave, runbindable, or rprivate(default). See also mount(2). . bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive. @@ -962,7 +962,7 @@ The _options_ is a comma delimited list and can be: * **rw**|**ro** * **z**|**Z** -* [**r**]**shared**|[**r**]**slave**|[**r**]**private** +* [**r**]**shared**|[**r**]**slave**|[**r**]**private**[**r**]**unbindable** * [**r**]**bind** * [**no**]**exec** * [**no**]**dev** @@ -1048,13 +1048,14 @@ visible on host and vice versa. Making a volume `slave` enables only one way mount propagation and that is mounts done on host under that volume will be visible inside container but not the other way around. <sup>[[1]](#Footnote1)</sup> -To control mount propagation property of volume one can use `:[r]shared`, -`:[r]slave` or `:[r]private` propagation flag. Propagation property can -be specified only for bind mounted volumes and not for internal volumes or -named volumes. For mount propagation to work source mount point (mount point -where source dir is mounted on) has to have right propagation properties. For -shared volumes, source mount point has to be shared. And for slave volumes, -source mount has to be either shared or slave. <sup>[[1]](#Footnote1)</sup> +To control mount propagation property of a volume one can use the [**r**]**shared**, +[**r**]**slave**, [**r**]**private** or the [**r**]**unbindable** propagation flag. +Propagation property can be specified only for bind mounted volumes and not for +internal volumes or named volumes. For mount propagation to work the source mount +point (the mount point where source dir is mounted on) has to have the right propagation +properties. For shared volumes, the source mount point has to be shared. And for +slave volumes, the source mount point has to be either shared or slave. +<sup>[[1]](#Footnote1)</sup> If you want to recursively mount a volume and all of its submounts into a container, then you can use the `rbind` option. By default the bind option is diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 71f77d307..0166a344a 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -567,7 +567,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and · ro, readonly: true or false (default). - · bind-propagation: shared, slave, private, rshared, rslave, or rprivate(default). See also mount(2). + · bind-propagation: shared, slave, private, unbindable, rshared, rslave, runbindable, or rprivate(default). See also mount(2). . bind-nonrecursive: do not setup a recursive bind mount. By default it is recursive. @@ -1015,7 +1015,7 @@ The _options_ is a comma delimited list and can be: <sup>[[1]](#Footnote1)</sup> * **rw**|**ro** * **z**|**Z** -* [**r**]**shared**|[**r**]**slave**|[**r**]**private** +* [**r**]**shared**|[**r**]**slave**|[**r**]**private**[**r**]**unbindable** * [**r**]**bind** * [**no**]**exec** * [**no**]**dev** @@ -1099,12 +1099,13 @@ way mount propagation and that is mounts done on host under that volume will be visible inside container but not the other way around. <sup>[[1]](#Footnote1)</sup> To control mount propagation property of volume one can use [**r**]**shared**, -[**r**]**slave** or [**r**]**private** propagation flag. Propagation property can -be specified only for bind mounted volumes and not for internal volumes or -named volumes. For mount propagation to work source mount point (mount point -where source dir is mounted on) has to have right propagation properties. For -shared volumes, source mount point has to be shared. And for slave volumes, -source mount has to be either shared or slave. <sup>[[1]](#Footnote1)</sup> +[**r**]**slave**, [**r**]**private** or [**r**]**unbindable** propagation flag. +Propagation property can be specified only for bind mounted volumes and not for +internal volumes or named volumes. For mount propagation to work source mount +point (mount point where source dir is mounted on) has to have right propagation +properties. For shared volumes, source mount point has to be shared. And for +slave volumes, source mount has to be either shared or slave. +<sup>[[1]](#Footnote1)</sup> If you want to recursively mount a volume and all of its submounts into a container, then you can use the **rbind** option. By default the bind option is diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 162f70326..f78d74ef7 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -270,7 +270,7 @@ func parseMountOptionsForInspect(options []string, mount *define.InspectMount) { isRW = false case "rw": // Do nothing, silently discard - case "shared", "slave", "private", "rshared", "rslave", "rprivate": + case "shared", "slave", "private", "rshared", "rslave", "rprivate", "unbindable", "runbindable": mountProp = opt case "z", "Z": zZ = opt diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index bf74ca954..83d5c20cb 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -344,7 +344,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { Type: "bind", Source: srcPath, Destination: dstPath, - Options: []string{"bind", "private"}, + Options: []string{"bind", "rprivate"}, } if c.IsReadOnly() && dstPath != "/dev/shm" { newMount.Options = append(newMount.Options, "ro", "nosuid", "noexec", "nodev") diff --git a/libpod/kube.go b/libpod/kube.go index cd5064c84..067e7827d 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -327,7 +327,7 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, error) { period := *c.config.Spec.Linux.Resources.CPU.Period if quota > 0 && period > 0 { - cpuLimitMilli := int64(1000 * float64(quota) / float64(period)) + cpuLimitMilli := int64(1000 * util.PeriodAndQuotaToCores(period, quota)) // Kubernetes: precision finer than 1m is not allowed if cpuLimitMilli >= 1 { diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 57de0f3b1..fbba00984 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -36,8 +36,6 @@ const ( kubeDirectoryPermission = 0755 // https://kubernetes.io/docs/concepts/storage/volumes/#hostpath kubeFilePermission = 0644 - // Kubernetes sets CPUPeriod to 100000us (100ms): https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/ - defaultCPUPeriod = 100000 ) func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options entities.PlayKubeOptions) (*entities.PlayKubeReport, error) { @@ -515,10 +513,9 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container return nil, errors.Wrap(err, "Failed to set CPU quota") } if milliCPU > 0 { - containerConfig.Resources.CPUPeriod = defaultCPUPeriod - // CPU quota is a fraction of the period: milliCPU / 1000.0 * period - // Or, without floating point math: - containerConfig.Resources.CPUQuota = milliCPU * defaultCPUPeriod / 1000 + period, quota := util.CoresToPeriodAndQuota(float64(milliCPU) / 1000) + containerConfig.Resources.CPUPeriod = period + containerConfig.Resources.CPUQuota = quota } containerConfig.Resources.Memory, err = quantityToInt64(containerYAML.Resources.Limits.Memory()) diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go index ebf5ec196..b441daf08 100644 --- a/pkg/spec/storage.go +++ b/pkg/spec/storage.go @@ -445,7 +445,7 @@ func getBindMount(args []string) (spec.Mount, error) { } setExec = true newMount.Options = append(newMount.Options, kv[0]) - case "shared", "rshared", "private", "rprivate", "slave", "rslave", "Z", "z": + case "shared", "rshared", "private", "rprivate", "slave", "rslave", "unbindable", "runbindable", "Z", "z": newMount.Options = append(newMount.Options, kv[0]) case "bind-propagation": if len(kv) == 1 { diff --git a/pkg/util/mountOpts.go b/pkg/util/mountOpts.go index eab2657e3..580aaf4f2 100644 --- a/pkg/util/mountOpts.go +++ b/pkg/util/mountOpts.go @@ -57,7 +57,7 @@ func ProcessOptions(options []string, isTmpfs bool, sourcePath string) ([]string return nil, errors.Wrapf(ErrDupeMntOption, "only one of 'rw' and 'ro' can be used") } foundWrite = true - case "private", "rprivate", "slave", "rslave", "shared", "rshared": + case "private", "rprivate", "slave", "rslave", "shared", "rshared", "unbindable", "runbindable": if foundProp { return nil, errors.Wrapf(ErrDupeMntOption, "only one root propagation mode can be used") } diff --git a/pkg/util/utils.go b/pkg/util/utils.go index a9aad657d..415fd169b 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -653,3 +653,26 @@ func CreateCidFile(cidfile string, id string) error { cidFile.Close() return nil } + +// DefaultCPUPeriod is the default CPU period is 100us, which is the same default +// as Kubernetes. +const DefaultCPUPeriod uint64 = 100000 + +// CoresToPeriodAndQuota converts a fraction of cores to the equivalent +// Completely Fair Scheduler (CFS) parameters period and quota. +// +// Cores is a fraction of the CFS period that a container may use. Period and +// Quota are in microseconds. +func CoresToPeriodAndQuota(cores float64) (uint64, int64) { + return DefaultCPUPeriod, int64(cores * float64(DefaultCPUPeriod)) +} + +// PeriodAndQuotaToCores takes the CFS parameters period and quota and returns +// a fraction that represents the limit to the number of cores that can be +// utilized over the scheduling period. +// +// Cores is a fraction of the CFS period that a container may use. Period and +// Quota are in microseconds. +func PeriodAndQuotaToCores(period uint64, quota int64) float64 { + return float64(quota) / float64(period) +} diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go index a9b37844e..cb737bd76 100644 --- a/pkg/util/utils_test.go +++ b/pkg/util/utils_test.go @@ -257,3 +257,23 @@ func TestValidateSysctlBadSysctl(t *testing.T) { _, err := ValidateSysctls(strSlice) assert.Error(t, err) } + +func TestCoresToPeriodAndQuota(t *testing.T) { + cores := 1.0 + expectedPeriod := DefaultCPUPeriod + expectedQuota := int64(DefaultCPUPeriod) + + actualPeriod, actualQuota := CoresToPeriodAndQuota(cores) + assert.Equal(t, actualPeriod, expectedPeriod, "Period does not match") + assert.Equal(t, actualQuota, expectedQuota, "Quota does not match") +} + +func TestPeriodAndQuotaToCores(t *testing.T) { + var ( + period uint64 = 100000 + quota int64 = 50000 + expectedCores = 0.5 + ) + + assert.Equal(t, PeriodAndQuotaToCores(period, quota), expectedCores) +} |