From 60c6e57b82f975d13da0335c5a9eca90f01449bb Mon Sep 17 00:00:00 2001 From: Albin Kerouanton Date: Tue, 26 Aug 2025 23:25:22 +0200 Subject: [PATCH] hack/make/test-integration: disable firewalld integration The daemon started by the test-integration script needs to run without firewalld integration to make sure that daemons started by networking tests will handle firewalld reload without any interference (i.e. without another daemon racing against them to recreate the iptables chains). Most tests are already running their own daemons, but the few that don't and need firewalld integration are updated to start their own. Signed-off-by: Albin Kerouanton --- daemon/libnetwork/iptables/firewalld.go | 9 +++++++++ hack/make/.integration-daemon-start | 8 ++++++++ integration/network/bridge/bridge_linux_test.go | 16 ++++++++++++++-- integration/networking/firewall_linux_test.go | 9 ++++++++- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/daemon/libnetwork/iptables/firewalld.go b/daemon/libnetwork/iptables/firewalld.go index 8dee26acd8..5453d6c520 100644 --- a/daemon/libnetwork/iptables/firewalld.go +++ b/daemon/libnetwork/iptables/firewalld.go @@ -5,6 +5,7 @@ package iptables import ( "context" "fmt" + "os" "strings" "sync" "sync/atomic" @@ -64,6 +65,14 @@ func FirewalldReloadedAt() time.Time { func firewalldInit() error { var err error + // DOCKER_TEST_NO_FIREWALLD is used by integration tests to disable firewalld integration to make sure that the + // daemon started by the 'test-integration' script won't recreate iptables / nftables rules upon receiving the + // firewalld reload signal, otherwise it'll race against the daemon-under-test started by networking integration + // tests. This is an internal implementation detail and users shall never rely on this. + if disable := os.Getenv("DOCKER_TEST_NO_FIREWALLD"); disable != "" { + return nil + } + if connection, err = newConnection(); err != nil { return fmt.Errorf("Failed to connect to D-Bus system bus: %v", err) } diff --git a/hack/make/.integration-daemon-start b/hack/make/.integration-daemon-start index 94b3e97f8c..5ebce9998f 100644 --- a/hack/make/.integration-daemon-start +++ b/hack/make/.integration-daemon-start @@ -119,6 +119,14 @@ if [ -z "$DOCKER_TEST_HOST" ]; then ( echo "Starting dockerd" [ -n "$TESTDEBUG" ] && set -x + if [ -n "${FIREWALLD:-}" ] && [ "${DOCKER_FIREWALL_BACKEND:-}" == "iptables" ]; then + # Networking integration tests start their own daemon to have fine control over the configuration of the + # daemon-under-test. Two daemons running with firewalld integration enabled would race against each other + # when the firewalld reload signal is dispatched, and would result in iptables disappearing unexpectedly + # from the point of view of the daemon-under-test. So, disable firewalld integration on this daemon, as it's + # only used to load frozen images. + export DOCKER_TEST_NO_FIREWALLD="true" + fi exec \ ${dockerd} --debug \ --host "$DOCKER_HOST" \ diff --git a/integration/network/bridge/bridge_linux_test.go b/integration/network/bridge/bridge_linux_test.go index 671d744479..2b89ee389e 100644 --- a/integration/network/bridge/bridge_linux_test.go +++ b/integration/network/bridge/bridge_linux_test.go @@ -368,7 +368,13 @@ func TestFilterForwardPolicy(t *testing.T) { // address is reserved for a gateway, because it won't be used). func TestPointToPoint(t *testing.T) { ctx := setupTest(t) - apiClient := testEnv.APIClient() + + d := daemon.New(t) + d.StartWithBusybox(ctx, t) + t.Cleanup(func() { d.Stop(t) }) + + apiClient := d.NewClientT(t) + t.Cleanup(func() { apiClient.Close() }) testcases := []struct { name string @@ -422,7 +428,13 @@ func TestIsolated(t *testing.T) { skip.If(t, testEnv.IsRootless, "can't inspect bridge addrs in rootless netns") ctx := setupTest(t) - apiClient := testEnv.APIClient() + + d := daemon.New(t) + d.StartWithBusybox(ctx, t) + t.Cleanup(func() { d.Stop(t) }) + + apiClient := d.NewClientT(t) + t.Cleanup(func() { apiClient.Close() }) const netName = "testisol" const bridgeName = "br-" + netName diff --git a/integration/networking/firewall_linux_test.go b/integration/networking/firewall_linux_test.go index e697d071df..64af7ebded 100644 --- a/integration/networking/firewall_linux_test.go +++ b/integration/networking/firewall_linux_test.go @@ -6,6 +6,7 @@ import ( "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/testutils/networking" + "github.com/moby/moby/v2/testutil/daemon" "github.com/moby/moby/v2/testutil/request" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -15,7 +16,13 @@ const defaultFirewallBackend = "iptables" func TestInfoFirewallBackend(t *testing.T) { ctx := setupTest(t) - c := testEnv.APIClient() + + d := daemon.New(t) + d.StartWithBusybox(ctx, t) + t.Cleanup(func() { d.Stop(t) }) + + c := d.NewClientT(t) + t.Cleanup(func() { c.Close() }) expDriver := defaultFirewallBackend if val := os.Getenv("DOCKER_FIREWALL_BACKEND"); val != "" {