From 70f826dcf2166191005db58774dc98d902ada521 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 | 7 ++- lib/main_containers.pm | 2 + lib/publiccloud/provider.pm | 3 ++ tests/containers/podman_ipv6.pm | 89 +++++++++++++++++++++++++++++++ variables.md | 1 + 5 files changed, 101 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..1672ccb45098 100644 --- a/data/publiccloud/terraform/gce.tf +++ b/data/publiccloud/terraform/gce.tf @@ -92,6 +92,10 @@ variable "ssh_public_key" { default = "/root/.ssh/id_ed25519.pub" } +variable "stack_type" { + default = "IPV4_ONLY" +} + resource "random_id" "service" { count = var.instance_count @@ -139,8 +143,9 @@ resource "google_compute_instance" "openqa" { network = "tf-network" subnetwork = "tf-subnetwork" access_config {} - stack_type = "IPV4_ONLY" + stack_type = var.stack_type } + 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..a8d8bcf2968d 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; @@ -131,6 +132,7 @@ sub load_host_tests_podman { loadtest('containers/podman_network_cni') unless (is_alp || is_sle_micro('6.0+') || (is_sle_micro('=5.5') && is_public_cloud)); # 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); + loadtest 'containers/podman_ipv6' if (is_public_cloud && is_gce && is_sle('>=15-SP5')); # Netavark not supported in 15-SP1 and 15-SP2 (due to podman version older than 4.0.0) loadtest 'containers/podman_netavark' unless (is_staging || is_sle("<15-sp3") || is_ppc64le); # Buildah is not available in SLE Micro, MicroOS and staging projects diff --git a/lib/publiccloud/provider.pm b/lib/publiccloud/provider.pm index eca56e247cd2..07bdaa4c842d 100644 --- a/lib/publiccloud/provider.pm +++ b/lib/publiccloud/provider.pm @@ -501,6 +501,9 @@ sub terraform_apply { # Note: Only the default Azure terraform profiles contains the 'storage-account' variable my $storage_account = get_var('PUBLIC_CLOUD_STORAGE_ACCOUNT'); $cmd .= "-var 'storage-account=$storage_account' " if ($storage_account); + } elsif (is_gce) { + my $stack_type = get_var('PUBLIC_CLOUD_GCE_STACK_TYPE', 'IPV4_ONLY'); + $cmd .= "-var 'stack_type=$stack_type' "; } $cmd .= "-var 'instance_count=" . $args{count} . "' "; $cmd .= "-var 'type=" . $instance_type . "' "; diff --git a/tests/containers/podman_ipv6.pm b/tests/containers/podman_ipv6.pm new file mode 100644 index 000000000000..291936f47a48 --- /dev/null +++ b/tests/containers/podman_ipv6.pm @@ -0,0 +1,89 @@ +# 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 publiccloud::utils '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(); +} + +sub run { + my ($self, $args) = @_; + + die('Please set PUBLIC_CLOUD_GCE_STACK_TYPE=IPV4_IPV6') if (is_gce && !check_var('PUBLIC_CLOUD_GCE_STACK_TYPE', 'IPV4_IPV6')); + + my $image = 'registry.opensuse.org/opensuse/leap:latest'; + + select_serial_terminal; + my $podman = $self->containers_factory('podman'); + install_packages('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 | grep -v suse'); + 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; diff --git a/variables.md b/variables.md index 5d649d3957ae..b18fb8f0dca1 100644 --- a/variables.md +++ b/variables.md @@ -314,6 +314,7 @@ PUBLIC_CLOUD_EC2_UPLOAD_SECGROUP | string | "" | Allow to instruct ec2uploadimg PUBLIC_CLOUD_EC2_UPLOAD_VPCSUBNET | string | "" | Allow to instruct ec2uploadimg script to use some existing VPC instead of creating new one. PUBLIC_CLOUD_EC2_BOOT_MODE | string | "uefi-preferred" | The `--boot-mode` parameter for `ec2uploadimg` script. Available values: `legacy-bios`, `uefi`, `uefi-preferred` Currently unused variable. Use `git blame` to get context. PUBLIC_CLOUD_EC2_IPV6_ADDRESS_COUNT | string | 0 | How many IPv6 addresses should the instance have +PUBLIC_CLOUD_GCE_STACK_TYPE | string | IPV4_ONLY | Network stack type, possible values: IPV4_IPV6 or IPV4_ONLY PUBLIC_CLOUD_FIO | boolean | false | If set, storage_perf test module is added to the job. PUBLIC_CLOUD_FIO_RUNTIME | integer | 300 | Set the execution time for each FIO tests. PUBLIC_CLOUD_FIO_SSD_SIZE | string | "100G" | Set the additional disk size for the FIO tests.