mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Run CI tests with nftables
Signed-off-by: Rob Murray <rob.murray@docker.com>
This commit is contained in:
25
.github/workflows/.test.yml
vendored
25
.github/workflows/.test.yml
vendored
@@ -145,6 +145,7 @@ jobs:
|
||||
];
|
||||
if ("${{ inputs.storage }}" == "snapshotter") {
|
||||
includes.push({ os: 'ubuntu-24.04', mode: 'firewalld' });
|
||||
includes.push({ os: 'ubuntu-24.04', mode: 'nftables' });
|
||||
}
|
||||
await core.group(`Set matrix`, async () => {
|
||||
core.info(`matrix: ${JSON.stringify(includes)}`);
|
||||
@@ -190,6 +191,9 @@ jobs:
|
||||
echo "FIREWALLD=true" >> $GITHUB_ENV
|
||||
CACHE_DEV_SCOPE="${CACHE_DEV_SCOPE}firewalld"
|
||||
fi
|
||||
if [[ "${{ matrix.mode }}" == *"nftables"* ]]; then
|
||||
echo "DOCKER_FIREWALL_BACKEND=nftables" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "CACHE_DEV_SCOPE=${CACHE_DEV_SCOPE}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
@@ -328,7 +332,7 @@ jobs:
|
||||
// 'include' with other matrix variables that aren't part of the
|
||||
// include items.
|
||||
// Moreover, since the goal is to run only relevant tests with
|
||||
// firewalld enabled to minimize the number of CI jobs, we
|
||||
// firewalld/nftables enabled to minimize the number of CI jobs, we
|
||||
// statically define the list of test suites that we want to run.
|
||||
if ("${{ inputs.storage }}" == "snapshotter") {
|
||||
matrix.include.push({
|
||||
@@ -343,6 +347,18 @@ jobs:
|
||||
'mode': 'firewalld',
|
||||
'test': 'DockerNetworkSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'nftables',
|
||||
'test': 'DockerCLINetworkSuite|DockerCLIPortSuite|DockerDaemonSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'nftables',
|
||||
'test': 'DockerSwarmSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'nftables',
|
||||
'test': 'DockerNetworkSuite'
|
||||
});
|
||||
}
|
||||
await core.group(`Set matrix`, async () => {
|
||||
core.info(`matrix: ${JSON.stringify(matrix)}`);
|
||||
@@ -380,6 +396,9 @@ jobs:
|
||||
echo "FIREWALLD=true" >> $GITHUB_ENV
|
||||
CACHE_DEV_SCOPE="${CACHE_DEV_SCOPE}firewalld"
|
||||
fi
|
||||
if [[ "${{ matrix.mode }}" == *"nftables"* ]]; then
|
||||
echo "DOCKER_FIREWALL_BACKEND=nftables" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "CACHE_DEV_SCOPE=${CACHE_DEV_SCOPE}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
@@ -437,7 +456,7 @@ jobs:
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-reports-integration-cli-${{ inputs.storage }}-${{ env.TESTREPORTS_NAME }}
|
||||
name: test-reports-integration-cli-${{ inputs.storage }}-${{ matrix.mode }}-${{ env.TESTREPORTS_NAME }}
|
||||
path: /tmp/reports/*
|
||||
retention-days: 1
|
||||
|
||||
@@ -460,7 +479,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: /tmp/reports
|
||||
pattern: test-reports-integration-cli-${{ inputs.storage }}-*
|
||||
pattern: test-reports-integration-cli-${{ inputs.storage }}-${{ matrix.mode }}-*
|
||||
merge-multiple: true
|
||||
-
|
||||
name: Install teststat
|
||||
|
||||
1
Makefile
1
Makefile
@@ -38,6 +38,7 @@ DOCKER_ENVS := \
|
||||
-e DOCKERCLI_INTEGRATION_REPOSITORY \
|
||||
-e DOCKER_DEBUG \
|
||||
-e DOCKER_EXPERIMENTAL \
|
||||
-e DOCKER_FIREWALL_BACKEND \
|
||||
-e DOCKER_GITCOMMIT \
|
||||
-e DOCKER_GRAPHDRIVER \
|
||||
-e DOCKER_LDFLAGS \
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package networking
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
@@ -10,12 +11,16 @@ import (
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
const defaultFirewallBackend = "iptables"
|
||||
|
||||
func TestInfoFirewallBackend(t *testing.T) {
|
||||
ctx := setupTest(t)
|
||||
c := testEnv.APIClient()
|
||||
|
||||
expDriver := "iptables"
|
||||
if !testEnv.IsRootless() && networking.FirewalldRunning() {
|
||||
expDriver := defaultFirewallBackend
|
||||
if val := os.Getenv("DOCKER_FIREWALL_BACKEND"); val != "" {
|
||||
expDriver = val
|
||||
} else if !testEnv.IsRootless() && networking.FirewalldRunning() {
|
||||
expDriver = "iptables+firewalld"
|
||||
}
|
||||
info, err := c.Info(ctx)
|
||||
|
||||
@@ -20,11 +20,7 @@ func (c *Controller) FirewallBackend() *system.FirewallInfo {
|
||||
if nftables.Enabled() {
|
||||
return &system.FirewallInfo{Driver: "nftables"}
|
||||
}
|
||||
usingFirewalld, err := iptables.UsingFirewalld()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if usingFirewalld {
|
||||
if iptables.UsingFirewalld() {
|
||||
info := &system.FirewallInfo{Driver: "iptables+firewalld"}
|
||||
reloadedAt := iptables.FirewalldReloadedAt()
|
||||
if !reloadedAt.IsZero() {
|
||||
|
||||
@@ -21,16 +21,8 @@ import (
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
func usingFirewalld() bool {
|
||||
// Check for existence of a dummy rule to make sure iptables is initialised - then can
|
||||
// check whether firewalld is running.
|
||||
_ = iptables.GetIptable(iptables.IPv4).Exists(iptables.Filter, "FORWARD", "-j", "DROP")
|
||||
fw, _ := iptables.UsingFirewalld()
|
||||
return fw
|
||||
}
|
||||
|
||||
func TestCleanupIptableRules(t *testing.T) {
|
||||
skip.If(t, usingFirewalld(), "firewalld is running in the host netns, it can't modify rules in the test's netns")
|
||||
skip.If(t, iptables.UsingFirewalld(), "firewalld is running in the host netns, it can't modify rules in the test's netns")
|
||||
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
bridgeChains := []struct {
|
||||
@@ -86,7 +78,7 @@ func TestCleanupIptableRules(t *testing.T) {
|
||||
|
||||
// TestIptabler tests combinations of firewaller options against golden results.
|
||||
func TestIptabler(t *testing.T) {
|
||||
skip.If(t, usingFirewalld(), "firewalld is running in the host netns, it can't modify rules in the test's netns")
|
||||
skip.If(t, iptables.UsingFirewalld(), "firewalld is running in the host netns, it can't modify rules in the test's netns")
|
||||
|
||||
const (
|
||||
ipv4 int64 = iota
|
||||
|
||||
@@ -14,6 +14,10 @@ import (
|
||||
const userChain = "DOCKER-USER"
|
||||
|
||||
func (c *Controller) selectFirewallBackend() {
|
||||
// Don't try to enable nftables if firewalld is running.
|
||||
if iptables.UsingFirewalld() {
|
||||
return
|
||||
}
|
||||
// Only try to use nftables if explicitly enabled by env-var.
|
||||
// TODO(robmry) - command line options?
|
||||
if os.Getenv("DOCKER_FIREWALL_BACKEND") == "nftables" {
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/pkg/rootless"
|
||||
dbus "github.com/godbus/dbus/v5"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -35,8 +34,7 @@ type Conn struct {
|
||||
var (
|
||||
connection *Conn
|
||||
|
||||
firewalldInitCalled bool
|
||||
firewalldRunning bool // is Firewalld service running
|
||||
firewalldRunning bool // is Firewalld service running
|
||||
// Time of the last firewalld reload.
|
||||
firewalldReloadedAt atomic.Value
|
||||
// Mutex to serialise firewalld reload callbacks.
|
||||
@@ -45,16 +43,10 @@ var (
|
||||
)
|
||||
|
||||
// UsingFirewalld returns true if iptables rules will be applied via firewalld's
|
||||
// passthrough interface. The error return is non-nil if the status cannot be
|
||||
// determined because the initialisation function has not been called.
|
||||
func UsingFirewalld() (bool, error) {
|
||||
// If called before startup has completed, the firewall backend is unknown.
|
||||
// But, if running rootless, the init function is not called because
|
||||
// firewalld will be running in the host's netns, not in rootlesskit's.
|
||||
if !firewalldInitCalled && !rootless.RunningWithRootlessKit() {
|
||||
return false, errors.New("iptables.firewalld is not initialised")
|
||||
}
|
||||
return firewalldRunning, nil
|
||||
// passthrough interface.
|
||||
func UsingFirewalld() bool {
|
||||
_ = initCheck()
|
||||
return firewalldRunning
|
||||
}
|
||||
|
||||
// FirewalldReloadedAt returns the time at which the daemon last completed a
|
||||
@@ -72,7 +64,6 @@ func FirewalldReloadedAt() time.Time {
|
||||
func firewalldInit() error {
|
||||
var err error
|
||||
|
||||
firewalldInitCalled = true
|
||||
if connection, err = newConnection(); err != nil {
|
||||
return fmt.Errorf("Failed to connect to D-Bus system bus: %v", err)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/docker/docker/internal/testutils/netnsutils"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -258,10 +259,7 @@ func TestExistsRaw(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRule(t *testing.T) {
|
||||
_ = firewalldInit()
|
||||
if res, _ := UsingFirewalld(); res {
|
||||
t.Skip("firewalld in host netns cannot create rules in the test's netns")
|
||||
}
|
||||
skip.If(t, UsingFirewalld(), "firewalld is running in the host netns, it can't modify rules in the test's netns")
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
|
||||
assert.NilError(t, exec.Command("iptables", "-N", "TESTCHAIN").Run())
|
||||
|
||||
Reference in New Issue
Block a user