summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml14
-rw-r--r--Makefile2
-rw-r--r--RELEASE_NOTES.md18
-rw-r--r--changelog.txt48
-rw-r--r--cmd/podman/cliconfig/config.go14
-rw-r--r--cmd/podman/network.go31
-rw-r--r--cmd/podman/network_inspect.go48
-rw-r--r--cmd/podman/network_list.go53
-rw-r--r--cmd/podman/network_rm.go48
-rw-r--r--commands.md4
-rw-r--r--completions/bash/podman72
-rwxr-xr-xcontrib/cirrus/integration_test.sh9
-rwxr-xr-xcontrib/cirrus/networking.sh17
-rw-r--r--contrib/cirrus/required_host_ports.txt11
-rw-r--r--contrib/spec/podman.spec.in2
-rw-r--r--docs/podman-create.1.md2
-rw-r--r--docs/podman-network-inspect.1.md50
-rw-r--r--docs/podman-network-ls.1.md43
-rw-r--r--docs/podman-network-rm.1.md25
-rw-r--r--docs/podman-network.1.md21
-rw-r--r--docs/podman-run.1.md2
-rw-r--r--docs/podman.1.md1
-rw-r--r--libpod/runtime_pod_infra_linux.go3
-rw-r--r--pkg/adapter/network.go147
-rw-r--r--pkg/adapter/runtime.go6
-rw-r--r--pkg/network/config.go4
-rw-r--r--pkg/network/network.go26
-rw-r--r--pkg/spec/storage.go4
-rw-r--r--pkg/util/mountOpts.go3
-rw-r--r--test/e2e/common_test.go2
-rw-r--r--test/e2e/network_test.go158
-rw-r--r--test/e2e/pause_test.go12
-rw-r--r--test/e2e/run_cpu_test.go110
-rw-r--r--test/e2e/run_memory_test.go38
-rw-r--r--test/e2e/run_test.go90
-rw-r--r--version/version.go2
36 files changed, 1090 insertions, 50 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 0a125287b..5a9dbcb54 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -93,8 +93,8 @@ gating_task:
timeout_in: 20m
- networking_script: # Don't bother going further if something is down
- - 'while read host port; do nc -zv -w 13 $host $port || exit 1; done < ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/required_host_ports.txt'
+ # Don't bother going further if something is down
+ networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
gate_script:
# N/B: entrypoint.sh resets $GOSRC (same as make clean)
@@ -331,6 +331,7 @@ testing_task:
TEST_REMOTE_CLIENT: true
TEST_REMOTE_CLIENT: false
+ networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
unit_test_script: '$SCRIPT_BASE/unit_test.sh |& ${TIMESTAMP}'
integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}'
@@ -367,6 +368,7 @@ testing_crun_task:
ADD_SECOND_PARTITION: true
OCI_RUNTIME: "/usr/bin/crun"
+ networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
install_crun_script: 'dnf install -y crun'
unit_test_script: '$SCRIPT_BASE/unit_test.sh |& ${TIMESTAMP}'
@@ -404,6 +406,7 @@ special_testing_rootless_task:
timeout_in: 60m
+ networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}'
system_test_script: '$SCRIPT_BASE/system_test.sh |& ${TIMESTAMP}'
@@ -432,6 +435,7 @@ special_testing_in_podman_task:
timeout_in: 60m
+ networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}'
@@ -458,6 +462,7 @@ special_testing_cross_task:
timeout_in: 20m
+ networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
cache_release_archive_script: '$SCRIPT_BASE/cache_release_archive.sh |& ${TIMESTAMP}'
@@ -485,6 +490,7 @@ special_testing_cgroupv2_task:
timeout_in: 20m
+ networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}'
@@ -520,7 +526,8 @@ test_build_cache_images_task:
- compute
- devstorage.full_control
- environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
+ networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
+ setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
build_vm_images_script: '$SCRIPT_BASE/build_vm_images.sh |& ${TIMESTAMP}'
df_script: '${DFCMD}'
journalctl_b_script: 'journalctl -b'
@@ -559,6 +566,7 @@ verify_test_built_images_task:
PACKER_BUILDER_NAME: "xfedora-30"
PACKER_BUILDER_NAME: "ubuntu-18"
+ networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
# Verify expectations once per image
check_image_script: >-
diff --git a/Makefile b/Makefile
index 4138586af..c4b66e261 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ export GO111MODULE=off
GO ?= go
DESTDIR ?=
-EPOCH_TEST_COMMIT ?= bb80586e275fe0d3f47700ec54c9718a28b1e59c
+EPOCH_TEST_COMMIT ?= b9a176bea94b8e3a97a70dd7cd599f1a057777b0
HEAD ?= HEAD
CHANGELOG_BASE ?= HEAD~
CHANGELOG_TARGET ?= HEAD
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index f55fd9b18..3cfd8ed86 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,5 +1,23 @@
# Release Notes
+## 1.5.1
+### Features
+- The hostname of pods is now set to the pod's name
+
+### Bugfixes
+- Fixed a bug where `podman run` and `podman create` did not honor the `--authfile` option ([#3730](https://github.com/containers/libpod/issues/3730))
+- Fixed a bug where containers restored with `podman container restore --import` would incorrectly duplicate the Conmon PID file of the original container
+- Fixed a bug where `podman build` ignored the default OCI runtime configured in `libpod.conf`
+- Fixed a bug where `podman run --rm` (or force-removing any running container with `podman rm --force`) were not retrieving the correct exit code ([#3795](https://github.com/containers/libpod/issues/3795))
+- Fixed a bug where Podman would exit with an error if any configured hooks directory was not present
+- Fixed a bug where `podman inspect` and `podman commit` would not use the correct `CMD` for containers run with `podman play kube`
+- Fixed a bug created pods when using rootless Podman and CGroups V2 ([#3801](https://github.com/containers/libpod/issues/3801))
+- Fixed a bug where the `podman events` command with the `--since` or `--until` options could take a very long time to complete
+
+### Misc
+- Rootless Podman will now inherit OCI runtime configuration from the root configuration ([#3781](https://github.com/containers/libpod/issues/3781))
+- Podman now properly sets a user agent while contacting registries ([#3788](https://github.com/containers/libpod/issues/3788))
+
## 1.5.0
### Features
- Podman containers can now join the user namespaces of other containers with `--userns=container:$ID`, or a user namespace at an arbitary path with `--userns=ns:$PATH`
diff --git a/changelog.txt b/changelog.txt
index beea8dd5c..b0a847aee 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,51 @@
+- Changelog for v1.5.1 (2019-08-15)
+ * Add release notes for v1.5.1
+ * Set Pod hostname as Pod name
+ * tests for exit status on podman run --rm
+ * performance fix for podman events with large journalds
+ * pkg/cgroups: use DBUS session when rootless
+ * Fix play kube command in pod yaml
+ * removMergeDir from inspect result if not mounted
+ * Running Podman with a nonexistent hooks dir is nonfatal
+ * Cirrus: Install varlink on Ubuntu
+ * Cirrus: Install varlink on Fedora
+ * Add missing stage-packages in snapcraft.yaml.
+ * Add RHEL and SUSE to snap doc
+ * start groundwork for adding snap
+ * Add user systemd service and socket
+ * Small optimization - only store exit code when nonzero
+ * Fix container exit code with Journald backend
+ * Revert "Cirrus: Temp. workaround missing imgprune image"
+ * Homebrew installation in install.md
+ * varlink endpoint for containerstats requires root
+ * Adjust get_ci_vm.sh for substitution
+ * Cirrus: Add verification for cgroupv2 image
+ * Cirrus: Add experimental fedora VM image & test
+ * image: add user agent to Docker registry options
+ * Cirrus: Minor, use newer Ubuntu base image
+ * tests: disable some tests currently failing when not using runc
+ * containers: look also for 'file not found' in the error message
+ * cirrus: add tests with crun on Fedora 30
+ * rootless: cherry-pick runtime from the system configuration
+ * cirrus: install crun
+ * cmd: drop check for euid==0
+ * storage: drop unused geteuid check
+ * cmd, stats: fix check for rootless mode
+ * oci: drop check for euid==0
+ * build: use the configured runtime
+ * Adjust read count so that a newline can be added afterwards
+ * Fix incorrect use of realloc()
+ * Bump gitvalidation epoch
+ * Bump to v1.5.1-dev
+ * Fix a couple of errors descovered by coverity
+ * Test that restored container does not depend on the original container
+ * Fix up ConmonPidFile after restore
+ * Cirrus: Enable updates-testing repo for Fedora
+ * enable windows remote client
+ * implement 'make remotesystem'
+ * Squish a few tpyo nits in container.go doc
+ * Cirrus: Add Second partition for storage testing
+
- Changelog for v1.5.0 (2019-08-09)
* vendor github.com/containers/storage@v1.13.2
* Improve dns-search validation, empty domains now return an error
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index d5098ee51..f7c78908f 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -258,6 +258,20 @@ type MountValues struct {
Latest bool
}
+type NetworkListValues struct {
+ PodmanCommand
+ Filter []string
+ Quiet bool
+}
+
+type NetworkRmValues struct {
+ PodmanCommand
+}
+
+type NetworkInspectValues struct {
+ PodmanCommand
+}
+
type PauseValues struct {
PodmanCommand
All bool
diff --git a/cmd/podman/network.go b/cmd/podman/network.go
new file mode 100644
index 000000000..83a5e71ab
--- /dev/null
+++ b/cmd/podman/network.go
@@ -0,0 +1,31 @@
+//+build !remoteclient
+
+package main
+
+import (
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/spf13/cobra"
+)
+
+var networkcheckDescription = "Manage networks"
+var networkcheckCommand = cliconfig.PodmanCommand{
+ Command: &cobra.Command{
+ Use: "network",
+ Short: "Manage Networks",
+ Long: networkcheckDescription,
+ RunE: commandRunE(),
+ },
+}
+
+// Commands that are universally implemented
+var networkcheckCommands = []*cobra.Command{
+ _networkinspectCommand,
+ _networklistCommand,
+ _networkrmCommand,
+}
+
+func init() {
+ networkcheckCommand.AddCommand(networkcheckCommands...)
+ networkcheckCommand.SetUsageTemplate(UsageTemplate())
+ rootCmd.AddCommand(networkcheckCommand.Command)
+}
diff --git a/cmd/podman/network_inspect.go b/cmd/podman/network_inspect.go
new file mode 100644
index 000000000..38aaf6ba4
--- /dev/null
+++ b/cmd/podman/network_inspect.go
@@ -0,0 +1,48 @@
+// +build !remoteclient
+
+package main
+
+import (
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/pkg/adapter"
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ networkinspectCommand cliconfig.NetworkInspectValues
+ networkinspectDescription = `Inspect network`
+ _networkinspectCommand = &cobra.Command{
+ Use: "inspect NETWORK [NETWORK...] [flags] ",
+ Short: "network inspect",
+ Long: networkinspectDescription,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ networkinspectCommand.InputArgs = args
+ networkinspectCommand.GlobalFlags = MainGlobalOpts
+ networkinspectCommand.Remote = remoteclient
+ return networkinspectCmd(&networkinspectCommand)
+ },
+ Example: `podman network inspect podman`,
+ }
+)
+
+func init() {
+ networkinspectCommand.Command = _networkinspectCommand
+ networkinspectCommand.SetHelpTemplate(HelpTemplate())
+ networkinspectCommand.SetUsageTemplate(UsageTemplate())
+}
+
+func networkinspectCmd(c *cliconfig.NetworkInspectValues) error {
+ if rootless.IsRootless() && !remoteclient {
+ return errors.New("network inspect is not supported for rootless mode")
+ }
+ if len(c.InputArgs) < 1 {
+ return errors.Errorf("at least one network name is required")
+ }
+ runtime, err := adapter.GetRuntimeNoStore(getContext(), &c.PodmanCommand)
+ if err != nil {
+ return err
+ }
+ return runtime.NetworkInspect(c)
+}
diff --git a/cmd/podman/network_list.go b/cmd/podman/network_list.go
new file mode 100644
index 000000000..16edf743b
--- /dev/null
+++ b/cmd/podman/network_list.go
@@ -0,0 +1,53 @@
+// +build !remoteclient
+
+package main
+
+import (
+ "errors"
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/pkg/adapter"
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/spf13/cobra"
+)
+
+var (
+ networklistCommand cliconfig.NetworkListValues
+ networklistDescription = `List networks`
+ _networklistCommand = &cobra.Command{
+ Use: "ls",
+ Args: noSubArgs,
+ Short: "network list",
+ Long: networklistDescription,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ networklistCommand.InputArgs = args
+ networklistCommand.GlobalFlags = MainGlobalOpts
+ networklistCommand.Remote = remoteclient
+ return networklistCmd(&networklistCommand)
+ },
+ Example: `podman network list`,
+ }
+)
+
+func init() {
+ networklistCommand.Command = _networklistCommand
+ networklistCommand.SetHelpTemplate(HelpTemplate())
+ networklistCommand.SetUsageTemplate(UsageTemplate())
+ flags := networklistCommand.Flags()
+ // TODO enable filters based on something
+ //flags.StringSliceVarP(&networklistCommand.Filter, "filter", "f", []string{}, "Pause all running containers")
+ flags.BoolVarP(&networklistCommand.Quiet, "quiet", "q", false, "display only names")
+}
+
+func networklistCmd(c *cliconfig.NetworkListValues) error {
+ if rootless.IsRootless() && !remoteclient {
+ return errors.New("network list is not supported for rootless mode")
+ }
+ if len(c.InputArgs) > 0 {
+ return errors.New("network list takes no arguments")
+ }
+ runtime, err := adapter.GetRuntimeNoStore(getContext(), &c.PodmanCommand)
+ if err != nil {
+ return err
+ }
+ return runtime.NetworkList(c)
+}
diff --git a/cmd/podman/network_rm.go b/cmd/podman/network_rm.go
new file mode 100644
index 000000000..50bd48cea
--- /dev/null
+++ b/cmd/podman/network_rm.go
@@ -0,0 +1,48 @@
+// +build !remoteclient
+
+package main
+
+import (
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/pkg/adapter"
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ networkrmCommand cliconfig.NetworkRmValues
+ networkrmDescription = `Remove networks`
+ _networkrmCommand = &cobra.Command{
+ Use: "rm [flags] NETWORK [NETWORK...]",
+ Short: "network rm",
+ Long: networkrmDescription,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ networkrmCommand.InputArgs = args
+ networkrmCommand.GlobalFlags = MainGlobalOpts
+ networkrmCommand.Remote = remoteclient
+ return networkrmCmd(&networkrmCommand)
+ },
+ Example: `podman network rm podman`,
+ }
+)
+
+func init() {
+ networkrmCommand.Command = _networkrmCommand
+ networkrmCommand.SetHelpTemplate(HelpTemplate())
+ networkrmCommand.SetUsageTemplate(UsageTemplate())
+}
+
+func networkrmCmd(c *cliconfig.NetworkRmValues) error {
+ if rootless.IsRootless() && !remoteclient {
+ return errors.New("network rm is not supported for rootless mode")
+ }
+ if len(c.InputArgs) < 1 {
+ return errors.Errorf("at least one network name is required")
+ }
+ runtime, err := adapter.GetRuntimeNoStore(getContext(), &c.PodmanCommand)
+ if err != nil {
+ return err
+ }
+ return runtime.NetworkRemove(c)
+}
diff --git a/commands.md b/commands.md
index 1b48d7862..4d3bea439 100644
--- a/commands.md
+++ b/commands.md
@@ -44,6 +44,10 @@
| [podman-logout(1)](/docs/podman-logout.1.md) | Logout of a container registry |
| [podman-logs(1)](/docs/podman-logs.1.md) | Display the logs of a container |
| [podman-mount(1)](/docs/podman-mount.1.md) | Mount a working container's root filesystem |
+| [podman-network(1)](/docs/podman-network.1.md) | Manage Podman CNI networks |
+| [podman-network-inspect(1)](/docs/podman-network-inspect.1.md) | Inspect one or more Podman networks |
+| [podman-network-ls(1)](/docs/podman-network-ls.1.md) | Display a summary of Podman networks |
+| [podman-network-rm(1)](/docs/podman-network-rm.1.md) | Remove one or more Podman networks |
| [podman-pause(1)](/docs/podman-pause.1.md) | Pause one or more running containers | [![...](/docs/play.png)](https://podman.io/asciinema/podman/pause_unpause/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_pause_unpause.sh) |
| [podman-play(1)](/docs/podman-play.1.md) | Play pods and containers based on a structured input file |
| [podman-pod(1)](/docs/podman-pod.1.md) | Simple management tool for groups of containers, called pods |
diff --git a/completions/bash/podman b/completions/bash/podman
index d2eb5b570..cf9b31393 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -946,6 +946,78 @@ _podman_healthcheck() {
esac
}
+_podman_network() {
+ local boolean_options="
+ --help
+ -h
+ "
+ subcommands="
+ inspect
+ ls
+ rm
+ "
+ __podman_subcommands "$subcommands $aliases" && return
+
+ case "$cur" in
+ -*)
+ COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
+ ;;
+ *)
+ COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
+ ;;
+ esac
+}
+
+_podman_network_inspect() {
+ local options_with_args="
+ "
+ local boolean_options="
+ --help
+ -h
+ "
+ _complete_ "$options_with_args" "$boolean_options"
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ esac
+}
+
+_podman_network_ls() {
+ local options_with_args="
+ "
+ local boolean_options="
+ --help
+ -h
+ --quiet
+ -q
+ "
+ _complete_ "$options_with_args" "$boolean_options"
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ esac
+}
+
+_podman_network_ls() {
+ local options_with_args="
+ "
+ local boolean_options="
+ --help
+ -h
+ "
+ _complete_ "$options_with_args" "$boolean_options"
+
+ case "$cur" in
+ -*)
+ COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
+ ;;
+ esac
+}
+
_podman_generate() {
local boolean_options="
--help
diff --git a/contrib/cirrus/integration_test.sh b/contrib/cirrus/integration_test.sh
index 8a43176e4..e5de518fa 100755
--- a/contrib/cirrus/integration_test.sh
+++ b/contrib/cirrus/integration_test.sh
@@ -37,11 +37,16 @@ case "$SPECIALMODE" in
-o CheckHostIP=no $GOSRC/$SCRIPT_BASE/rootless_test.sh ${TESTSUITE}
;;
cgroupv2)
+ # FIXME: use the package once all the fixes are in a release
+ # yum install -y crun
+ setenforce 0
+ yum builddep -y crun
+ (git clone --depth=1 https://github.com/containers/crun && cd crun && ./autogen.sh && ./configure --prefix=/usr && make -j4 && make install)
+ export OCI_RUNTIME=/usr/bin/crun
make
make install PREFIX=/usr ETCDIR=/etc
make test-binaries
- echo "WARNING: Integration tests not yet ready for cgroups V2"
- #TODO: make local${TESTSUITE}
+ make local${TESTSUITE}
;;
none)
make
diff --git a/contrib/cirrus/networking.sh b/contrib/cirrus/networking.sh
new file mode 100755
index 000000000..aeaf74035
--- /dev/null
+++ b/contrib/cirrus/networking.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# This script attempts basic confirmation of functional networking
+# by connecting to a set of essential external servers and failing
+# if any cannot be reached.
+
+source $(dirname $0)/lib.sh
+
+while read host port
+do
+ if [[ "$port" -eq "443" ]]
+ then
+ item_test "SSL/TLS to $host:$port" "$(echo -n '' | openssl s_client -quiet -no_ign_eof -connect $host:$port &> /dev/null; echo $?)" -eq "0"
+ else
+ item_test "Connect to $host:$port" "$(nc -zv -w 13 $host $port &> /dev/null; echo $?)" -eq 0
+ fi
+done < ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/required_host_ports.txt
diff --git a/contrib/cirrus/required_host_ports.txt b/contrib/cirrus/required_host_ports.txt
index 9248e497a..85a6c26be 100644
--- a/contrib/cirrus/required_host_ports.txt
+++ b/contrib/cirrus/required_host_ports.txt
@@ -2,3 +2,14 @@ github.com 22
docker.io 443
quay.io 443
registry.fedoraproject.org 443
+mirrors.fedoraproject.org 443
+dl.fedoraproject.org 443
+ewr.edge.kernel.org 443
+mirror.chpc.utah.edu 443
+mirror.clarkson.edu 443
+mirror.umd.edu 443
+mirror.vcu.edu 443
+mirrors.cat.pdx.edu 443
+pubmirror1.math.uh.edu 443
+pubmirror2.math.uh.edu 443
+sjc.edge.kernel.org 443
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 35f3b2014..934f785db 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -39,7 +39,7 @@
%global shortcommit_conmon %(c=%{commit_conmon}; echo ${c:0:7})
Name: podman
-Version: 1.5.1
+Version: 1.5.2
Release: #COMMITDATE#.git%{shortcommit0}%{?dist}
Summary: Manage Pods, Containers and Container Images
License: ASL 2.0
diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md
index 50fca3541..6fe224bd4 100644
--- a/docs/podman-create.1.md
+++ b/docs/podman-create.1.md
@@ -715,7 +715,7 @@ $ podman run -d --tmpfs /tmp:rw,size=787448k,mode=1777 my_image
This command mounts a `tmpfs` at `/tmp` within the container. The supported mount
options are the same as the Linux default `mount` flags. If you do not specify
any options, the systems uses the following options:
-`rw,noexec,nosuid,nodev,size=65536k`.
+`rw,noexec,nosuid,nodev`.
**--tty**, **-t**=*true|false*
diff --git a/docs/podman-network-inspect.1.md b/docs/podman-network-inspect.1.md
new file mode 100644
index 000000000..576e61c79
--- /dev/null
+++ b/docs/podman-network-inspect.1.md
@@ -0,0 +1,50 @@
+% podman-network-inspect(1)
+
+## NAME
+podman\-network-inspect- Inspect one or more Podman networks
+
+## SYNOPSIS
+**podman network inspect** [*network* ...]
+
+## DESCRIPTION
+Display the raw (JSON format) network configuration. This command is not available for rootless users.
+
+## EXAMPLE
+
+Inspect the default podman network
+
+```
+# podman network inspect podman
+[{
+ "cniVersion": "0.3.0",
+ "name": "podman",
+ "plugins": [
+ {
+ "type": "bridge",
+ "bridge": "cni0",
+ "isGateway": true,
+ "ipMasq": true,
+ "ipam": {
+ "type": "host-local",
+ "subnet": "10.88.1.0/24",
+ "routes": [
+ { "dst": "0.0.0.0/0" }
+ ]
+ }
+ },
+ {
+ "type": "portmap",
+ "capabilities": {
+ "portMappings": true
+ }
+ }
+ ]
+}
+]
+```
+
+## SEE ALSO
+podman(1), podman-network(1), podman-network-ls(1)
+
+## HISTORY
+August 2019, Originally compiled by Brent Baude <bbaude@redhat.com>
diff --git a/docs/podman-network-ls.1.md b/docs/podman-network-ls.1.md
new file mode 100644
index 000000000..725e07dbb
--- /dev/null
+++ b/docs/podman-network-ls.1.md
@@ -0,0 +1,43 @@
+% podman-network-ls(1)
+
+## NAME
+podman\-network-ls- Display a summary of CNI networks
+
+## SYNOPSIS
+**podman network ls** [*options*]
+
+## DESCRIPTION
+Displays a list of existing podman networks. This command is not available for rootless users.
+
+## OPTIONS
+**--quiet**, **-q**
+
+The `quiet` options will restrict the output to only the network names
+
+## EXAMPLE
+
+Display networks
+
+```
+# podman network ls
+NAME VERSION PLUGINS
+podman 0.3.0 bridge,portmap
+podman2 0.3.0 bridge,portmap
+outside 0.3.0 bridge
+podman9 0.3.0 bridge,portmap
+```
+
+Display only network names
+```
+# podman network ls -q
+podman
+podman2
+outside
+podman9
+```
+
+## SEE ALSO
+podman(1), podman-network(1), podman-network-inspect(1)
+
+## HISTORY
+August 2019, Originally compiled by Brent Baude <bbaude@redhat.com>
diff --git a/docs/podman-network-rm.1.md b/docs/podman-network-rm.1.md
new file mode 100644
index 000000000..f72d6a694
--- /dev/null
+++ b/docs/podman-network-rm.1.md
@@ -0,0 +1,25 @@
+% podman-network-rm(1)
+
+## NAME
+podman\-network-rm- Delete a Podman CNI network
+
+## SYNOPSIS
+**podman network rm** [*network...*]
+
+## DESCRIPTION
+Delete one or more Podman networks.
+
+## EXAMPLE
+
+Delete the `podman9` network
+
+```
+# podman network rm podman
+Deleted: podman9
+```
+
+## SEE ALSO
+podman(1), podman-network(1), podman-network-inspect(1)
+
+## HISTORY
+August 2019, Originally compiled by Brent Baude <bbaude@redhat.com>
diff --git a/docs/podman-network.1.md b/docs/podman-network.1.md
new file mode 100644
index 000000000..c01adc23e
--- /dev/null
+++ b/docs/podman-network.1.md
@@ -0,0 +1,21 @@
+% podman-network(1)
+
+## NAME
+podman\-network- Manage podman CNI networks
+
+## SYNOPSIS
+**podman network** *subcommand*
+
+## DESCRIPTION
+The network command manages CNI networks for Podman. It is not supported for rootless users.
+
+## COMMANDS
+
+| Command | Man Page | Description |
+| ------- | --------------------------------------------------- | ---------------------------------------------------------------------------- |
+| inspect | [podman-network-inspect(1)](podman-network-inspect.1.md)| Displays the raw CNI network configuration for one or more networks|
+| ls | [podman-network-ls(1)](podman-network-ls.1.md)| Display a summary of CNI networks |
+| rm | [podman-network-rm(1)](podman-network-rm.1.md)| Remove one or more CNI networks |
+
+## SEE ALSO
+podman(1)
diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md
index e7c898b25..4f6c3568b 100644
--- a/docs/podman-run.1.md
+++ b/docs/podman-run.1.md
@@ -752,7 +752,7 @@ $ podman run -d --tmpfs /tmp:rw,size=787448k,mode=1777 my_image
This command mounts a `tmpfs` at `/tmp` within the container. The supported mount
options are the same as the Linux default `mount` flags. If you do not specify
any options, the systems uses the following options:
-`rw,noexec,nosuid,nodev,size=65536k`.
+`rw,noexec,nosuid,nodev`.
**--tty**, **-t**=*true|false*
diff --git a/docs/podman.1.md b/docs/podman.1.md
index 12b7866ca..33ea81ef6 100644
--- a/docs/podman.1.md
+++ b/docs/podman.1.md
@@ -161,6 +161,7 @@ the exit codes follow the `chroot` standard, see below:
| [podman-logout(1)](podman-logout.1.md) | Logout of a container registry. |
| [podman-logs(1)](podman-logs.1.md) | Display the logs of a container. |
| [podman-mount(1)](podman-mount.1.md) | Mount a working container's root filesystem. |
+| [podman-network(1)](podman-network.1.md) | Manage Podman CNI networks. |
| [podman-pause(1)](podman-pause.1.md) | Pause one or more containers. |
| [podman-play(1)](podman-play.1.md) | Play pods and containers based on a structured input file. |
| [podman-pod(1)](podman-pod.1.md) | Management tool for groups of containers, called pods. |
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index da35b7f93..24651099f 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -30,6 +30,9 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID
return nil, err
}
+ // Set Pod hostname as Pod name
+ g.Config.Hostname = p.config.Name
+
isRootless := rootless.IsRootless()
entryCmd := []string{r.config.InfraCommand}
diff --git a/pkg/adapter/network.go b/pkg/adapter/network.go
new file mode 100644
index 000000000..cf3a1dfdd
--- /dev/null
+++ b/pkg/adapter/network.go
@@ -0,0 +1,147 @@
+// +build !remoteclient
+
+package adapter
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+ "text/tabwriter"
+
+ "github.com/containernetworking/cni/libcni"
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/pkg/network"
+ "github.com/pkg/errors"
+)
+
+func getCNIConfDir(r *LocalRuntime) (string, error) {
+ config, err := r.GetConfig()
+ if err != nil {
+ return "", err
+ }
+ configPath := config.CNIConfigDir
+
+ if len(config.CNIConfigDir) < 1 {
+ configPath = network.CNIConfigDir
+ }
+ return configPath, nil
+}
+
+// NetworkList displays summary information about CNI networks
+func (r *LocalRuntime) NetworkList(cli *cliconfig.NetworkListValues) error {
+ cniConfigPath, err := getCNIConfDir(r)
+ if err != nil {
+ return err
+ }
+ networks, err := network.LoadCNIConfsFromDir(cniConfigPath)
+ if err != nil {
+ return err
+ }
+ // quiet means we only print the network names
+ if cli.Quiet {
+ for _, cniNetwork := range networks {
+ fmt.Println(cniNetwork.Name)
+ }
+ return nil
+ }
+ w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
+ if _, err := fmt.Fprintln(w, "NAME\tVERSION\tPLUGINS"); err != nil {
+ return err
+ }
+ for _, cniNetwork := range networks {
+ if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", cniNetwork.Name, cniNetwork.CNIVersion, getCNIPlugins(cniNetwork)); err != nil {
+ return err
+ }
+ }
+ return w.Flush()
+}
+
+// NetworkInspect displays the raw CNI configuration for one
+// or more CNI networks
+func (r *LocalRuntime) NetworkInspect(cli *cliconfig.NetworkInspectValues) error {
+ var (
+ rawCNINetworks []map[string]interface{}
+ )
+ cniConfigPath, err := getCNIConfDir(r)
+ if err != nil {
+ return err
+ }
+ for _, name := range cli.InputArgs {
+ b, err := readRawCNIConfByName(name, cniConfigPath)
+ if err != nil {
+ return err
+ }
+ rawList := make(map[string]interface{})
+ if err := json.Unmarshal(b, &rawList); err != nil {
+ return fmt.Errorf("error parsing configuration list: %s", err)
+ }
+ rawCNINetworks = append(rawCNINetworks, rawList)
+ }
+ out, err := json.MarshalIndent(rawCNINetworks, "", "\t")
+ if err != nil {
+ return err
+ }
+ fmt.Printf("%s\n", out)
+ return nil
+}
+
+// NetworkRemove deletes one or more CNI networks
+func (r *LocalRuntime) NetworkRemove(cli *cliconfig.NetworkRmValues) error {
+ cniConfigPath, err := getCNIConfDir(r)
+ if err != nil {
+ return err
+ }
+ for _, name := range cli.InputArgs {
+ cniPath, err := getCNIConfigPathByName(name, cniConfigPath)
+ if err != nil {
+ return err
+ }
+ if err := os.Remove(cniPath); err != nil {
+ return err
+ }
+ fmt.Printf("Deleted: %s\n", name)
+ }
+ return nil
+}
+
+// getCNIConfigPathByName finds a CNI network by name and
+// returns its configuration file path
+func getCNIConfigPathByName(name, cniConfigPath string) (string, error) {
+ files, err := libcni.ConfFiles(cniConfigPath, []string{".conflist"})
+ if err != nil {
+ return "", err
+ }
+ for _, confFile := range files {
+ conf, err := libcni.ConfListFromFile(confFile)
+ if err != nil {
+ return "", err
+ }
+ if conf.Name == name {
+ return confFile, nil
+ }
+ }
+ return "", errors.Errorf("unable to find network configuration for %s", name)
+}
+
+// readRawCNIConfByName reads the raw CNI configuration for a CNI
+// network by name
+func readRawCNIConfByName(name, cniConfigPath string) ([]byte, error) {
+ confFile, err := getCNIConfigPathByName(name, cniConfigPath)
+ if err != nil {
+ return nil, err
+ }
+ b, err := ioutil.ReadFile(confFile)
+ return b, err
+}
+
+// getCNIPlugins returns a list of plugins that a given network
+// has in the form of a string
+func getCNIPlugins(list *libcni.NetworkConfigList) string {
+ var plugins []string
+ for _, plug := range list.Plugins {
+ plugins = append(plugins, plug.Network.Type)
+ }
+ return strings.Join(plugins, ",")
+}
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index 03419c0bd..c80d5991e 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -288,7 +288,11 @@ func (r *LocalRuntime) Build(ctx context.Context, c *cliconfig.BuildValues, opti
options.CommonBuildOpts = commonOpts
options.SystemContext = systemContext
- options.Runtime = r.GetOCIRuntimePath()
+ if c.GlobalFlags.Runtime != "" {
+ options.Runtime = c.GlobalFlags.Runtime
+ } else {
+ options.Runtime = r.GetOCIRuntimePath()
+ }
if c.Quiet {
options.ReportWriter = ioutil.Discard
diff --git a/pkg/network/config.go b/pkg/network/config.go
new file mode 100644
index 000000000..d282f66b6
--- /dev/null
+++ b/pkg/network/config.go
@@ -0,0 +1,4 @@
+package network
+
+// CNIConfigDir is the path where CNI config files exist
+const CNIConfigDir = "/etc/cni/net.d"
diff --git a/pkg/network/network.go b/pkg/network/network.go
new file mode 100644
index 000000000..9d04340a3
--- /dev/null
+++ b/pkg/network/network.go
@@ -0,0 +1,26 @@
+package network
+
+import (
+ "sort"
+
+ "github.com/containernetworking/cni/libcni"
+)
+
+// LoadCNIConfsFromDir loads all the CNI configurations from a dir
+func LoadCNIConfsFromDir(dir string) ([]*libcni.NetworkConfigList, error) {
+ var configs []*libcni.NetworkConfigList
+ files, err := libcni.ConfFiles(dir, []string{".conflist"})
+ if err != nil {
+ return nil, err
+ }
+ sort.Strings(files)
+
+ for _, confFile := range files {
+ conf, err := libcni.ConfListFromFile(confFile)
+ if err != nil {
+ return nil, err
+ }
+ configs = append(configs, conf)
+ }
+ return configs, nil
+}
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go
index a8dc7f4a8..b634f4cac 100644
--- a/pkg/spec/storage.go
+++ b/pkg/spec/storage.go
@@ -168,14 +168,14 @@ func (config *CreateConfig) parseVolumes(runtime *libpod.Runtime) ([]spec.Mount,
"/run": false,
}
if config.ReadOnlyRootfs && config.ReadOnlyTmpfs {
- options := []string{"rw", "rprivate", "nosuid", "nodev", "tmpcopyup", "size=65536k"}
+ options := []string{"rw", "rprivate", "nosuid", "nodev", "tmpcopyup"}
for dest := range readonlyTmpfs {
if _, ok := baseMounts[dest]; ok {
continue
}
localOpts := options
if dest == "/run" {
- localOpts = append(localOpts, "noexec")
+ localOpts = append(localOpts, "noexec", "size=65536k")
}
baseMounts[dest] = spec.Mount{
Destination: dest,
diff --git a/pkg/util/mountOpts.go b/pkg/util/mountOpts.go
index 40c99384d..9b2c734c0 100644
--- a/pkg/util/mountOpts.go
+++ b/pkg/util/mountOpts.go
@@ -92,9 +92,6 @@ func ProcessTmpfsOptions(options []string) ([]string, error) {
if !foundWrite {
baseOpts = append(baseOpts, "rw")
}
- if !foundSize {
- baseOpts = append(baseOpts, "size=65536k")
- }
if !foundProp {
baseOpts = append(baseOpts, "rprivate")
}
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index b6dd1ecd1..4e9881d59 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -538,7 +538,7 @@ func (p *PodmanTestIntegration) RunHealthCheck(cid string) error {
return nil
}
// Restart container if it's not running
- ps := p.Podman([]string{"ps", "--no-trunc", "--q", "--filter", fmt.Sprintf("id=%s", cid)})
+ ps := p.Podman([]string{"ps", "--no-trunc", "--quiet", "--filter", fmt.Sprintf("id=%s", cid)})
ps.WaitWithDefaultTimeout()
if ps.ExitCode() == 0 {
if !strings.Contains(ps.OutputToString(), cid) {
diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go
new file mode 100644
index 000000000..9aed5351a
--- /dev/null
+++ b/test/e2e/network_test.go
@@ -0,0 +1,158 @@
+// +build !remoteclient
+
+package integration
+
+import (
+ "fmt"
+ . "github.com/containers/libpod/test/utils"
+ "github.com/containers/storage/pkg/stringid"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+)
+
+func writeConf(conf []byte, confPath string) {
+ if err := ioutil.WriteFile(confPath, conf, 777); err != nil {
+ fmt.Println(err)
+ }
+}
+func removeConf(confPath string) {
+ if err := os.Remove(confPath); err != nil {
+ fmt.Println(err)
+ }
+}
+
+var _ = Describe("Podman network", func() {
+ var (
+ tempdir string
+ err error
+ podmanTest *PodmanTestIntegration
+ )
+
+ BeforeEach(func() {
+ tempdir, err = CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ podmanTest = PodmanTestCreate(tempdir)
+ podmanTest.Setup()
+ })
+
+ AfterEach(func() {
+ podmanTest.Cleanup()
+ f := CurrentGinkgoTestDescription()
+ processTestResult(f)
+
+ })
+
+ var (
+ secondConf = `{
+ "cniVersion": "0.3.0",
+ "name": "podman-integrationtest",
+ "plugins": [
+ {
+ "type": "bridge",
+ "bridge": "cni1",
+ "isGateway": true,
+ "ipMasq": true,
+ "ipam": {
+ "type": "host-local",
+ "subnet": "10.99.0.0/16",
+ "routes": [
+ { "dst": "0.0.0.0/0" }
+ ]
+ }
+ },
+ {
+ "type": "portmap",
+ "capabilities": {
+ "portMappings": true
+ }
+ }
+ ]
+}`
+ cniPath = "/etc/cni/net.d"
+ )
+
+ It("podman network list", func() {
+ SkipIfRootless()
+ // Setup, use uuid to prevent conflict with other tests
+ uuid := stringid.GenerateNonCryptoID()
+ secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid))
+ writeConf([]byte(secondConf), secondPath)
+ defer removeConf(secondPath)
+
+ session := podmanTest.Podman([]string{"network", "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.LineInOutputContains("podman-integrationtest")).To(BeTrue())
+ })
+
+ It("podman network list -q", func() {
+ SkipIfRootless()
+ // Setup, use uuid to prevent conflict with other tests
+ uuid := stringid.GenerateNonCryptoID()
+ secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid))
+ writeConf([]byte(secondConf), secondPath)
+ defer removeConf(secondPath)
+
+ session := podmanTest.Podman([]string{"network", "ls", "--quiet"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.LineInOutputContains("podman-integrationtest")).To(BeTrue())
+ })
+
+ It("podman network rm no args", func() {
+ SkipIfRootless()
+ session := podmanTest.Podman([]string{"network", "rm"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).ToNot(BeZero())
+ })
+
+ It("podman network rm", func() {
+ SkipIfRootless()
+ // Setup, use uuid to prevent conflict with other tests
+ uuid := stringid.GenerateNonCryptoID()
+ secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid))
+ writeConf([]byte(secondConf), secondPath)
+ defer removeConf(secondPath)
+
+ session := podmanTest.Podman([]string{"network", "ls", "--quiet"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.LineInOutputContains("podman-integrationtest")).To(BeTrue())
+
+ rm := podmanTest.Podman([]string{"network", "rm", "podman-integrationtest"})
+ rm.WaitWithDefaultTimeout()
+ Expect(rm.ExitCode()).To(BeZero())
+
+ results := podmanTest.Podman([]string{"network", "ls", "--quiet"})
+ results.WaitWithDefaultTimeout()
+ Expect(results.ExitCode()).To(Equal(0))
+ Expect(results.LineInOutputContains("podman-integrationtest")).To(BeFalse())
+ })
+
+ It("podman network inspect no args", func() {
+ SkipIfRootless()
+ session := podmanTest.Podman([]string{"network", "inspect"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).ToNot(BeZero())
+ })
+
+ It("podman network inspect", func() {
+ SkipIfRootless()
+ // Setup, use uuid to prevent conflict with other tests
+ uuid := stringid.GenerateNonCryptoID()
+ secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid))
+ writeConf([]byte(secondConf), secondPath)
+ defer removeConf(secondPath)
+
+ session := podmanTest.Podman([]string{"network", "inspect", "podman-integrationtest", "podman"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.IsJSONOutputValid()).To(BeTrue())
+ })
+
+})
diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go
index 455f60937..c61131078 100644
--- a/test/e2e/pause_test.go
+++ b/test/e2e/pause_test.go
@@ -4,6 +4,7 @@ import (
"fmt"
"os"
+ "github.com/containers/libpod/pkg/cgroups"
. "github.com/containers/libpod/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -25,6 +26,17 @@ var _ = Describe("Podman pause", func() {
if err != nil {
os.Exit(1)
}
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if cgroupsv2 {
+ _, err := os.Stat("/sys/fs/cgroup/cgroup.freeze")
+ if err != nil {
+ Skip("freezer controller not available on the current kernel")
+ }
+ }
+
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
podmanTest.SeedImages()
diff --git a/test/e2e/run_cpu_test.go b/test/e2e/run_cpu_test.go
index 87f89b1dd..4be9da3d2 100644
--- a/test/e2e/run_cpu_test.go
+++ b/test/e2e/run_cpu_test.go
@@ -3,8 +3,10 @@
package integration
import (
+ "io/ioutil"
"os"
+ "github.com/containers/libpod/pkg/cgroups"
. "github.com/containers/libpod/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -22,6 +24,16 @@ var _ = Describe("Podman run cpu", func() {
if err != nil {
os.Exit(1)
}
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if cgroupsv2 {
+ if err := ioutil.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+cpuset"), 0644); err != nil {
+ Skip("cpuset controller not available on the current kernel")
+ }
+ }
+
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
podmanTest.SeedImages()
@@ -36,44 +48,96 @@ var _ = Describe("Podman run cpu", func() {
It("podman run cpu-period", func() {
SkipIfRootless()
- result := podmanTest.Podman([]string{"run", "--rm", "--cpu-period=5000", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_period_us"})
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var result *PodmanSessionIntegration
+ if cgroupsv2 {
+ result = podmanTest.Podman([]string{"run", "--rm", "--cpu-period=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"})
+ } else {
+ result = podmanTest.Podman([]string{"run", "--rm", "--cpu-period=5000", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_period_us"})
+ }
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
- Expect(result.OutputToString()).To(Equal("5000"))
+ Expect(result.LineInOutputContains("5000"))
})
It("podman run cpu-quota", func() {
SkipIfRootless()
- result := podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"})
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var result *PodmanSessionIntegration
+
+ if cgroupsv2 {
+ result = podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"})
+ } else {
+ result = podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"})
+ }
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
- Expect(result.OutputToString()).To(Equal("5000"))
+ Expect(result.LineInOutputContains("5000"))
})
It("podman run cpus", func() {
SkipIfRootless()
- result := podmanTest.Podman([]string{"run", "--rm", "--cpus=0.5", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_period_us"})
- result.WaitWithDefaultTimeout()
- Expect(result.ExitCode()).To(Equal(0))
- Expect(result.OutputToString()).To(Equal("100000"))
- result = podmanTest.Podman([]string{"run", "--rm", "--cpus=0.5", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"})
- result.WaitWithDefaultTimeout()
- Expect(result.ExitCode()).To(Equal(0))
- Expect(result.OutputToString()).To(Equal("50000"))
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if cgroupsv2 {
+ result := podmanTest.Podman([]string{"run", "--rm", "--cpu-quota=5000", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.max"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(Equal("5000 100000"))
+ } else {
+ result := podmanTest.Podman([]string{"run", "--rm", "--cpus=0.5", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_period_us"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(Equal("100000"))
+
+ result = podmanTest.Podman([]string{"run", "--rm", "--cpus=0.5", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(Equal("50000"))
+ }
})
It("podman run cpu-shares", func() {
SkipIfRootless()
- result := podmanTest.Podman([]string{"run", "--rm", "--cpu-shares=2", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.shares"})
- result.WaitWithDefaultTimeout()
- Expect(result.ExitCode()).To(Equal(0))
- Expect(result.OutputToString()).To(Equal("2"))
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if cgroupsv2 {
+ // [2-262144] is mapped to [1-10000]
+ result := podmanTest.Podman([]string{"run", "--rm", "--cpu-shares=262144", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpu.weight"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(Equal("10000"))
+ } else {
+ result := podmanTest.Podman([]string{"run", "--rm", "--cpu-shares=2", ALPINE, "cat", "/sys/fs/cgroup/cpu/cpu.shares"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(Equal("2"))
+ }
})
It("podman run cpuset-cpus", func() {
SkipIfRootless()
- result := podmanTest.Podman([]string{"run", "--rm", "--cpuset-cpus=0", ALPINE, "cat", "/sys/fs/cgroup/cpuset/cpuset.cpus"})
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var result *PodmanSessionIntegration
+
+ if cgroupsv2 {
+ result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-cpus=0", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpuset.cpus.effective"})
+ } else {
+ result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-cpus=0", ALPINE, "cat", "/sys/fs/cgroup/cpuset/cpuset.cpus"})
+ }
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(result.OutputToString()).To(Equal("0"))
@@ -81,7 +145,17 @@ var _ = Describe("Podman run cpu", func() {
It("podman run cpuset-mems", func() {
SkipIfRootless()
- result := podmanTest.Podman([]string{"run", "--rm", "--cpuset-mems=0", ALPINE, "cat", "/sys/fs/cgroup/cpuset/cpuset.mems"})
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var result *PodmanSessionIntegration
+
+ if cgroupsv2 {
+ result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-mems=0", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/cpuset.mems.effective"})
+ } else {
+ result = podmanTest.Podman([]string{"run", "--rm", "--cpuset-mems=0", ALPINE, "cat", "/sys/fs/cgroup/cpuset/cpuset.mems"})
+ }
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(result.OutputToString()).To(Equal("0"))
diff --git a/test/e2e/run_memory_test.go b/test/e2e/run_memory_test.go
index 8fe90c8d8..a45735a8a 100644
--- a/test/e2e/run_memory_test.go
+++ b/test/e2e/run_memory_test.go
@@ -5,6 +5,7 @@ package integration
import (
"os"
+ "github.com/containers/libpod/pkg/cgroups"
. "github.com/containers/libpod/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -36,7 +37,16 @@ var _ = Describe("Podman run memory", func() {
})
It("podman run memory test", func() {
- session := podmanTest.Podman([]string{"run", "--memory=40m", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes"})
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var session *PodmanSessionIntegration
+
+ if cgroupsv2 {
+ session = podmanTest.Podman([]string{"run", "--memory=40m", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/memory.max"})
+ } else {
+ session = podmanTest.Podman([]string{"run", "--memory=40m", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes"})
+ }
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("41943040"))
@@ -46,13 +56,31 @@ var _ = Describe("Podman run memory", func() {
if podmanTest.Host.Distribution == "ubuntu" {
Skip("Unable to perform test on Ubuntu distributions due to memory management")
}
- session := podmanTest.Podman([]string{"run", "--memory-reservation=40m", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.soft_limit_in_bytes"})
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var session *PodmanSessionIntegration
+
+ if cgroupsv2 {
+ session = podmanTest.Podman([]string{"run", "--memory-reservation=40m", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/memory.high"})
+ } else {
+ session = podmanTest.Podman([]string{"run", "--memory-reservation=40m", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.soft_limit_in_bytes"})
+ }
+
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("41943040"))
})
It("podman run memory-swappiness test", func() {
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if cgroupsv2 {
+ Skip("Memory swappiness not supported on cgroups v2")
+ }
+
session := podmanTest.Podman([]string{"run", "--memory-swappiness=15", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.swappiness"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -60,6 +88,12 @@ var _ = Describe("Podman run memory", func() {
})
It("podman run kernel-memory test", func() {
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if cgroupsv2 {
+ Skip("Kernel memory not supported on cgroups v2")
+ }
session := podmanTest.Podman([]string{"run", "--kernel-memory=40m", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.kmem.limit_in_bytes"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 1420a8403..ce2044a72 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -13,6 +13,7 @@ import (
"syscall"
"time"
+ "github.com/containers/libpod/pkg/cgroups"
. "github.com/containers/libpod/test/utils"
"github.com/containers/storage/pkg/stringid"
"github.com/mrunalp/fileutils"
@@ -263,9 +264,15 @@ var _ = Describe("Podman run", func() {
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("1024"))
- session = podmanTest.Podman([]string{"run", "--rm", "--oom-kill-disable=true", fedoraMinimal, "echo", "memory-hog"})
- session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(0))
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if !cgroupsv2 {
+ // --oom-kill-disable not supported on cgroups v2.
+ session = podmanTest.Podman([]string{"run", "--rm", "--oom-kill-disable=true", fedoraMinimal, "echo", "memory-hog"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ }
session = podmanTest.Podman([]string{"run", "--rm", "--oom-score-adj=100", fedoraMinimal, "cat", "/proc/self/oom_score_adj"})
session.WaitWithDefaultTimeout()
@@ -310,18 +317,43 @@ var _ = Describe("Podman run", func() {
It("podman run blkio-weight test", func() {
SkipIfRootless()
- if _, err := os.Stat("/sys/fs/cgroup/blkio/blkio.weight"); os.IsNotExist(err) {
- Skip("Kernel does not support blkio.weight")
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if !cgroupsv2 {
+ if _, err := os.Stat("/sys/fs/cgroup/blkio/blkio.weight"); os.IsNotExist(err) {
+ Skip("Kernel does not support blkio.weight")
+ }
+ }
+
+ if cgroupsv2 {
+ // convert linearly from [10-1000] to [1-10000]
+ session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.bfq.weight"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("51"))
+ } else {
+ session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.weight"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("15"))
}
- session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.weight"})
- session.WaitWithDefaultTimeout()
- Expect(session.ExitCode()).To(Equal(0))
- Expect(session.OutputToString()).To(ContainSubstring("15"))
})
It("podman run device-read-bps test", func() {
SkipIfRootless()
- session := podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"})
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var session *PodmanSessionIntegration
+
+ if cgroupsv2 {
+ session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
+ } else {
+ session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"})
+ }
+
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
@@ -329,7 +361,17 @@ var _ = Describe("Podman run", func() {
It("podman run device-write-bps test", func() {
SkipIfRootless()
- session := podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"})
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var session *PodmanSessionIntegration
+
+ if cgroupsv2 {
+ session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
+ } else {
+ session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"})
+ }
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
@@ -337,7 +379,18 @@ var _ = Describe("Podman run", func() {
It("podman run device-read-iops test", func() {
SkipIfRootless()
- session := podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"})
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var session *PodmanSessionIntegration
+
+ if cgroupsv2 {
+ session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
+ } else {
+ session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"})
+ }
+
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("100"))
@@ -345,7 +398,18 @@ var _ = Describe("Podman run", func() {
It("podman run device-write-iops test", func() {
SkipIfRootless()
- session := podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"})
+
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ var session *PodmanSessionIntegration
+
+ if cgroupsv2 {
+ session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
+ } else {
+ session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"})
+ }
+
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("100"))
diff --git a/version/version.go b/version/version.go
index d5f91210e..f0823f260 100644
--- a/version/version.go
+++ b/version/version.go
@@ -4,7 +4,7 @@ package version
// NOTE: remember to bump the version at the top
// of the top-level README.md file when this is
// bumped.
-const Version = "1.5.1-dev"
+const Version = "1.5.2-dev"
// RemoteAPIVersion is the version for the remote
// client API. It is used to determine compatibility