From d26d04c76c5d3e825594a52b94fe5abf85beb142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Dost=C3=A1l?= Date: Wed, 3 Apr 2024 09:51:22 +0200 Subject: [PATCH] Introduce podman IPv6 test --- data/publiccloud/terraform/gce.tf | 3 +- lib/main_containers.pm | 2 + tests/containers/podman_ipv6.pm | 93 +++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 tests/containers/podman_ipv6.pm diff --git a/data/publiccloud/terraform/gce.tf b/data/publiccloud/terraform/gce.tf index 9a74e6b8b3b7..21fbb57a4b57 100644 --- a/data/publiccloud/terraform/gce.tf +++ b/data/publiccloud/terraform/gce.tf @@ -139,8 +139,9 @@ resource "google_compute_instance" "openqa" { network = "tf-network" subnetwork = "tf-subnetwork" access_config {} - stack_type = "IPV4_ONLY" + stack_type = "IPV4_IPV6" } + can_ip_forward = true service_account { email = data.external.gce_cred.result["client_email"] diff --git a/lib/main_containers.pm b/lib/main_containers.pm index 08594b0dd278..91e7ba3bb53e 100644 --- a/lib/main_containers.pm +++ b/lib/main_containers.pm @@ -13,6 +13,7 @@ use utils; use version_utils; use main_common qw(loadtest boot_hdd_image); use testapi qw(check_var get_required_var get_var set_var); +use publiccloud::utils 'is_gce'; use Utils::Architectures; use Utils::Backends; use strict; @@ -132,6 +133,7 @@ sub load_host_tests_podman { # Firewall is not installed in JeOS OpenStack, MicroOS and Public Cloud images load_firewall_test($run_args) unless (is_public_cloud || is_openstack || is_microos || is_alp); # Netavark not supported in 15-SP1 and 15-SP2 (due to podman version older than 4.0.0) + loadtest 'containers/podman_ipv6' if (is_public_cloud && is_gce && is_sle('>=15-SP5')); loadtest 'containers/podman_netavark' unless (is_staging || is_sle("<15-sp3") || is_ppc64le); # Buildah is not available in SLE Micro, MicroOS and staging projects load_buildah_tests($run_args) unless (is_sle('<15') || is_sle_micro || is_microos || is_leap_micro || is_alp || is_staging); diff --git a/tests/containers/podman_ipv6.pm b/tests/containers/podman_ipv6.pm new file mode 100644 index 000000000000..8d5defaa3702 --- /dev/null +++ b/tests/containers/podman_ipv6.pm @@ -0,0 +1,93 @@ +# SUSE's openQA tests +# +# Copyright 2023-2024 SUSE LLC +# SPDX-License-Identifier: FSFAP + +# Package: podman, netavark, aardvark +# Summary: Test podman IPv6 +# Maintainer: QE-C team + +use Mojo::Base 'containers::basetest'; +use testapi; +use serial_terminal qw(select_serial_terminal); +use version_utils qw(package_version_cmp is_transactional is_jeos is_leap is_sle_micro is_leap_micro is_sle is_microos is_public_cloud); +use containers::common qw(install_packages); +use containers::utils qw(get_podman_version registry_url); +use utils 'zypper_call'; +use Utils::Systemd qw(systemctl); +use Utils::Architectures qw(is_s390x); +use main_common qw(is_updates_tests); +use publiccloud::utils qw(is_gce); + +# clean up routine only for systems that run CNI as default network backend +sub _cleanup { + my $podman = shift->containers_factory('podman'); + select_console 'log-console'; + #$podman->cleanup_system_host(); + #validate_script_output('podman info --format {{.Host.NetworkBackend}}', sub { /netavark/ }); +} + +sub run { + my ($self, $args) = @_; + + my $image = 'registry.opensuse.org/opensuse/leap:latest'; + + select_serial_terminal; + my $podman = $self->containers_factory('podman'); + zypper_call('in bind-utils'); + + my $host_if = script_output('ip -6 route show default | awk "{print \$5; exit}"'); + record_info('HOST IF', $host_if); + my $host_addr = script_output("ip -6 addr show $host_if scope global | grep -oP 'inet6 \\K[^/]+' | head -n1"); + record_info('HOST ADDR', $host_addr); + my $host_gw = script_output('ip -6 route show default | awk "{print \$3}"'); + record_info('HOST GW', $host_gw); + my $subnet = $host_addr; + $subnet =~ s/::/:1:0\/112/g; + record_info('SUBNET', $subnet); + my $cont_addr = $subnet; + $cont_addr =~ s/:0\/112/:2/g; + record_info('CONT ADDR', $cont_addr); + + # Test host IPv6 connectivity + validate_script_output('curl -sSf6 https://wtfismyip.com/text', sub { m/$host_addr/g }); + # Test openSUSE registry over IPv6 + assert_script_run('curl -sSf6 https://registry.opensuse.org/v2/; echo $?'); + + # Block access to openSUSE registry via IPv4 + my $registry_ipv4 = script_output('dig +short registry.opensuse.org A | tail -n1'); + script_run("iptables -A OUTPUT -d $registry_ipv4 -j DROP"); + validate_script_output('iptables -L OUTPUT', sub { m/$registry_ipv4/g }); + # Test that access to openSUSE registry no longer works via IPv4 + assert_script_run("!curl -sSf4 https://registry.opensuse.org/v2/"); + # Test that access to openSUSE registry still works (IPv6 should work) + assert_script_run('curl -sSf https://registry.opensuse.org/v2/'); + # Pull image from openSUSE registry (over IPv6 now) + assert_script_run("podman pull $image", timeout => 300); + + # Create the IPv6 network + assert_script_run(sprintf('podman network create --ipv6 --subnet %s podman-ipv6', $subnet)); + assert_script_run("podman run --name test-ipv6 --network podman-ipv6 --ip6 $cont_addr -d -p 80:80 -p '[::]:80:80' $image sleep 999", timeout => 180); + + if(script_output('ip -6 r s default') !~ m/^default via/gi) { + record_soft_failure('bsc#1222239 - Host loses default IPv6 route when podman IPv6 network is created'); + assert_script_run("ip -6 route add default via $host_gw dev $host_if"); + assert_script_run('ip -6 r s default'); + } + + # Test host IPv6 connectivity + validate_script_output('curl -sSf6 https://wtfismyip.com/text', sub { m/$host_addr/g }); + # check that the container has IPv6 connectivity + # there is iptables masquarade so the container appears under the host address + validate_script_output('podman exec -it test-ipv6 curl -sSf6 https://wtfismyip.com/text', sub { m/$host_addr/g }); +} + +sub post_run_hook { + shift->_cleanup(); +} +sub post_fail_hook { + script_run("sysctl -a | grep --color=never net"); + shift->_cleanup(); +} + +1;