Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cmd/buildkitd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type Config struct {
} `toml:"worker"`

Registries map[string]RegistryConfig `toml:"registry"`

DNS *DNSConfig `toml:"dns"`
}

type GRPCConfig struct {
Expand Down Expand Up @@ -85,6 +87,12 @@ type GCPolicy struct {
Filters []string `toml:"filters"`
}

type DNSConfig struct {
Nameservers []string `toml:"nameservers"`
Options []string `toml:"options"`
SearchDomains []string `toml:"searchDomains"`
}

func Load(r io.Reader) (Config, *toml.MetaData, error) {
var c Config
md, err := toml.DecodeReader(r, &c)
Expand Down
10 changes: 10 additions & 0 deletions cmd/buildkitd/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ keepDuration=7200
[registry."docker.io"]
mirrors=["hub.docker.io"]
http=true

[dns]
nameservers=["1.1.1.1","8.8.8.8"]
options=["edns0"]
searchDomains=["example.com"]
`

cfg, md, err := Load(bytes.NewBuffer([]byte(testConfig)))
Expand Down Expand Up @@ -98,4 +103,9 @@ http=true

require.Equal(t, cfg.Registries["docker.io"].PlainHTTP, true)
require.Equal(t, cfg.Registries["docker.io"].Mirrors[0], "hub.docker.io")

require.NotNil(t, cfg.DNS)
require.Equal(t, cfg.DNS.Nameservers, []string{"1.1.1.1", "8.8.8.8"})
require.Equal(t, cfg.DNS.SearchDomains, []string{"example.com"})
require.Equal(t, cfg.DNS.Options, []string{"edns0"})
}
13 changes: 13 additions & 0 deletions cmd/buildkitd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/cmd/buildkitd/config"
"github.com/moby/buildkit/control"
"github.com/moby/buildkit/executor/oci"
"github.com/moby/buildkit/frontend"
dockerfile "github.com/moby/buildkit/frontend/dockerfile/builder"
"github.com/moby/buildkit/frontend/gateway"
Expand Down Expand Up @@ -685,3 +686,15 @@ func getGCPolicy(cfg config.GCConfig, root string) []client.PruneInfo {
}
return out
}

func getDNSConfig(cfg *config.DNSConfig) *oci.DNSConfig {
var dns *oci.DNSConfig
if cfg != nil {
dns = &oci.DNSConfig{
Nameservers: cfg.Nameservers,
Options: cfg.Options,
SearchDomains: cfg.SearchDomains,
}
}
return dns
}
4 changes: 3 additions & 1 deletion cmd/buildkitd/main_containerd_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ func containerdWorkerInitializer(c *cli.Context, common workerInitializerOpt) ([
return nil, nil
}

opt, err := containerd.NewWorkerOpt(common.config.Root, cfg.Address, ctd.DefaultSnapshotter, cfg.Namespace, cfg.Labels, ctd.WithTimeout(60*time.Second))
dns := getDNSConfig(common.config.DNS)

opt, err := containerd.NewWorkerOpt(common.config.Root, cfg.Address, ctd.DefaultSnapshotter, cfg.Namespace, cfg.Labels, dns, ctd.WithTimeout(60*time.Second))
if err != nil {
return nil, err
}
Expand Down
4 changes: 3 additions & 1 deletion cmd/buildkitd/main_oci_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ func ociWorkerInitializer(c *cli.Context, common workerInitializerOpt) ([]worker
processMode = oci.NoProcessSandbox
}

opt, err := runc.NewWorkerOpt(common.config.Root, snFactory, cfg.Rootless, processMode, cfg.Labels, idmapping)
dns := getDNSConfig(common.config.DNS)

opt, err := runc.NewWorkerOpt(common.config.Root, snFactory, cfg.Rootless, processMode, cfg.Labels, idmapping, dns)
if err != nil {
return nil, err
}
Expand Down
6 changes: 4 additions & 2 deletions executor/containerdexecutor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ type containerdExecutor struct {
root string
networkProviders map[pb.NetMode]network.Provider
cgroupParent string
dnsConfig *oci.DNSConfig
}

// New creates a new executor backed by connection to containerd API
func New(client *containerd.Client, root, cgroup string, networkProviders map[pb.NetMode]network.Provider) executor.Executor {
func New(client *containerd.Client, root, cgroup string, networkProviders map[pb.NetMode]network.Provider, dnsConfig *oci.DNSConfig) executor.Executor {
// clean up old hosts/resolv.conf file. ignore errors
os.RemoveAll(filepath.Join(root, "hosts"))
os.RemoveAll(filepath.Join(root, "resolv.conf"))
Expand All @@ -43,13 +44,14 @@ func New(client *containerd.Client, root, cgroup string, networkProviders map[pb
root: root,
networkProviders: networkProviders,
cgroupParent: cgroup,
dnsConfig: dnsConfig,
}
}

func (w containerdExecutor) Exec(ctx context.Context, meta executor.Meta, root cache.Mountable, mounts []executor.Mount, stdin io.ReadCloser, stdout, stderr io.WriteCloser) (err error) {
id := identity.NewID()

resolvConf, err := oci.GetResolvConf(ctx, w.root, nil)
resolvConf, err := oci.GetResolvConf(ctx, w.root, nil, w.dnsConfig)
if err != nil {
return err
}
Expand Down
40 changes: 36 additions & 4 deletions executor/oci/resolvconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@ import (

"github.com/docker/docker/pkg/idtools"
"github.com/docker/libnetwork/resolvconf"
"github.com/docker/libnetwork/types"
"github.com/moby/buildkit/util/flightcontrol"
)

var g flightcontrol.Group
var notFirstRun bool
var lastNotEmpty bool

func GetResolvConf(ctx context.Context, stateDir string, idmap *idtools.IdentityMapping) (string, error) {
type DNSConfig struct {
Nameservers []string
Options []string
SearchDomains []string
}

func GetResolvConf(ctx context.Context, stateDir string, idmap *idtools.IdentityMapping, dns *DNSConfig) (string, error) {
p := filepath.Join(stateDir, "resolv.conf")
_, err := g.Do(ctx, stateDir, func(ctx context.Context) (interface{}, error) {
generate := !notFirstRun
Expand Down Expand Up @@ -61,9 +68,34 @@ func GetResolvConf(ctx context.Context, stateDir string, idmap *idtools.Identity
dt = f.Content
}

f, err = resolvconf.FilterResolvDNS(dt, true)
if err != nil {
return "", err
if dns != nil {
var (
dnsNameservers = resolvconf.GetNameservers(dt, types.IP)
dnsSearchDomains = resolvconf.GetSearchDomains(dt)
dnsOptions = resolvconf.GetOptions(dt)
)
if len(dns.Nameservers) > 0 {
dnsNameservers = dns.Nameservers
}
if len(dns.SearchDomains) > 0 {
dnsSearchDomains = dns.SearchDomains
}
if len(dns.Options) > 0 {
dnsOptions = dns.Options
}

f, err = resolvconf.Build(p+".tmp", dnsNameservers, dnsSearchDomains, dnsOptions)
if err != nil {
return "", err
}
} else {
// Logic seems odd here: why are we filtering localhost IPs
// only if neither of the DNS configs were specified?
// Logic comes from https://github.com/docker/libnetwork/blob/164a77ee6d24fb2b1d61f8ad3403a51d8453899e/sandbox_dns_unix.go#L230-L269
f, err = resolvconf.FilterResolvDNS(f.Content, true)
if err != nil {
return "", err
}
}

tmpPath := p + ".tmp"
Expand Down
5 changes: 4 additions & 1 deletion executor/runcexecutor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type Opt struct {
IdentityMapping *idtools.IdentityMapping
// runc run --no-pivot (unrecommended)
NoPivot bool
DNS *oci.DNSConfig
}

var defaultCommandCandidates = []string{"buildkit-runc", "runc"}
Expand All @@ -57,6 +58,7 @@ type runcExecutor struct {
processMode oci.ProcessMode
idmap *idtools.IdentityMapping
noPivot bool
dns *oci.DNSConfig
}

func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Executor, error) {
Expand Down Expand Up @@ -115,6 +117,7 @@ func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Ex
processMode: opt.ProcessMode,
idmap: opt.IdentityMapping,
noPivot: opt.NoPivot,
dns: opt.DNS,
}
return w, nil
}
Expand All @@ -134,7 +137,7 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache.
logrus.Info("enabling HostNetworking")
}

resolvConf, err := oci.GetResolvConf(ctx, w.root, w.idmap)
resolvConf, err := oci.GetResolvConf(ctx, w.root, w.idmap, w.dns)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ github.com/docker/go-events
github.com/docker/go-units
# github.com/docker/libnetwork v0.8.0-dev.2.0.20190604151032-3c26b4e7495e
github.com/docker/libnetwork/resolvconf
github.com/docker/libnetwork/resolvconf/dns
github.com/docker/libnetwork/types
github.com/docker/libnetwork/resolvconf/dns
# github.com/gofrs/flock v0.7.0
github.com/gofrs/flock
# github.com/gogo/googleapis v1.1.0
Expand Down
9 changes: 5 additions & 4 deletions worker/containerd/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/containerd/containerd/snapshots"
"github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/executor/containerdexecutor"
"github.com/moby/buildkit/executor/oci"
"github.com/moby/buildkit/identity"
containerdsnapshot "github.com/moby/buildkit/snapshot/containerd"
"github.com/moby/buildkit/util/leaseutil"
Expand All @@ -26,16 +27,16 @@ import (
)

// NewWorkerOpt creates a WorkerOpt.
func NewWorkerOpt(root string, address, snapshotterName, ns string, labels map[string]string, opts ...containerd.ClientOpt) (base.WorkerOpt, error) {
func NewWorkerOpt(root string, address, snapshotterName, ns string, labels map[string]string, dns *oci.DNSConfig, opts ...containerd.ClientOpt) (base.WorkerOpt, error) {
opts = append(opts, containerd.WithDefaultNamespace(ns))
client, err := containerd.New(address, opts...)
if err != nil {
return base.WorkerOpt{}, errors.Wrapf(err, "failed to connect client to %q . make sure containerd is running", address)
}
return newContainerd(root, client, snapshotterName, ns, labels)
return newContainerd(root, client, snapshotterName, ns, labels, dns)
}

func newContainerd(root string, client *containerd.Client, snapshotterName, ns string, labels map[string]string) (base.WorkerOpt, error) {
func newContainerd(root string, client *containerd.Client, snapshotterName, ns string, labels map[string]string, dns *oci.DNSConfig) (base.WorkerOpt, error) {
if strings.Contains(snapshotterName, "/") {
return base.WorkerOpt{}, errors.Errorf("bad snapshotter name: %q", snapshotterName)
}
Expand Down Expand Up @@ -106,7 +107,7 @@ func newContainerd(root string, client *containerd.Client, snapshotterName, ns s
ID: id,
Labels: xlabels,
MetadataStore: md,
Executor: containerdexecutor.New(client, root, "", network.Default()),
Executor: containerdexecutor.New(client, root, "", network.Default(), dns),
Snapshotter: containerdsnapshot.NewSnapshotter(snapshotterName, client.SnapshotService(snapshotterName), cs, md, ns, gc, nil),
ContentStore: cs,
Applier: winlayers.NewFileSystemApplierWithWindows(cs, df),
Expand Down
3 changes: 2 additions & 1 deletion worker/runc/runc.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type SnapshotterFactory struct {
}

// NewWorkerOpt creates a WorkerOpt.
func NewWorkerOpt(root string, snFactory SnapshotterFactory, rootless bool, processMode oci.ProcessMode, labels map[string]string, idmap *idtools.IdentityMapping) (base.WorkerOpt, error) {
func NewWorkerOpt(root string, snFactory SnapshotterFactory, rootless bool, processMode oci.ProcessMode, labels map[string]string, idmap *idtools.IdentityMapping, dns *oci.DNSConfig) (base.WorkerOpt, error) {
var opt base.WorkerOpt
name := "runc-" + snFactory.Name
root = filepath.Join(root, name)
Expand All @@ -52,6 +52,7 @@ func NewWorkerOpt(root string, snFactory SnapshotterFactory, rootless bool, proc
Rootless: rootless,
ProcessMode: processMode,
IdentityMapping: idmap,
DNS: dns,
}, network.Default())
if err != nil {
return opt, err
Expand Down
2 changes: 1 addition & 1 deletion worker/runc/runc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func newWorkerOpt(t *testing.T, processMode oci.ProcessMode) (base.WorkerOpt, fu
},
}
rootless := false
workerOpt, err := NewWorkerOpt(tmpdir, snFactory, rootless, processMode, nil, nil)
workerOpt, err := NewWorkerOpt(tmpdir, snFactory, rootless, processMode, nil, nil, nil)
require.NoError(t, err)

return workerOpt, cleanup
Expand Down