Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions data/containers/bats/skip.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,13 @@ podman:
# https://github.com/containers/podman/pull/26798 is needed for 505-networking-pasta
# https://github.com/containers/podman/pull/26920 is needed to drop ncat
# https://github.com/containers/podman/pull/26921 is needed to drop socat
# https://github.com/containers/podman/pull/26934 - test/e2e: fix 'block all syscalls' seccomp for runc
# https://github.com/containers/podman/pull/27152 is needed for 030-run
opensuse-Tumbleweed:
GITHUB_PATCHES:
- 26017
- 26798
- 26934
- 27152
BATS_IGNORE:
BATS_IGNORE_ROOT_LOCAL:
Expand Down
84 changes: 84 additions & 0 deletions data/containers/patches/podman/26934.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
From 18b5b2e2d699551dab8fb25c9969d231d5662513 Mon Sep 17 00:00:00 2001
From: Kir Kolyshkin <kolyshkin@gmail.com>
Date: Fri, 29 Aug 2025 17:18:44 -0700
Subject: [PATCH] test/e2e: fix 'block all syscalls' seccomp for runc

Error messages between runc and crun are not synchronized, and
in some case exit codes can be different, too.

Commit dd1bcabae9 ("CI: use local registry, part 2 of 3: fix tests")
removed the special case handling for runc from the
"podman run --seccomp-policy image (block all syscalls)"
test case, and so it fails, for example, like this:

Error: failed to connect to container's attach socket: /tmp/podman-e2e-2877753109/subtest-1698249469/p/root/overlay-containers/62585e98da7dc3fdb32d3b6de0980c762a8a6cde008ed35c68727fb97f5369c7/userdata/attach: no such file or directory
[FAILED] Command exited with status 127 (expected 126)

or this:

time="2025-08-29T17:16:52-07:00" level=error msg="cannot start a container that has stopped"
Error: `/usr/bin/runc start 63ce789f7037d9545cde832d29343704cab842e7288046407d0efa347d5ecb77` failed: exit status 1
[FAILED] Command exited 126 as expected, but did not emit 'OCI runtime error: runc: read from the init process'

(depending on runc version, phase of the moon etc.)

We can not reasonably expect a specific error message and exit code in
such an unusual scenario, but let's try.

With this commit, the above test passes successfully on my machine.

Tested with:

make localintegration FOCUS="block all syscalls" OCI_RUNTIME=/usr/local/bin/runc
make remoteintegration FOCUS="block all syscalls" OCI_RUNTIME=/usr/local/bin/runc

While at it, simplify the error message check for crun (we don't have to
check for the entire message, [the same] substring is fine for both
local and remote cases).

Fixes: dd1bcabae9 ("CI: use local registry, part 2 of 3: fix tests")
Reported-by: Yiqiao Pu <ypu@redhat.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
---
test/e2e/run_seccomp_test.go | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/test/e2e/run_seccomp_test.go b/test/e2e/run_seccomp_test.go
index 82a7a42831..ada74b071f 100644
--- a/test/e2e/run_seccomp_test.go
+++ b/test/e2e/run_seccomp_test.go
@@ -3,7 +3,7 @@
package integration

