Browse code

builder: setup code for a bridge networking

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>

Tonis Tiigi authored on 2018/08/03 06:24:34
Showing 6 changed files
... ...
@@ -15,6 +15,7 @@ import (
15 15
 	"github.com/docker/docker/daemon/images"
16 16
 	"github.com/docker/docker/pkg/streamformatter"
17 17
 	"github.com/docker/docker/pkg/system"
18
+	"github.com/docker/libnetwork"
18 19
 	controlapi "github.com/moby/buildkit/api/services/control"
19 20
 	"github.com/moby/buildkit/control"
20 21
 	"github.com/moby/buildkit/identity"
... ...
@@ -27,9 +28,10 @@ import (
27 27
 
28 28
 // Opt is option struct required for creating the builder
29 29
 type Opt struct {
30
-	SessionManager *session.Manager
31
-	Root           string
32
-	Dist           images.DistributionServices
30
+	SessionManager    *session.Manager
31
+	Root              string
32
+	Dist              images.DistributionServices
33
+	NetworkController libnetwork.NetworkController
33 34
 }
34 35
 
35 36
 // Builder can build using BuildKit backend
... ...
@@ -90,7 +90,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
90 90
 		return nil, err
91 91
 	}
92 92
 
93
-	exec, err := newExecutor(root)
93
+	exec, err := newExecutor(root, opt.NetworkController)
94 94
 	if err != nil {
95 95
 		return nil, err
96 96
 	}
... ...
@@ -3,15 +3,108 @@
3 3
 package buildkit
4 4
 
5 5
 import (
6
+	"fmt"
6 7
 	"path/filepath"
8
+	"sync"
7 9
 
10
+	"github.com/docker/libnetwork"
8 11
 	"github.com/moby/buildkit/executor"
9 12
 	"github.com/moby/buildkit/executor/runcexecutor"
13
+	"github.com/moby/buildkit/identity"
14
+	"github.com/moby/buildkit/util/network"
15
+	"github.com/pkg/errors"
16
+	"github.com/sirupsen/logrus"
10 17
 )
11 18
 
12
-func newExecutor(root string) (executor.Executor, error) {
19
+const networkName = "bridge"
20
+
21
+func newExecutor(root string, net libnetwork.NetworkController) (executor.Executor, error) {
13 22
 	return runcexecutor.New(runcexecutor.Opt{
14 23
 		Root:              filepath.Join(root, "executor"),
15 24
 		CommandCandidates: []string{"docker-runc", "runc"},
25
+	}, &bridgeProvider{NetworkController: net})
26
+}
27
+
28
+type bridgeProvider struct {
29
+	libnetwork.NetworkController
30
+}
31
+
32
+func (p *bridgeProvider) NewInterface() (network.Interface, error) {
33
+	n, err := p.NetworkByName(networkName)
34
+	if err != nil {
35
+		return nil, err
36
+	}
37
+
38
+	iface := &lnInterface{ready: make(chan struct{})}
39
+	iface.Once.Do(func() {
40
+		go iface.init(p.NetworkController, n)
16 41
 	})
42
+
43
+	return iface, nil
44
+}
45
+
46
+func (p *bridgeProvider) Release(iface network.Interface) error {
47
+	go func() {
48
+		if err := p.release(iface); err != nil {
49
+			logrus.Errorf("%s", err)
50
+		}
51
+	}()
52
+	return nil
53
+}
54
+
55
+func (p *bridgeProvider) release(iface network.Interface) error {
56
+	li, ok := iface.(*lnInterface)
57
+	if !ok {
58
+		return errors.Errorf("invalid interface %T", iface)
59
+	}
60
+	err := li.sbx.Delete()
61
+	if err1 := li.ep.Delete(true); err1 != nil && err == nil {
62
+		err = err1
63
+	}
64
+	return err
65
+}
66
+
67
+type lnInterface struct {
68
+	ep  libnetwork.Endpoint
69
+	sbx libnetwork.Sandbox
70
+	sync.Once
71
+	err   error
72
+	ready chan struct{}
73
+}
74
+
75
+func (iface *lnInterface) init(c libnetwork.NetworkController, n libnetwork.Network) {
76
+	defer close(iface.ready)
77
+	id := identity.NewID()
78
+
79
+	ep, err := n.CreateEndpoint(id)
80
+	if err != nil {
81
+		iface.err = err
82
+		return
83
+	}
84
+
85
+	sbx, err := c.NewSandbox(id)
86
+	if err != nil {
87
+		iface.err = err
88
+		return
89
+	}
90
+
91
+	if err := ep.Join(sbx); err != nil {
92
+		iface.err = err
93
+		return
94
+	}
95
+
96
+	iface.sbx = sbx
97
+	iface.ep = ep
98
+}
99
+
100
+func (iface *lnInterface) Set(pid int) error {
101
+	<-iface.ready
102
+	if iface.err != nil {
103
+		return iface.err
104
+	}
105
+	return iface.sbx.SetKey(fmt.Sprintf("/proc/%d/ns/net", pid))
106
+}
107
+
108
+func (iface *lnInterface) Remove(pid int) error {
109
+	return nil
17 110
 }
... ...
@@ -5,11 +5,12 @@ import (
5 5
 	"errors"
6 6
 	"io"
7 7
 
8
+	"github.com/docker/libnetwork"
8 9
 	"github.com/moby/buildkit/cache"
9 10
 	"github.com/moby/buildkit/executor"
10 11
 )
11 12
 
12
-func newExecutor(_ string) (executor.Executor, error) {
13
+func newExecutor(_ string, _ libnetwork.NetworkController) (executor.Executor, error) {
13 14
 	return &winExecutor{}, nil
14 15
 }
15 16
 
... ...
@@ -286,9 +286,10 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio
286 286
 		return opts, err
287 287
 	}
288 288
 	bk, err := buildkit.New(buildkit.Opt{
289
-		SessionManager: sm,
290
-		Root:           filepath.Join(config.Root, "buildkit"),
291
-		Dist:           daemon.DistributionServices(),
289
+		SessionManager:    sm,
290
+		Root:              filepath.Join(config.Root, "buildkit"),
291
+		Dist:              daemon.DistributionServices(),
292
+		NetworkController: daemon.NetworkController(),
292 293
 	})
293 294
 	if err != nil {
294 295
 		return opts, err
... ...
@@ -49,6 +49,11 @@ func (daemon *Daemon) NetworkControllerEnabled() bool {
49 49
 	return daemon.netController != nil
50 50
 }
51 51
 
52
+// NetworkController returns the network controller created by the daemon.
53
+func (daemon *Daemon) NetworkController() libnetwork.NetworkController {
54
+	return daemon.netController
55
+}
56
+
52 57
 // FindNetwork returns a network based on:
53 58
 // 1. Full ID
54 59
 // 2. Full Name