daemon/config: make DNSConfig.DNS a netip.Addr

Modernize the field and allow using it as-is in some places, or
convert it to a string (which won't produce an error down the line).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-08-01 18:27:42 +02:00
parent 5f121ce463
commit 5365f08ae2
9 changed files with 37 additions and 28 deletions

View File

@@ -45,7 +45,7 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
_ = flags.MarkHidden("network-diagnostic-port")
flags.BoolVar(&conf.RawLogs, "raw-logs", false, "Full timestamps without ANSI coloring")
flags.IPSliceVar(&conf.DNS, "dns", conf.DNS, "DNS server to use")
flags.Var(dopts.NewNamedIPListOptsRef("dns", &conf.DNS), "dns", "DNS server to use")
flags.Var(opts.NewNamedListOptsRef("dns-opts", &conf.DNSOptions, nil), "dns-opt", "DNS options to use")
flags.Var(opts.NewListOptsRef(&conf.DNSSearch, opts.ValidateDNSSearch), "dns-search", "DNS search domains to use")
flags.Var(dopts.NewNamedIPListOptsRef("host-gateway-ips", &conf.HostGatewayIPs), "host-gateway-ip", "IP addresses that the special 'host-gateway' string in --add-host resolves to. Defaults to the IP addresses of the default bridge")

View File

@@ -170,7 +170,7 @@ type TLSOptions struct {
// DNSConfig defines the DNS configurations.
type DNSConfig struct {
DNS []net.IP `json:"dns,omitempty"`
DNS []netip.Addr `json:"dns,omitempty"`
DNSOptions []string `json:"dns-opts,omitempty"`
DNSSearch []string `json:"dns-search,omitempty"`
HostGatewayIP net.IP `json:"host-gateway-ip,omitempty"` // Deprecated: this single-IP is migrated to HostGatewayIPs

View File

@@ -658,12 +658,12 @@ func TestConfigInvalidDNS(t *testing.T) {
{
doc: "single DNS, invalid IP-address",
input: `{"dns": ["1.1.1.1o"]}`,
expectedErr: `invalid IP address: 1.1.1.1o`,
expectedErr: `ParseAddr("1.1.1.1o"): unexpected character (at "o")`,
},
{
doc: "multiple DNS, invalid IP-address",
input: `{"dns": ["2.2.2.2", "1.1.1.1o"]}`,
expectedErr: `invalid IP address: 1.1.1.1o`,
expectedErr: `ParseAddr("1.1.1.1o"): unexpected character (at "o")`,
},
}
@@ -671,7 +671,7 @@ func TestConfigInvalidDNS(t *testing.T) {
t.Run(tc.doc, func(t *testing.T) {
var cfg Config
err := json.Unmarshal([]byte(tc.input), &cfg)
assert.Check(t, is.Error(err, tc.expectedErr))
assert.Check(t, is.Error(err, tc.expectedErr), "type: %T", err)
})
}
}

View File

@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net"
"net/netip"
"os"
"runtime"
"strings"
@@ -36,12 +37,16 @@ import (
const errSetupNetworking = "failed to set up container networking"
func ipAddresses(ips []net.IP) []string {
var addrs []string
for _, ip := range ips {
addrs = append(addrs, ip.String())
func toNetIP(ips []string) ([]netip.Addr, error) {
var dnsAddrs []netip.Addr
for _, ns := range ips {
addr, err := netip.ParseAddr(ns)
if err != nil {
return nil, fmt.Errorf("bad nameserver address %s: %w", ns, err)
}
dnsAddrs = append(dnsAddrs, addr)
}
return addrs
return dnsAddrs, nil
}
func buildSandboxOptions(cfg *config.Config, ctr *container.Container) ([]libnetwork.SandboxOption, error) {
@@ -62,9 +67,13 @@ func buildSandboxOptions(cfg *config.Config, ctr *container.Container) ([]libnet
}
if len(ctr.HostConfig.DNS) > 0 {
sboxOptions = append(sboxOptions, libnetwork.OptionDNS(ctr.HostConfig.DNS))
dnsAddrs, err := toNetIP(ctr.HostConfig.DNS)
if err != nil {
return nil, err
}
sboxOptions = append(sboxOptions, libnetwork.OptionDNS(dnsAddrs))
} else if len(cfg.DNS) > 0 {
sboxOptions = append(sboxOptions, libnetwork.OptionDNS(ipAddresses(cfg.DNS)))
sboxOptions = append(sboxOptions, libnetwork.OptionDNS(cfg.DNS))
}
if len(ctr.HostConfig.DNSSearch) > 0 {
sboxOptions = append(sboxOptions, libnetwork.OptionDNSSearch(ctr.HostConfig.DNSSearch))
@@ -711,7 +720,7 @@ func (daemon *Daemon) connectToNetwork(ctx context.Context, cfg *config.Config,
return err
}
createOptions, err := buildCreateEndpointOptions(ctr, n, endpointConfig, sb, ipAddresses(cfg.DNS))
createOptions, err := buildCreateEndpointOptions(ctr, n, endpointConfig, sb, cfg.DNS)
if err != nil {
return err
}

View File

@@ -2,7 +2,7 @@ package buildkit
import (
"context"
"net"
"net/netip"
"os"
"path/filepath"
"sync"
@@ -110,7 +110,7 @@ func getDNSConfig(cfg config.DNSConfig) *oci.DNSConfig {
return nil
}
func ipAddresses(ips []net.IP) []string {
func ipAddresses(ips []netip.Addr) []string {
var addrs []string
for _, ip := range ips {
addrs = append(addrs, ip.String())

View File

@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"net"
"net/netip"
"slices"
"sort"
"strings"
@@ -80,7 +81,7 @@ type resolvConfPathConfig struct {
resolvConfPath string
originResolvConfPath string
resolvConfHashFile string
dnsList []string
dnsList []netip.Addr
dnsSearchList []string
dnsOptionsList []string
}

View File

@@ -254,15 +254,7 @@ func (sb *Sandbox) loadResolvConf(path string) (*resolvconf.ResolvConf, error) {
# This file can be edited; Docker Engine will not make further changes once it
# has been modified.`)
if len(sb.config.dnsList) > 0 {
var dnsAddrs []netip.Addr
for _, ns := range sb.config.dnsList {
addr, err := netip.ParseAddr(ns)
if err != nil {
return nil, errors.Wrapf(err, "bad nameserver address %s", ns)
}
dnsAddrs = append(dnsAddrs, addr)
}
rc.OverrideNameServers(dnsAddrs)
rc.OverrideNameServers(sb.config.dnsList)
}
if len(sb.config.dnsSearchList) > 0 {
rc.OverrideSearch(sb.config.dnsSearchList)

View File

@@ -1,6 +1,8 @@
package libnetwork
import (
"net/netip"
"github.com/moby/moby/v2/daemon/libnetwork/netlabel"
"github.com/moby/moby/v2/daemon/libnetwork/osl"
"github.com/moby/moby/v2/daemon/libnetwork/types"
@@ -64,7 +66,7 @@ func OptionOriginResolvConfPath(path string) SandboxOption {
// OptionDNS function returns an option setter for dns entry option to
// be passed to container Create method.
func OptionDNS(dns []string) SandboxOption {
func OptionDNS(dns []netip.Addr) SandboxOption {
return func(sb *Sandbox) {
sb.config.dnsList = dns
}

View File

@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net"
"net/netip"
"sort"
"strconv"
"strings"
@@ -831,7 +832,7 @@ func (daemon *Daemon) clearAttachableNetworks() {
}
// buildCreateEndpointOptions builds endpoint options from a given network.
func buildCreateEndpointOptions(c *container.Container, n *libnetwork.Network, epConfig *network.EndpointSettings, sb *libnetwork.Sandbox, daemonDNS []string) ([]libnetwork.EndpointOption, error) {
func buildCreateEndpointOptions(c *container.Container, n *libnetwork.Network, epConfig *network.EndpointSettings, sb *libnetwork.Sandbox, daemonDNS []netip.Addr) ([]libnetwork.EndpointOption, error) {
var createOptions []libnetwork.EndpointOption
genericOptions := make(options.Generic)
@@ -914,7 +915,11 @@ func buildCreateEndpointOptions(c *container.Container, n *libnetwork.Network, e
if len(c.HostConfig.DNS) > 0 {
createOptions = append(createOptions, libnetwork.CreateOptionDNS(c.HostConfig.DNS))
} else if len(daemonDNS) > 0 {
createOptions = append(createOptions, libnetwork.CreateOptionDNS(daemonDNS))
dns := make([]string, len(daemonDNS))
for i, a := range daemonDNS {
dns[i] = a.String()
}
createOptions = append(createOptions, libnetwork.CreateOptionDNS(dns))
}
}