import (
- "fmt"
+ "path"

. "github.com/containers/podman/v5/test/utils"
. "github.com/onsi/ginkgo/v2"
@@ -55,11 +55,21 @@ var _ = Describe("Podman run", func() {
session := podmanTest.Podman([]string{"run", "--seccomp-policy", "image", img, "ls"})
session.WaitWithDefaultTimeout()

- expect := fmt.Sprintf("OCI runtime error: %s: read from the init process", podmanTest.OCIRuntime)
- if IsRemote() {
- expect = fmt.Sprintf("for attach: %s: read from the init process: OCI runtime error", podmanTest.OCIRuntime)
+ switch path.Base(podmanTest.OCIRuntime) {
+ case "crun":
+ // "crun create" fails with "read from the init process" error.
+ Expect(session).To(ExitWithError(126, "read from the init process"))
+ case "runc":
+ // "runc create" succeeds, then...
+ Expect(session).To(Or(
+ // either "runc start" fails with "cannot start a container that has stopped",
+ ExitWithError(126, "cannot start a container that has stopped"),
+ // or podman itself fails with "failed to connect to container's attach socket".
+ ExitWithError(127, "failed to connect to container's attach socket"),
+ ))
+ default:
+ Expect(session.ExitCode()).To(BeNumerically(">", 0), "Exit status using generic runtime")
}
- Expect(session).To(ExitWithError(126, expect))
})

It("podman run --seccomp-policy image (bogus profile)", func() {
5 changes: 3 additions & 2 deletions tests/containers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ In addition to the [BATS](bats/) tests we currently have tests for:
| --- | --- |
| [docker-compose](docker_compose.pm) | https://github.com/docker/compose/tree/main/pkg/e2e |
| [docker-py](python_runtime.pm) | https://github.com/docker/docker-py/tree/main/tests |
| [podman-py](python_runtime.pm) | https://github.com/containers/podman-py |
| [podman-py](python_runtime.pm) | https://github.com/containers/podman-py/tree/main/podman/tests |
| [podman](podman_e2e.pm) | https://github.com/containers/podman/tree/main/test/e2e |

Library code is found in [lib/containers/bats.pm](../../../lib/containers/bats.pm)

Expand All @@ -31,7 +32,7 @@ Note: These jobs are scheduled only for the x86_64 architecture.

Notes:
- `docker_testsuite` tests `docker-compose` & `docker-py`
- `podman_e2e` tests `podman-py` & the upcoming e2e tests.
- `podman_e2e` tests `podman-py` & `podman` (e2e)

[logo]: bats/logo.svg

Expand Down
112 changes: 112 additions & 0 deletions tests/containers/podman_e2e.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# SUSE's openQA tests
#
# Copyright SUSE LLC
# SPDX-License-Identifier: FSFAP

# Packages: python3-docker & python3-podman
# Summary: Test podman & docker python packages
# Maintainer: QE-C team <qa-c@suse.de>

use Mojo::Base 'containers::basetest', -signatures;
use testapi;
use serial_terminal qw(select_serial_terminal);
use power_action_utils 'power_action';
use version_utils;
use utils;
use containers::common qw(install_packages);
use containers::bats;

my $oci_runtime;
my $version;

sub setup {
my $self = shift;
my @pkgs = qw(aardvark-dns apache2-utils buildah catatonit glibc-devel-static go1.24 gpg2 jq libgpgme-devel
libseccomp-devel make netavark openssl podman podman-remote skopeo socat sudo systemd-container xfsprogs);
push @pkgs, qw(criu libcriu2) unless is_sle;
$oci_runtime = get_var("OCI_RUNTIME", "runc");
push @pkgs, $oci_runtime;

$self->setup_pkgs(@pkgs);
select_serial_terminal;

record_info "info", script_output("podman info -f json");
record_info("OCI runtime", script_output("$oci_runtime --version"));

# Workaround for https://bugzilla.opensuse.org/show_bug.cgi?id=1248988 - catatonit missing in /usr/libexec/podman/
run_command "cp -f /usr/bin/catatonit /usr/libexec/podman/catatonit";
# rootless user needed for these tests
run_command "useradd -m containers";
run_command "usermod --add-subuids 100000-165535 containers";
run_command "usermod --add-subgids 100000-165535 containers";
# Make /run/secrets directory available on containers
run_command "echo /var/lib/empty:/run/secrets >> /etc/containers/mounts.conf";

$version = script_output q(podman --version | awk '{ print $3 }');
record_info "version", $version;
$version = "v$version";

# Download podman sources
patch_sources "podman", $version, "test/e2e";
# This test fails with:
# Command exited 125 as expected, but did not emit 'failed to connect: dial tcp: lookup '
run_command "rm -f test/e2e/image_scp_test.go";

assert_script_run "curl -o /usr/local/bin/patch_junit " . data_url("containers/patch_junit.py");
assert_script_run "chmod +x /usr/local/bin/patch_junit";
}

sub run {
my ($self, $args) = @_;
select_serial_terminal;

$self->setup;
select_serial_terminal;

assert_script_run "cd /var/tmp/podman";

my $quadlet = script_output "rpm -ql podman | grep podman/quadlet";

my %env = (
OCI_RUNTIME => $oci_runtime,
PODMAN_BINARY => "/usr/bin/podman",
PODMAN_REMOTE_BINARY => "/usr/bin/podman-remote",
QUADLET_BINARY => "/usr/libexec/podman/quadlet",
TESTFLAGS => "--junit-report=report.xml",
);
my $env = join " ", map { "$_=$env{$_}" } sort keys %env;

# mapping of known expected failures
my @xfails = ();
unless (is_tumbleweed) {
# Fixed in podman 5.6.1:
# https://bugzilla.suse.com/show_bug.cgi?id=1249050 - podman passes volume options as bind mount options to runtime
push @xfails, (
'localintegration::[It] Podman run with volumes podman run with --mount and named volume with driver-opts',
'remoteintegration::[It] Podman run with volumes podman run with --mount and named volume with driver-opts',
'localintegration::[It] Podman run with volumes podman named volume copyup',
'remoteintegration::[It] Podman run with volumes podman named volume copyup',
);
}

my @targets = split('\s+', get_var('PODMAN_TARGETS', 'localintegration remoteintegration'));
foreach my $target (@targets) {
run_command "env $env make $target &> $target.txt || true", timeout => 1800;
script_run "mv report.xml $target.xml";
my $xfails = join(' ', map { "\"$_\"" } @xfails);
assert_script_run "patch_junit $target.xml $xfails";
patch_junit "podman", $version, "$target.xml";
parse_extra_log(XUnit => "$target.xml");
upload_logs("$target.txt");
}
}

sub post_fail_hook {
bats_post_hook;
}

sub post_run_hook {
bats_post_hook;
}

1;