Merge pull request #49761 from robmry/add_info_firewallbackend

Add Info.FirewallBackend
This commit is contained in:
Paweł Gronowski
2025-04-07 17:00:45 +00:00
committed by GitHub
10 changed files with 125 additions and 1 deletions

View File

@@ -106,6 +106,10 @@ func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *ht
info.RegistryConfig.AllowNondistributableArtifactsCIDRs = []*registry.NetIPNet{}
info.RegistryConfig.AllowNondistributableArtifactsHostnames = []string{}
}
if versions.LessThan(version, "1.49") {
// FirewallBackend field introduced in API v1.49.
info.FirewallBackend = nil
}
// TODO(thaJeztah): Expected commits are deprecated, and should no longer be set in API 1.49.
info.ContainerdCommit.Expected = info.ContainerdCommit.ID //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.49.

View File

@@ -6856,6 +6856,8 @@ definitions:
description: "The network pool size"
type: "integer"
example: "24"
FirewallBackend:
$ref: "#/definitions/FirewallInfo"
Warnings:
description: |
List of warnings / informational messages about missing features, or
@@ -6939,6 +6941,37 @@ definitions:
default: "plugins.moby"
example: "plugins.moby"
FirewallInfo:
description: |
Information about the daemon's firewalling configuration.
This field is currently only used on Linux, and omitted on other platforms.
type: "object"
x-nullable: true
properties:
Driver:
description: |
The name of the firewall backend driver.
type: "string"
example: "nftables"
Info:
description: |
Information about the firewall backend, provided as
"label" / "value" pairs.
<p><br /></p>
> **Note**: The information returned in this field, including the
> formatting of values and labels, should not be considered stable,
> and may change without notice.
type: "array"
items:
type: "array"
items:
type: "string"
example:
- ["ReloadedAt", "2025-01-01T00:00:00Z"]
# PluginsInfo is a temp struct holding Plugins name
# registered with docker daemon. It is used by Info struct
PluginsInfo:

View File

@@ -73,6 +73,7 @@ type Info struct {
SecurityOptions []string
ProductLicense string `json:",omitempty"`
DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
FirewallBackend *FirewallInfo `json:"FirewallBackend,omitempty"`
CDISpecDirs []string
Containerd *ContainerdInfo `json:",omitempty"`
@@ -151,3 +152,11 @@ type NetworkAddressPool struct {
Base string
Size int
}
// FirewallInfo describes the firewall backend.
type FirewallInfo struct {
// Driver is the name of the firewall backend driver.
Driver string `json:"Driver"`
// Info is a list of label/value pairs, containing information related to the firewall.
Info [][2]string `json:"Info,omitempty"`
}

View File

@@ -93,6 +93,7 @@ func (daemon *Daemon) SystemInfo(ctx context.Context) (*system.Info, error) {
daemon.fillSecurityOptions(v, sysInfo, &cfg.Config)
daemon.fillLicense(v)
daemon.fillDefaultAddressPools(ctx, v, &cfg.Config)
daemon.fillFirewallInfo(v)
return v, nil
}
@@ -284,6 +285,13 @@ func (daemon *Daemon) fillDefaultAddressPools(ctx context.Context, v *system.Inf
}
}
func (daemon *Daemon) fillFirewallInfo(v *system.Info) {
if daemon.netController == nil {
return
}
v.FirewallBackend = daemon.netController.FirewallBackend()
}
func hostName(ctx context.Context) string {
ctx, span := tracing.StartSpan(ctx, "hostName")
defer span.End()

View File

@@ -21,6 +21,8 @@ keywords: "API, Docker, rcli, REST, documentation"
encoded OCI Platform type) allowing to specify a platform of the multi-platform
image to inspect.
This option is mutually exclusive with the `manifests` option.
* `GET /info` now returns a `FirewallBackend` containing information about
the daemon's firewalling configuration.
## v1.48 API changes

View File

@@ -0,0 +1,37 @@
package networking
import (
"testing"
"github.com/docker/docker/client"
"github.com/docker/docker/internal/testutils/networking"
"github.com/docker/docker/testutil/request"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestInfoFirewallBackend(t *testing.T) {
ctx := setupTest(t)
c := testEnv.APIClient()
expDriver := "iptables"
if !testEnv.IsRootless() && networking.FirewalldRunning() {
expDriver = "iptables+firewalld"
}
info, err := c.Info(ctx)
assert.NilError(t, err)
assert.Assert(t, info.FirewallBackend != nil, "expected firewall backend in info response")
t.Log("FirewallBackend: Driver:", info.FirewallBackend.Driver)
for _, kv := range info.FirewallBackend.Info {
t.Logf("FirewallBackend: %s: %s", kv[0], kv[1])
}
assert.Check(t, is.Equal(info.FirewallBackend.Driver, expDriver))
// Check FirewallBackend is omitted for API <= 1.48.
t.Run("api 1.48", func(t *testing.T) {
c148 := request.NewAPIClient(t, client.WithVersion("1.48"))
info148, err := c148.Info(ctx)
assert.NilError(t, err)
assert.Check(t, is.Nil(info148.FirewallBackend))
})
}

View File

@@ -6,12 +6,25 @@ import (
"sync"
"github.com/containerd/log"
"github.com/docker/docker/api/types/system"
"github.com/docker/docker/libnetwork/iptables"
"github.com/docker/docker/libnetwork/netlabel"
"github.com/docker/docker/libnetwork/options"
"github.com/docker/docker/libnetwork/osl"
)
// FirewallBackend returns the name of the firewall backend for "docker info".
func (c *Controller) FirewallBackend() *system.FirewallInfo {
usingFirewalld, err := iptables.UsingFirewalld()
if err != nil {
return nil
}
if usingFirewalld {
return &system.FirewallInfo{Driver: "iptables+firewalld"}
}
return &system.FirewallInfo{Driver: "iptables"}
}
// enabledIptablesVersions returns the iptables versions that are enabled
// for the controller.
func (c *Controller) enabledIptablesVersions() []iptables.IPVersion {

View File

@@ -2,6 +2,13 @@
package libnetwork
import "github.com/docker/docker/api/types/system"
// FirewallBackend returns the name of the firewall backend for "docker info".
func (c *Controller) FirewallBackend() *system.FirewallInfo {
return nil
}
// enabledIptablesVersions is a no-op on non-Linux systems.
func (c *Controller) enabledIptablesVersions() []any {
return nil

View File

@@ -8,6 +8,7 @@ import (
"strings"
"github.com/containerd/log"
"github.com/docker/docker/pkg/rootless"
dbus "github.com/godbus/dbus/v5"
"github.com/pkg/errors"
)
@@ -40,7 +41,10 @@ var (
// 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 !firewalldInitCalled {
// 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, fmt.Errorf("iptables.firewalld is not initialised")
}
return firewalldRunning, nil

View File

@@ -982,6 +982,13 @@ func (d *Daemon) Info(t testing.TB) system.Info {
return info
}
func (d *Daemon) FirewallBackendDriver(t testing.TB) string {
t.Helper()
info := d.Info(t)
assert.Assert(t, info.FirewallBackend != nil, "no firewall backend reported")
return info.FirewallBackend.Driver
}
// TamperWithContainerConfig modifies the on-disk config of a container.
func (d *Daemon) TamperWithContainerConfig(t testing.TB, containerID string, tamper func(*container.Container)) {
t.Helper()