diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | RELEASE_NOTES.md | 97 | ||||
-rw-r--r-- | cmd/podman/common/create.go | 2 | ||||
-rw-r--r-- | cmd/podman/containers/create.go | 4 | ||||
-rw-r--r-- | docs/source/markdown/podman-create.1.md | 2 | ||||
-rw-r--r-- | docs/source/markdown/podman-run.1.md | 2 | ||||
-rw-r--r-- | libpod/define/config.go | 3 | ||||
-rw-r--r-- | libpod/kube.go | 51 | ||||
-rw-r--r-- | libpod/reset.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/play.go | 2 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/kube.go | 13 | ||||
-rw-r--r-- | pkg/specgen/generate/validate.go | 3 | ||||
-rw-r--r-- | test/e2e/generate_kube_test.go | 11 | ||||
-rw-r--r-- | test/e2e/play_kube_test.go | 33 |
14 files changed, 199 insertions, 28 deletions
@@ -5,7 +5,7 @@ Podman (the POD MANager) is a tool for managing containers and images, volumes mounted into those containers, and pods made from groups of containers. Podman is based on libpod, a library for container lifecycle management that is also contained in this repository. The libpod library provides APIs for managing containers, pods, container images, and volumes. -* [Latest Version: 3.3.1](https://github.com/containers/podman/releases/latest) +* [Latest Version: 3.4.0](https://github.com/containers/podman/releases/latest) * Latest Remote client for Windows * Latest Remote client for macOS * Latest Static Remote client for Linux diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b9b94dbb3..ef48df291 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,102 @@ # Release Notes +## 3.4.0 +### Features +- Pods now support init containers! Init containers are containers which run before the rest of the pod starts. There are two types of init containers: "always", which always run before the pod is started, and "once", which only run the first time the pod starts and are subsequently removed. They can be added using the `podman create` command's `--init-ctr` option. +- Support for init containers has also been added to `podman play kube` and `podman generate kube` - init containers contained in Kubernetes YAML will be created as Podman init containers, and YAML generated by Podman will include any init containers created. +- The `podman play kube` command now supports building images. If the `--build` option is given and a directory with the name of the specified image exists in the current working directory and contains a valid Containerfile or Dockerfile, the image will be built and used for the container. +- The `podman play kube` command now supports a new option, `--teardown`, which removes any pods and containers created by the given Kubernetes YAML. +- The `podman generate kube` command now generates annotations for SELinux mount options on volume (`:z` and `:Z`) that are respected by the `podman play kube` command. +- A new command has been added, `podman pod logs`, to return logs for all containers in a pod at the same time. +- Two new commands have been added, `podman volume export` (to export a volume to a tar file) and `podman volume import`) (to populate a volume from a given tar file). +- The `podman auto-update` command now supports simple rollbacks. If a container fails to start after an automatic update, it will be rolled back to the previous image and restarted again. +- Pods now share their user namespace by default, and the `podman pod create` command now supports the `--userns` option. This allows rootless pods to be created with the `--userns=keep-id` option. +- The `podman pod ps` command now supports a new filter with its `--filter` option, `until`, which returns pods created before a given timestamp. +- The `podman image scp` command has been added. This command allows images to be transferred between different hosts. +- The `podman stats` command supports a new option, `--interval`, to specify the amount of time before the information is refreshed. +- The `podman inspect` command now includes ports exposed (but not published) by containers (e.g. ports from `--expose` when `--publish-all` is not specified). +- The `podman inspect` command now has a new boolean value, `Checkpointed`, which indicates that a container was stopped as a result of a `podman container checkpoint` operation. +- Volumes created by `podman volume create` now support setting quotas when run atop XFS. The `size` and `inode` options allow the maximum size and maximum number of inodes consumed by a volume to be limited. +- The `podman info` command now outputs information on what log drivers, network drivers, and volume plugins are available for use ([#11265](https://github.com/containers/podman/issues/11265)). +- The `podman info` command now outputs the current log driver in use, and the variant and codename of the distribution in use. +- The parameters of the VM created by `podman machine init` (amount of disk space, memory, CPUs) can now be set in `containers.conf`. +- The `podman machine ls` command now shows additional information (CPUs, memory, disk size) about VMs managed by `podman machine`. +- The `podman ps` command now includes healthcheck status in container state for containers that have healthchecks ([#11527](https://github.com/containers/podman/issues/11527)). + +### Changes +- The `podman build` command has a new alias, `podman buildx`, to improve compatibility with Docker. We have already added support for many `docker buildx` flags to `podman build` and aim to continue to do so. +- Cases where Podman is run without a user session or a writable temporary files directory will now produce better error messages. +- The default log driver has been changed from `file` to `journald`. The `file` driver did not properly support log rotation, so this should lead to a better experience. If journald is not available on the system, Podman will automatically revert to the `file`. +- Podman no longer depends on `ip` for removing networks ([#11403](https://github.com/containers/podman/issues/11403)). +- The deprecated `--macvlan` flag to `podman network create` now warns when it is used. It will be removed entirely in the Podman 4.0 release. +- The `podman machine start` command now prints a message when the VM is successfully started. +- The `podman stats` command can now be used on containers that are paused. +- The `podman unshare` command will now return the exit code of the command that was run in the user namespace (assuming the command was successfully run). +- Successful healthchecks will no longer add a `healthy` line to the system log to reduce log spam. +- As a temporary workaround for a lack of shortname prompts in the Podman remote client, VMs created by `podman machine` now default to only using the `docker.io` registry. + +### Bugfixes +- Fixed a bug where whitespace in the definition of sysctls (particularly default sysctls specified in `containers.conf`) would cause them to be parsed incorrectly. +- Fixed a bug where the Windows remote client improperly validated volume paths ([#10900](https://github.com/containers/podman/issues/10900)). +- Fixed a bug where the first line of logs from a container run with the `journald` log driver could be skipped. +- Fixed a bug where images created by `podman commit` did not include ports exposed by the container. +- Fixed a bug where the `podman auto-update` command would ignore the `io.containers.autoupdate.authfile` label when pulling images ([#11171](https://github.com/containers/podman/issues/11171)). +- Fixed a bug where the `--workdir` option to `podman create` and `podman run` could not be set to a directory where a volume was mounted ([#11352](https://github.com/containers/podman/issues/11352)). +- Fixed a bug where systemd socket-activation did not properly work with systemd-managed Podman containers ([#10443](https://github.com/containers/podman/issues/10443)). +- Fixed a bug where environment variable secrets added to a container were not available to exec sessions launched in the container. +- Fixed a bug where rootless containers could fail to start the `rootlessport` port-forwarding service when `XDG_RUNTIME_DIR` was set to a long path. +- Fixed a bug where arguments to the `--systemd` option to `podman create` and `podman run` were case-sensitive ([#11387](https://github.com/containers/podman/issues/11387)). +- Fixed a bug where the `podman manifest rm` command would also remove images referenced by the manifest, not just the manifest itself ([#11344](https://github.com/containers/podman/issues/11344)). +- Fixed a bug where the Podman remote client on OS X would not function properly if the `TMPDIR` environment variable was not set ([#11418](https://github.com/containers/podman/issues/11418)). +- Fixed a bug where the `/etc/hosts` file was not guaranteed to contain an entry for `localhost` (this is still not guaranteed if `--net=host` is used; such containers will exactly match the host's `/etc/hosts`) ([#11411](https://github.com/containers/podman/issues/11411)). +- Fixed a bug where the `podman machine start` command could print warnings about unsupported CPU features ([#11421](https://github.com/containers/podman/issues/11421)). +- Fixed a bug where the `podman info` command could segfault when accessing cgroup information. +- Fixed a bug where the `podman logs -f` command could hang when a container exited ([#11461](https://github.com/containers/podman/issues/11461)). +- Fixed a bug where the `podman generate systemd` command could not be used on containers that specified a restart policy ([#11438](https://github.com/containers/podman/issues/11438)). +- Fixed a bug where the remote Podman client's `podman build` command would fail to build containers if the UID and GID on the client were higher than 65536 ([#11474](https://github.com/containers/podman/issues/11474)). +- Fixed a bug where the remote Podman client's `podman build` command would fail to build containers if the context directory was a symlink ([#11732](https://github.com/containers/podman/issues/11732)). +- Fixed a bug where the `--network` flag to `podman play kube` was not properly parsed when a non-bridge network configuration was specified. +- Fixed a bug where the `podman inspect` command could error when the container being inspected was removed as it was being inspected ([#11392](https://github.com/containers/podman/issues/11392)). +- Fixed a bug where the `podman play kube` command ignored the default pod infra image specified in `containers.conf`. +- Fixed a bug where the `--format` option to `podman inspect` was nonfunctional under some circumstances ([#8785](https://github.com/containers/podman/issues/8785)). +- Fixed a bug where the remote Podman client's `podman run` and `podman exec` commands could skip a byte of output every 8192 bytes ([#11496](https://github.com/containers/podman/issues/11496)). +- Fixed a bug where the `podman stats` command would print nonsensical results if the container restarted while it was running ([#11469](https://github.com/containers/podman/issues/11469)). +- Fixed a bug where the remote Podman client would error when STDOUT was redirected on a Windows client ([#11444](https://github.com/containers/podman/issues/11444)). +- Fixed a bug where the `podman run` command could return 0 when the application in the container exited with 125 ([#11540](https://github.com/containers/podman/issues/11540)). +- Fixed a bug where containers with `--restart=always` set using the rootlessport port-forwarding service could not be restarted automatically. +- Fixed a bug where the `--cgroups=split` option to `podman create` and `podman run` was silently discarded if the container was part of a pod. +- Fixed a bug where the `podman container runlabel` command could fail if the image name given included a tag. +- Fixed a bug where Podman could add an extra `127.0.0.1` entry to `/etc/hosts` under some circumstances ([#11596](https://github.com/containers/podman/issues/11596)). +- Fixed a bug where the remote Podman client's `podman untag` command did not properly handle tags including a digest ([#11557](https://github.com/containers/podman/issues/11557)). +- Fixed a bug where the `--format` option to `podman ps` did not properly support the `table` argument for tabular output. +- Fixed a bug where the `--filter` option to `podman ps` did not properly handle filtering by healthcheck status ([#11687](https://github.com/containers/podman/issues/11687)). +- Fixed a bug where the `podman run` and `podman start --attach` commands could race when retrieving the exit code of a container that had already been removed resulting in an error (e.g. by an external `podman rm -f`) ([#11633](https://github.com/containers/podman/issues/11633)). +- Fixed a bug where the `podman generate kube` command would add default environment variables to generated YAML. +- Fixed a bug where the `podman generate kube` command would add the default CMD from the image to generated YAML ([#11672](https://github.com/containers/podman/issues/11672)). +- Fixed a bug where the `podman rm --storage` command could fail to remove containers under some circumstances ([#11207](https://github.com/containers/podman/issues/11207)). +- Fixed a bug where the `podman machine ssh` command could fail when run on Linux ([#11731](https://github.com/containers/podman/issues/11731)). +- Fixed a bug where the `podman stop` command would error when used on a container that was already stopped ([#11740](https://github.com/containers/podman/issues/11740)). +- Fixed a bug where renaming a container in a pod using the `podman rename` command, then removing the pod using `podman pod rm`, could cause Podman to believe the new name of the container was permanently in use, despite the container being removed ([#11750](https://github.com/containers/podman/issues/11750)). + +### API +- The Libpod Pull endpoint for Images now has a new query parameter, `quiet`, which (when set to true) suppresses image pull progress reports ([#10612](https://github.com/containers/podman/issues/10612)). +- The Compat Events endpoint now includes several deprecated fields from the Docker v1.21 API for improved compatibility with older clients. +- The Compat List and Inspect endpoints for Images now prefix image IDs with `sha256:` for improved Docker compatibility ([#11623](https://github.com/containers/podman/issues/11623)). +- The Compat Create endpoint for Containers now properly sets defaults for healthcheck-related fields ([#11225](https://github.com/containers/podman/issues/11225)). +- The Compat Create endpoint for Containers now supports volume options provided by the `Mounts` field ([#10831](https://github.com/containers/podman/issues/10831)). +- The Compat List endpoint for Secrets now supports a new query parameter, `filter`, which allows returned results to be filtered. +- The Compat Auth endpoint now returns the correct response code (500 instead of 400) when logging into a registry fails. +- The Version endpoint now includes information about the OCI runtime and Conmon in use ([#11227](https://github.com/containers/podman/issues/11227)). +- Fixed a bug where the X-Registry-Config header was not properly handled, leading to errors when pulling images ([#11235](https://github.com/containers/podman/issues/11235)). +- Fixed a bug where invalid query parameters could cause a null pointer dereference when creating error messages. +- Logging of API requests and responses at trace level has been greatly improved, including the addition of an X-Reference-Id header to correlate requests and responses ([#10053](https://github.com/containers/podman/issues/10053)). + +### Misc +- Updated Buildah to v1.23.0 +- Updated the containers/storage library to v1.36.0 +- Updated the containers/image library to v5.16.0 +- Updated the containers/common library to v0.44.0 + ## 3.3.1 ### Bugfixes - Fixed a bug where unit files created by `podman generate systemd` could not cleanup shut down containers when stopped by `systemctl stop` ([#11304](https://github.com/containers/podman/issues/11304)). diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index a969e17e9..e490fa121 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -421,7 +421,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions, pidsLimitFlagName := "pids-limit" createFlags.Int64( pidsLimitFlagName, pidsLimit(), - "Tune container pids limit (set 0 for unlimited, -1 for server defaults)", + "Tune container pids limit (set -1 for unlimited)", ) _ = cmd.RegisterFlagCompletionFunc(pidsLimitFlagName, completion.AutocompleteNone) diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index 2593b4c44..bfeeb7ebe 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -235,6 +235,10 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra if c.Flags().Changed("pids-limit") { val := c.Flag("pids-limit").Value.String() + // Convert -1 to 0, so that -1 maps to unlimited pids limit + if val == "-1" { + val = "0" + } pidsLimit, err := strconv.ParseInt(val, 10, 32) if err != nil { return vals, err diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index 0630c8be9..ee52bfd13 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -732,7 +732,7 @@ Default is to create a private PID namespace for the container #### **--pids-limit**=*limit* -Tune the container's pids limit. Set `0` to have unlimited pids for the container. (default "4096" on systems that support PIDS cgroups). +Tune the container's pids limit. Set `-1` to have unlimited pids for the container. (default "4096" on systems that support PIDS cgroups). #### **--platform**=*OS/ARCH* diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 43b6d5cc6..5cc17f470 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -756,7 +756,7 @@ The default is to create a private PID namespace for the container. #### **--pids-limit**=*limit* -Tune the container's pids limit. Set to **0** to have unlimited pids for the container. The default is **4096** on systems that support "pids" cgroup controller. +Tune the container's pids limit. Set to **-1** to have unlimited pids for the container. The default is **4096** on systems that support "pids" cgroup controller. #### **--platform**=*OS/ARCH* diff --git a/libpod/define/config.go b/libpod/define/config.go index 7a0d39e42..a5cf07afc 100644 --- a/libpod/define/config.go +++ b/libpod/define/config.go @@ -90,3 +90,6 @@ const ( // DefaultRlimitValue is the value set by default for nofile and nproc const RLimitDefaultValue = uint64(1048576) + +// BindMountPrefix distinguishes its annotations from others +const BindMountPrefix = "bind-mount-options:" diff --git a/libpod/kube.go b/libpod/kube.go index 57d99f3ef..bf86a9d16 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -241,11 +241,13 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po isInit := ctr.IsInitCtr() - ctr, volumes, _, err := containerToV1Container(ctx, ctr) + ctr, volumes, _, annotations, err := containerToV1Container(ctx, ctr) if err != nil { return nil, err } - + for k, v := range annotations { + podAnnotations[define.BindMountPrefix+k] = v + } // Since port bindings for the pod are handled by the // infra container, wipe them here. ctr.Ports = nil @@ -271,7 +273,7 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po deDupPodVolumes[vol.Name] = &vol } } else { - _, _, infraDNS, err := containerToV1Container(ctx, ctr) + _, _, infraDNS, _, err := containerToV1Container(ctx, ctr) if err != nil { return nil, err } @@ -359,17 +361,19 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, if !ctr.HostNetwork() { hostNetwork = false } - kubeCtr, kubeVols, ctrDNS, err := containerToV1Container(ctx, ctr) + kubeCtr, kubeVols, ctrDNS, annotations, err := containerToV1Container(ctx, ctr) if err != nil { return nil, err } + for k, v := range annotations { + kubeAnnotations[define.BindMountPrefix+k] = v + } if isInit { kubeInitCtrs = append(kubeInitCtrs, kubeCtr) } else { kubeCtrs = append(kubeCtrs, kubeCtr) } kubeVolumes = append(kubeVolumes, kubeVols...) - // Combine DNS information in sum'd structure if ctrDNS != nil { // nameservers @@ -415,42 +419,44 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, // containerToV1Container converts information we know about a libpod container // to a V1.Container specification. -func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []v1.Volume, *v1.PodDNSConfig, error) { +func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []v1.Volume, *v1.PodDNSConfig, map[string]string, error) { kubeContainer := v1.Container{} kubeVolumes := []v1.Volume{} + annotations := make(map[string]string) kubeSec, err := generateKubeSecurityContext(c) if err != nil { - return kubeContainer, kubeVolumes, nil, err + return kubeContainer, kubeVolumes, nil, annotations, err } // NOTE: a privileged container mounts all of /dev/*. if !c.Privileged() && len(c.config.Spec.Linux.Devices) > 0 { // TODO Enable when we can support devices and their names kubeContainer.VolumeDevices = generateKubeVolumeDeviceFromLinuxDevice(c.config.Spec.Linux.Devices) - return kubeContainer, kubeVolumes, nil, errors.Wrapf(define.ErrNotImplemented, "linux devices") + return kubeContainer, kubeVolumes, nil, annotations, errors.Wrapf(define.ErrNotImplemented, "linux devices") } if len(c.config.UserVolumes) > 0 { - volumeMounts, volumes, err := libpodMountsToKubeVolumeMounts(c) + volumeMounts, volumes, localAnnotations, err := libpodMountsToKubeVolumeMounts(c) if err != nil { - return kubeContainer, kubeVolumes, nil, err + return kubeContainer, kubeVolumes, nil, nil, err } + annotations = localAnnotations kubeContainer.VolumeMounts = volumeMounts kubeVolumes = append(kubeVolumes, volumes...) } envVariables, err := libpodEnvVarsToKubeEnvVars(c.config.Spec.Process.Env) if err != nil { - return kubeContainer, kubeVolumes, nil, err + return kubeContainer, kubeVolumes, nil, annotations, err } portmappings, err := c.PortMappings() if err != nil { - return kubeContainer, kubeVolumes, nil, err + return kubeContainer, kubeVolumes, nil, annotations, err } ports, err := ocicniPortMappingToContainerPort(portmappings) if err != nil { - return kubeContainer, kubeVolumes, nil, err + return kubeContainer, kubeVolumes, nil, annotations, err } // Handle command and arguments. @@ -469,11 +475,11 @@ func containerToV1Container(ctx context.Context, c *Container) (v1.Container, [] kubeContainer.Stdin = c.Stdin() img, _, err := c.runtime.libimageRuntime.LookupImage(image, nil) if err != nil { - return kubeContainer, kubeVolumes, nil, err + return kubeContainer, kubeVolumes, nil, annotations, err } imgData, err := img.Inspect(ctx, false) if err != nil { - return kubeContainer, kubeVolumes, nil, err + return kubeContainer, kubeVolumes, nil, annotations, err } if reflect.DeepEqual(imgData.Config.Cmd, kubeContainer.Command) { kubeContainer.Command = nil @@ -555,7 +561,7 @@ func containerToV1Container(ctx context.Context, c *Container) (v1.Container, [] } dns.Options = dnsOptions } - return kubeContainer, kubeVolumes, &dns, nil + return kubeContainer, kubeVolumes, &dns, annotations, nil } // ocicniPortMappingToContainerPort takes an ocicni portmapping and converts @@ -606,16 +612,23 @@ func libpodEnvVarsToKubeEnvVars(envs []string) ([]v1.EnvVar, error) { } // libpodMountsToKubeVolumeMounts converts the containers mounts to a struct kube understands -func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, []v1.Volume, error) { +func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, []v1.Volume, map[string]string, error) { namedVolumes, mounts := c.sortUserVolumes(c.config.Spec) vms := make([]v1.VolumeMount, 0, len(mounts)) vos := make([]v1.Volume, 0, len(mounts)) + annotations := make(map[string]string) var suffix string for index, m := range mounts { + for _, opt := range m.Options { + if opt == "Z" || opt == "z" { + annotations[m.Source] = opt + break + } + } vm, vo, err := generateKubeVolumeMount(m) if err != nil { - return vms, vos, err + return vms, vos, annotations, err } // Name will be the same, so use the index as suffix suffix = fmt.Sprintf("-%d", index) @@ -629,7 +642,7 @@ func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, []v1.Volume vms = append(vms, vm) vos = append(vos, vo) } - return vms, vos, nil + return vms, vos, annotations, nil } // generateKubePersistentVolumeClaim converts a ContainerNamedVolume to a Kubernetes PersistentVolumeClaim diff --git a/libpod/reset.go b/libpod/reset.go index 96fa44c2f..7b25ed680 100644 --- a/libpod/reset.go +++ b/libpod/reset.go @@ -123,7 +123,7 @@ func (r *Runtime) Reset(ctx context.Context) error { if storageConfPath, err := storage.DefaultConfigFile(rootless.IsRootless()); err == nil { if _, err = os.Stat(storageConfPath); err == nil { fmt.Printf("A storage.conf file exists at %s\n", storageConfPath) - fmt.Println("You should remove this file if you did not modified the configuration.") + fmt.Println("You should remove this file if you did not modify the configuration.") } } else { if prevError != nil { diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 35389ec5e..cf72a6253 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -319,8 +319,8 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY if err != nil { return nil, err } - specgenOpts := kube.CtrSpecGenOptions{ + Annotations: annotations, Container: initCtr, Image: pulledImage, Volumes: volumes, diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index c01d7a1f0..9389b1a20 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -12,6 +12,7 @@ import ( "github.com/containers/common/pkg/parse" "github.com/containers/common/pkg/secrets" "github.com/containers/image/v5/manifest" + "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/network/types" ann "github.com/containers/podman/v3/pkg/annotations" "github.com/containers/podman/v3/pkg/domain/entities" @@ -86,6 +87,8 @@ func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions, } type CtrSpecGenOptions struct { + // Annotations from the Pod + Annotations map[string]string // Container as read from the pod yaml Container v1.Container // Image available to use (pulled or found local) @@ -157,7 +160,7 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener return nil, errors.Wrap(err, "Failed to set CPU quota") } if milliCPU > 0 { - period, quota := util.CoresToPeriodAndQuota(float64(milliCPU) / 1000) + period, quota := util.CoresToPeriodAndQuota(float64(milliCPU)) s.ResourceLimits.CPU = &spec.LinuxCPU{ Quota: "a, Period: &period, @@ -289,6 +292,14 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener volume.MountPath = dest switch volumeSource.Type { case KubeVolumeTypeBindMount: + // If the container has bind mounts, we need to check if + // a selinux mount option exists for it + for k, v := range opts.Annotations { + // Make sure the z/Z option is not already there (from editing the YAML) + if strings.Replace(k, define.BindMountPrefix, "", 1) == volumeSource.Source && !util.StringInSlice("z", options) && !util.StringInSlice("Z", options) { + options = append(options, v) + } + } mount := spec.Mount{ Destination: volume.MountPath, Source: volumeSource.Source, diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go index 50efe7fa3..b0d84825e 100644 --- a/pkg/specgen/generate/validate.go +++ b/pkg/specgen/generate/validate.go @@ -72,10 +72,9 @@ func verifyContainerResourcesCgroupV1(s *specgen.SpecGenerator) ([]string, error // Pids checks if s.ResourceLimits.Pids != nil { - pids := s.ResourceLimits.Pids // TODO: Should this be 0, or checking that ResourceLimits.Pids // is set at all? - if pids.Limit > 0 && !sysInfo.PidsLimit { + if s.ResourceLimits.Pids.Limit >= 0 && !sysInfo.PidsLimit { warnings = append(warnings, "Your kernel does not support pids limit capabilities or the cgroup is not mounted. PIDs limit discarded.") s.ResourceLimits.Pids = nil } diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index cb556991c..cb987e139 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -6,6 +6,8 @@ import ( "path/filepath" "strconv" + "github.com/containers/podman/v3/libpod/define" + "github.com/containers/podman/v3/pkg/util" . "github.com/containers/podman/v3/test/utils" "github.com/ghodss/yaml" @@ -555,6 +557,15 @@ var _ = Describe("Podman generate kube", func() { kube.WaitWithDefaultTimeout() Expect(kube).Should(Exit(0)) + b, err := ioutil.ReadFile(outputFile) + Expect(err).ShouldNot(HaveOccurred()) + pod := new(v1.Pod) + err = yaml.Unmarshal(b, pod) + Expect(err).To(BeNil()) + val, found := pod.Annotations[define.BindMountPrefix+vol1] + Expect(found).To(BeTrue()) + Expect(val).To(HaveSuffix("z")) + rm := podmanTest.Podman([]string{"pod", "rm", "-f", "test1"}) rm.WaitWithDefaultTimeout() Expect(rm).Should(Exit(0)) diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 0d5b9d52c..83ce751e6 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -2320,6 +2320,39 @@ MemoryReservation: {{ .HostConfig.MemoryReservation }}`}) } }) + It("podman play kube allows setting resource limits with --cpus 1", func() { + SkipIfContainerized("Resource limits require a running systemd") + SkipIfRootless("CPU limits require root") + podmanTest.CgroupManager = "systemd" + + var ( + expectedCpuLimit string = "1" + ) + + deployment := getDeployment( + withPod(getPod(withCtr(getCtr( + withCpuLimit(expectedCpuLimit), + ))))) + err := generateKubeYaml("deployment", deployment, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(Exit(0)) + + for _, pod := range getPodNamesInDeployment(deployment) { + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&pod), "--format", `{{ .HostConfig.CpuPeriod }}:{{ .HostConfig.CpuQuota }}`}) + + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + + parts := strings.Split(strings.Trim(inspect.OutputToString(), "\n"), ":") + Expect(parts).To(HaveLen(2)) + + Expect(parts[0]).To(Equal(parts[1])) + } + }) + It("podman play kube reports invalid image name", func() { invalidImageName := "./myimage" |