mirror of
https://github.com/moby/moby.git
synced 2026-08-09 09:33:50 +00:00
Merge pull request #49575 from thaJeztah/refactor_resolvconf_build
libnetwork/resolvconf: re-implement "Build" with the new libnetwork/internal/resolvconf code
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
"bytes"
|
||||
"net/netip"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/libnetwork/internal/resolvconf"
|
||||
"github.com/opencontainers/go-digest"
|
||||
@@ -127,31 +126,33 @@ func GetOptions(resolvConf []byte) []string {
|
||||
//
|
||||
// Note that the resolv.conf file is written, but the hash file is not.
|
||||
func Build(path string, nameservers, dnsSearch, dnsOptions []string) (*File, error) {
|
||||
content := bytes.NewBuffer(nil)
|
||||
if len(dnsSearch) > 0 {
|
||||
if searchString := strings.Join(dnsSearch, " "); strings.Trim(searchString, " ") != "." {
|
||||
if _, err := content.WriteString("search " + searchString + "\n"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, dns := range nameservers {
|
||||
if _, err := content.WriteString("nameserver " + dns + "\n"); err != nil {
|
||||
var ns []netip.Addr
|
||||
for _, addr := range nameservers {
|
||||
ipAddr, err := netip.ParseAddr(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ns = append(ns, ipAddr)
|
||||
}
|
||||
if len(dnsOptions) > 0 {
|
||||
if optsString := strings.Join(dnsOptions, " "); strings.Trim(optsString, " ") != "" {
|
||||
if _, err := content.WriteString("options " + optsString + "\n"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
rc := resolvconf.ResolvConf{}
|
||||
rc.OverrideNameServers(ns)
|
||||
rc.OverrideSearch(dnsSearch)
|
||||
rc.OverrideOptions(dnsOptions)
|
||||
|
||||
if err := os.WriteFile(path, content.Bytes(), 0o644); err != nil {
|
||||
content, err := rc.Generate(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hash := digest.FromBytes(content.Bytes())
|
||||
return &File{Content: content.Bytes(), Hash: []byte(hash)}, nil
|
||||
// Write the resolv.conf file - it's bind-mounted into the container, so can't
|
||||
// move a temp file into place, just have to truncate and write it.
|
||||
//
|
||||
// TODO(thaJeztah): the Build function is currently only used by BuildKit, which only uses "File.Content", and doesn't require the file to be written.
|
||||
if err := os.WriteFile(path, content, 0o644); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO(thaJeztah): the Build function is currently only used by BuildKit, which does not use the Hash
|
||||
hash := digest.FromBytes(content)
|
||||
return &File{Content: content, Hash: []byte(hash)}, nil
|
||||
}
|
||||
|
||||
@@ -289,6 +289,16 @@ func strSlicesEqual(a, b []string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
// Example IP-addresses as defined in [RFC 5737], [RFC 3849, section 2].
|
||||
//
|
||||
// [RFC 5737]: https://datatracker.ietf.org/doc/html/rfc5737
|
||||
// [RFC 3849, section 2]: https://datatracker.ietf.org/doc/html/rfc3849#section-2
|
||||
testNS1 = "192.0.2.1"
|
||||
testNS2 = "2001:db8::1"
|
||||
testNS3 = "203.0.113.3"
|
||||
)
|
||||
|
||||
func TestBuild(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
file, err := os.CreateTemp(tmpDir, "")
|
||||
@@ -296,12 +306,18 @@ func TestBuild(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f, err := Build(file.Name(), []string{"ns1", "ns2", "ns3"}, []string{"search1"}, []string{"opt1"})
|
||||
f, err := Build(file.Name(), []string{testNS1, testNS2, testNS3}, []string{"search1"}, []string{"opt1"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
const expected = "search search1\nnameserver ns1\nnameserver ns2\nnameserver ns3\noptions opt1\n"
|
||||
const expected = `nameserver 192.0.2.1
|
||||
nameserver 2001:db8::1
|
||||
nameserver 203.0.113.3
|
||||
search search1
|
||||
options opt1
|
||||
`
|
||||
|
||||
if !bytes.Equal(f.Content, []byte(expected)) {
|
||||
t.Errorf("Expected to find '%s' got '%s'", expected, f.Content)
|
||||
}
|
||||
@@ -321,12 +337,17 @@ func TestBuildWithZeroLengthDomainSearch(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f, err := Build(file.Name(), []string{"ns1", "ns2", "ns3"}, []string{"."}, []string{"opt1"})
|
||||
f, err := Build(file.Name(), []string{testNS1, testNS2, testNS3}, []string{"."}, []string{"opt1"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
const expected = "nameserver ns1\nnameserver ns2\nnameserver ns3\noptions opt1\n"
|
||||
const expected = `nameserver 192.0.2.1
|
||||
nameserver 2001:db8::1
|
||||
nameserver 203.0.113.3
|
||||
options opt1
|
||||
`
|
||||
|
||||
if !bytes.Equal(f.Content, []byte(expected)) {
|
||||
t.Errorf("Expected to find '%s' got '%s'", expected, f.Content)
|
||||
}
|
||||
@@ -346,12 +367,17 @@ func TestBuildWithNoOptions(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f, err := Build(file.Name(), []string{"ns1", "ns2", "ns3"}, []string{"search1"}, []string{})
|
||||
f, err := Build(file.Name(), []string{testNS1, testNS2, testNS3}, []string{"search1"}, []string{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
const expected = "search search1\nnameserver ns1\nnameserver ns2\nnameserver ns3\n"
|
||||
const expected = `nameserver 192.0.2.1
|
||||
nameserver 2001:db8::1
|
||||
nameserver 203.0.113.3
|
||||
search search1
|
||||
`
|
||||
|
||||
if !bytes.Equal(f.Content, []byte(expected)) {
|
||||
t.Errorf("Expected to find '%s' got '%s'", expected, f.Content)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user