summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--docs/source/markdown/podman-build.1.md4
-rw-r--r--docs/source/markdown/podman-create.1.md6
-rw-r--r--docs/source/markdown/podman-play-kube.1.md6
-rw-r--r--docs/source/markdown/podman-pod-create.1.md6
-rw-r--r--docs/source/markdown/podman-run.1.md6
-rw-r--r--libpod/networking_slirp4netns.go1
-rw-r--r--pkg/specgen/generate/container.go19
-rw-r--r--test/e2e/benchmarks_test.go173
-rw-r--r--test/e2e/common_test.go2
-rw-r--r--test/e2e/healthcheck_run_test.go2
-rw-r--r--test/utils/utils.go13
12 files changed, 230 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index af9a2b7f6..e94d4cf73 100644
--- a/Makefile
+++ b/Makefile
@@ -553,8 +553,8 @@ test: localunit localintegration remoteintegration localsystem remotesystem ##
.PHONY: ginkgo-run
ginkgo-run:
- $(GOBIN)/ginkgo version
- $(GOBIN)/ginkgo -v $(TESTFLAGS) -tags "$(TAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/. $(HACK)
+ ACK_GINKGO_RC=true $(GOBIN)/ginkgo version
+ ACK_GINKGO_RC=true $(GOBIN)/ginkgo -v $(TESTFLAGS) -tags "$(TAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/. $(HACK)
.PHONY: ginkgo
ginkgo:
@@ -570,6 +570,14 @@ localintegration: test-binaries ginkgo
.PHONY: remoteintegration
remoteintegration: test-binaries ginkgo-remote
+.PHONY: localbenchmarks
+localbenchmarks: test-binaries
+ ACK_GINKGO_RC=true $(GOBIN)/ginkgo \
+ -focus "Podman Benchmark Suite" \
+ -tags "$(BUILDTAGS) benchmarks" -noColor \
+ -noisySkippings=false -noisyPendings=false \
+ test/e2e/.
+
.PHONY: localsystem
localsystem:
# Wipe existing config, database, and cache: start with clean slate.
diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md
index 03ff88aeb..1080581d7 100644
--- a/docs/source/markdown/podman-build.1.md
+++ b/docs/source/markdown/podman-build.1.md
@@ -495,6 +495,10 @@ If the pull option is set to `always` (with *--pull=always*),
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 pull option is set to `missing` (with *--pull=missing*),
+Pull the image only if it is not present in the local storage. Raise an error if it
+could neither be found in the local storage or on a registry.
+
If the pull option is set to `never` (with *--pull=never*),
Do not pull the image from the registry, use only the local version. Raise an error
if the image is not present locally.
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 45d0d0b3e..f6d028f4d 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -718,11 +718,11 @@ Valid _mode_ values are:
- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
- **ns:**_path_: Path to a network namespace to join.
- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootfull containers and **slirp4netns** for rootless ones.
-- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
- - **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`, which is added to `/etc/hosts` as `host.containers.internal` for your convenience). Default is false.
+- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
+ - **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
- **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`).
- - **enable_ipv6=true|false**: Enable IPv6. Default is false. (Required for `outbound_addr6`).
+ - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`).
- **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only).
- **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to.
- **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only).
diff --git a/docs/source/markdown/podman-play-kube.1.md b/docs/source/markdown/podman-play-kube.1.md
index b959f6dd9..471c17f91 100644
--- a/docs/source/markdown/podman-play-kube.1.md
+++ b/docs/source/markdown/podman-play-kube.1.md
@@ -201,11 +201,11 @@ Valid _mode_ values are:
- **container:**_id_: Reuse another container's network stack.
- **ns:**_path_: Path to a network namespace to join.
- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootfull containers and **slirp4netns** for rootless ones.
-- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
- - **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`, which is added to `/etc/hosts` as `host.containers.internal` for your convenience). Default is false.
+- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
+ - **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
- **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`).
- - **enable_ipv6=true|false**: Enable IPv6. Default is false. (Required for `outbound_addr6`).
+ - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`).
- **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only).
- **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to.
- **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only).
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index 2ae4453c9..1bf14efdb 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -166,11 +166,11 @@ Valid _mode_ values are:
- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
- **ns:**_path_: Path to a network namespace to join.
- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootfull containers and **slirp4netns** for rootless ones.
-- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
- - **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`, which is added to `/etc/hosts` as `host.containers.internal` for your convenience). Default is false.
+- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
+ - **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
- **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`).
- - **enable_ipv6=true|false**: Enable IPv6. Default is false. (Required for `outbound_addr6`).
+ - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`).
- **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only).
- **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to.
- **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only).
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 5c276c04a..8f72d4f49 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -742,11 +742,11 @@ Valid _mode_ values are:
- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
- **ns:**_path_: Path to a network namespace to join.
- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootfull containers and **slirp4netns** for rootless ones.
-- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
- - **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`, which is added to `/etc/hosts` as `host.containers.internal` for your convenience). Default is false.
+- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
+ - **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
- **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`).
- - **enable_ipv6=true|false**: Enable IPv6. Default is false. (Required for `outbound_addr6`).
+ - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`).
- **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only).
- **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to.
- **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only).
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index 3f2842d4c..4a0ef0b3a 100644
--- a/libpod/networking_slirp4netns.go
+++ b/libpod/networking_slirp4netns.go
@@ -88,6 +88,7 @@ func parseSlirp4netnsNetworkOptions(r *Runtime, extraOptions []string) (*slirp4n
disableHostLoopback: true,
mtu: slirp4netnsMTU,
noPivotRoot: r.config.Engine.NoPivotRoot,
+ enableIPv6: true,
}
for _, o := range slirpOptions {
parts := strings.SplitN(o, "=", 2)
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index f7ea2edfa..5f4218899 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -67,12 +67,21 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
// NOTE: the health check is only set for Docker images
// but inspect will take care of it.
s.HealthConfig = inspectData.HealthCheck
- if s.HealthConfig != nil && s.HealthConfig.Timeout == 0 {
- hct, err := time.ParseDuration(define.DefaultHealthCheckTimeout)
- if err != nil {
- return nil, err
+ if s.HealthConfig != nil {
+ if s.HealthConfig.Timeout == 0 {
+ hct, err := time.ParseDuration(define.DefaultHealthCheckTimeout)
+ if err != nil {
+ return nil, err
+ }
+ s.HealthConfig.Timeout = hct
+ }
+ if s.HealthConfig.Interval == 0 {
+ hct, err := time.ParseDuration(define.DefaultHealthCheckInterval)
+ if err != nil {
+ return nil, err
+ }
+ s.HealthConfig.Interval = hct
}
- s.HealthConfig.Timeout = hct
}
}
diff --git a/test/e2e/benchmarks_test.go b/test/e2e/benchmarks_test.go
new file mode 100644
index 000000000..c631b06ee
--- /dev/null
+++ b/test/e2e/benchmarks_test.go
@@ -0,0 +1,173 @@
+//go:build benchmarks
+// +build benchmarks
+
+package integration
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+ "strconv"
+ "strings"
+
+ . "github.com/containers/podman/v4/test/utils"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
+)
+
+var (
+ // Number of times to execute each benchmark.
+ numBenchmarkSamples = 3
+ // All benchmarks are ququed here.
+ allBenchmarks []benchmark
+)
+
+// An internal struct for queuing benchmarks.
+type benchmark struct {
+ // The name of the benchmark.
+ name string
+ // The function to execute.
+ main func()
+ // Function is run before `main`.
+ init func()
+}
+
+// Allows for customizing the benchnmark in an easy to extend way.
+type newBenchmarkOptions struct {
+ // Sets the benchmark's init function.
+ init func()
+}
+
+// Queue a new benchmark.
+func newBenchmark(name string, main func(), options *newBenchmarkOptions) {
+ bm := benchmark{name: name, main: main}
+ if options != nil {
+ bm.init = options.init
+ }
+ allBenchmarks = append(allBenchmarks, bm)
+}
+
+var _ = Describe("Podman Benchmark Suite", func() {
+ var (
+ timedir string
+ podmanTest *PodmanTestIntegration
+ )
+
+ setup := func() {
+ tempdir, err := CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ podmanTest = PodmanTestCreate(tempdir)
+ podmanTest.Setup()
+
+ timedir, err = CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ }
+
+ cleanup := func() {
+ podmanTest.Cleanup()
+ os.RemoveAll(timedir)
+ }
+
+ totalMemoryInKb := func() (total uint64) {
+ files, err := ioutil.ReadDir(timedir)
+ if err != nil {
+ Fail(fmt.Sprintf("Error reading timing dir: %v", err))
+ }
+
+ for _, f := range files {
+ if f.IsDir() {
+ continue
+ }
+ raw, err := ioutil.ReadFile(path.Join(timedir, f.Name()))
+ if err != nil {
+ Fail(fmt.Sprintf("Error reading timing file: %v", err))
+ }
+ rawS := strings.TrimSuffix(string(raw), "\n")
+ number, err := strconv.ParseUint(rawS, 10, 64)
+ if err != nil {
+ Fail(fmt.Sprintf("Error converting timing file to numeric value: %v", err))
+ }
+ total += number
+ }
+
+ return total
+ }
+
+ // Make sure to clean up after the benchmarks.
+ AfterEach(func() {
+ cleanup()
+ })
+
+ // All benchmarks are executed here to have *one* table listing all data.
+ Measure("Podman Benchmark Suite", func(b Benchmarker) {
+ for i := range allBenchmarks {
+ setup()
+ bm := allBenchmarks[i]
+ if bm.init != nil {
+ bm.init()
+ }
+
+ // Set the time dir only for the main() function.
+ os.Setenv(EnvTimeDir, timedir)
+ b.Time("[CPU] "+bm.name, bm.main)
+ os.Unsetenv(EnvTimeDir)
+
+ mem := totalMemoryInKb()
+ b.RecordValueWithPrecision("[MEM] "+bm.name, float64(mem), "KB", 1)
+ cleanup()
+ }
+ }, numBenchmarkSamples)
+
+ BeforeEach(func() {
+
+ // --------------------------------------------------------------------------
+ // IMAGE BENCHMARKS
+ // --------------------------------------------------------------------------
+
+ newBenchmark("podman images", func() {
+ session := podmanTest.Podman([]string{"images"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ }, nil)
+
+ newBenchmark("podman pull", func() {
+ session := podmanTest.Podman([]string{"pull", "quay.io/libpod/cirros"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ }, nil)
+
+ // --------------------------------------------------------------------------
+ // CONTAINER BENCHMARKS
+ // --------------------------------------------------------------------------
+
+ newBenchmark("podman create", func() {
+ session := podmanTest.Podman([]string{"run", ALPINE, "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ }, nil)
+
+ newBenchmark("podman start", func() {
+ session := podmanTest.Podman([]string{"start", "foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ }, &newBenchmarkOptions{
+ init: func() {
+ session := podmanTest.Podman([]string{"create", "--name=foo", ALPINE, "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ },
+ })
+
+ newBenchmark("podman run", func() {
+ session := podmanTest.Podman([]string{"run", ALPINE, "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ }, nil)
+ })
+})
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index 620494b34..9580230b5 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -849,7 +849,7 @@ func (p *PodmanTestIntegration) makeOptions(args []string, noEvents, noCache boo
}
var debug string
- if _, ok := os.LookupEnv("DEBUG"); ok {
+ if _, ok := os.LookupEnv("E2E_DEBUG"); ok {
debug = "--log-level=debug --syslog=true "
}
diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go
index 757eaed20..23f1a1dbf 100644
--- a/test/e2e/healthcheck_run_test.go
+++ b/test/e2e/healthcheck_run_test.go
@@ -325,6 +325,8 @@ HEALTHCHECK CMD ls -l / 2>&1`, ALPINE)
inspect := podmanTest.InspectContainer("hctest")
// Check to make sure a default time value was added
Expect(inspect[0].Config.Healthcheck.Timeout).To(BeNumerically("==", 30000000000))
+ // Check to make sure a default time interval value was added
+ Expect(inspect[0].Config.Healthcheck.Interval).To(BeNumerically("==", 30000000000))
// Check to make sure characters were not coerced to utf8
Expect(inspect[0].Config.Healthcheck.Test).To(Equal([]string{"CMD-SHELL", "ls -l / 2>&1"}))
})
diff --git a/test/utils/utils.go b/test/utils/utils.go
index 57f002130..da56a3a2e 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -27,6 +27,8 @@ const (
CNI NetworkBackend = iota
// Netavark network backend
Netavark NetworkBackend = iota
+ // Env variable for creating time files.
+ EnvTimeDir = "_PODMAN_TIME_DIR"
)
func (n NetworkBackend) ToString() string {
@@ -96,6 +98,17 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string
if p.RemoteTest {
podmanBinary = p.RemotePodmanBinary
}
+
+ if timeDir := os.Getenv(EnvTimeDir); timeDir != "" {
+ timeFile, err := ioutil.TempFile(timeDir, ".time")
+ if err != nil {
+ Fail(fmt.Sprintf("Error creating time file: %v", err))
+ }
+ timeArgs := []string{"-f", "%M", "-o", timeFile.Name()}
+ timeCmd := append([]string{"/usr/bin/time"}, timeArgs...)
+ wrapper = append(timeCmd, wrapper...)
+ }
+
runCmd := append(wrapper, podmanBinary)
if p.NetworkBackend == Netavark {
runCmd = append(runCmd, []string{"--network-backend", "netavark"}...)