Skip to content

Commit da5a3e6

Browse files
committed
register libnetwork API and UI with docker parent chain
This commit also brings in the ability to specify a default network and its corresponding driver as daemon flags. This helps in existing clients to make use of newer networking features provided by libnetwork. Signed-off-by: Madhu Venugopal <[email protected]>
1 parent 8ea1b54 commit da5a3e6

24 files changed

Lines changed: 1968 additions & 16 deletions

api/client/network.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// +build experimental
2+
3+
package client
4+
5+
import (
6+
"os"
7+
8+
nwclient "github.com/docker/libnetwork/client"
9+
)
10+
11+
func (cli *DockerCli) CmdNetwork(args ...string) error {
12+
nCli := nwclient.NewNetworkCli(cli.out, cli.err, nwclient.CallFunc(cli.call))
13+
args = append([]string{"network"}, args...)
14+
return nCli.Cmd(os.Args[0], args...)
15+
}

api/server/server_experimental.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// +build experimental
2+
3+
package server
4+
5+
func (s *Server) registerSubRouter() {
6+
httpHandler := s.daemon.NetworkApiRouter()
7+
8+
subrouter := s.router.PathPrefix("/v{version:[0-9.]+}/networks").Subrouter()
9+
subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)
10+
subrouter = s.router.PathPrefix("/networks").Subrouter()
11+
subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)
12+
}

api/server/server_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func (s *Server) newServer(proto, addr string) ([]serverCloser, error) {
7070
func (s *Server) AcceptConnections(d *daemon.Daemon) {
7171
// Tell the init daemon we are accepting requests
7272
s.daemon = d
73+
s.registerSubRouter()
7374
go systemd.SdNotify("READY=1")
7475
// close the lock so the listeners start accepting connections
7576
select {

api/server/server_stub.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// +build !experimental
2+
3+
package server
4+
5+
func (s *Server) registerSubRouter() {
6+
}

api/server/server_windows.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func (s *Server) newServer(proto, addr string) ([]serverCloser, error) {
4545

4646
func (s *Server) AcceptConnections(d *daemon.Daemon) {
4747
s.daemon = d
48+
s.registerSubRouter()
4849
// close the lock so the listeners start accepting connections
4950
select {
5051
case <-s.start:

daemon/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type CommonConfig struct {
3232
Pidfile string
3333
Root string
3434
TrustKeyPath string
35+
DefaultNetwork string
3536
}
3637

3738
// InstallCommonFlags adds command-line options to the top-level flag parser for
@@ -50,6 +51,7 @@ func (config *Config) InstallCommonFlags() {
5051
flag.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, "Set the containers network MTU")
5152
flag.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, "Enable CORS headers in the remote API, this is deprecated by --api-cors-header")
5253
flag.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", "Set CORS headers in the remote API")
54+
flag.StringVar(&config.DefaultNetwork, []string{"-default-network"}, "", "Set default network")
5355
// FIXME: why the inconsistency between "hosts" and "sockets"?
5456
opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "DNS server to use")
5557
opts.DnsSearchListVar(&config.DnsSearch, []string{"-dns-search"}, "DNS search domains to use")

daemon/container_linux.go

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -737,17 +737,47 @@ func (container *Container) buildCreateEndpointOptions() ([]libnetwork.EndpointO
737737
return createOptions, nil
738738
}
739739

740+
func createDefaultNetwork(controller libnetwork.NetworkController) (libnetwork.Network, error) {
741+
createOptions := []libnetwork.NetworkOption{}
742+
genericOption := options.Generic{}
743+
dnet := controller.Config().Daemon.DefaultNetwork
744+
driver := controller.Config().Daemon.DefaultDriver
745+
746+
// Bridge driver is special due to legacy reasons
747+
if runconfig.NetworkMode(driver).IsBridge() {
748+
genericOption[netlabel.GenericData] = map[string]interface{}{
749+
"BridgeName": dnet,
750+
"AllowNonDefaultBridge": "true",
751+
}
752+
networkOption := libnetwork.NetworkOptionGeneric(genericOption)
753+
createOptions = append(createOptions, networkOption)
754+
}
755+
756+
return controller.NewNetwork(driver, dnet, createOptions...)
757+
}
758+
740759
func (container *Container) AllocateNetwork() error {
741760
mode := container.hostConfig.NetworkMode
761+
controller := container.daemon.netController
742762
if container.Config.NetworkDisabled || mode.IsContainer() {
743763
return nil
744764
}
745765

766+
networkName := mode.NetworkName()
767+
if mode.IsDefault() {
768+
networkName = controller.Config().Daemon.DefaultNetwork
769+
}
770+
746771
var err error
747772

748-
n, err := container.daemon.netController.NetworkByName(string(mode))
773+
n, err := controller.NetworkByName(networkName)
749774
if err != nil {
750-
return fmt.Errorf("error locating network with name %s: %v", string(mode), err)
775+
if !mode.IsDefault() {
776+
return fmt.Errorf("error locating network with name %s: %v", networkName, err)
777+
}
778+
if n, err = createDefaultNetwork(controller); err != nil {
779+
return err
780+
}
751781
}
752782

753783
createOptions, err := container.buildCreateEndpointOptions()
@@ -790,9 +820,8 @@ func (container *Container) initializeNetworking() error {
790820
// Make sure NetworkMode has an acceptable value before
791821
// initializing networking.
792822
if container.hostConfig.NetworkMode == runconfig.NetworkMode("") {
793-
container.hostConfig.NetworkMode = runconfig.NetworkMode("bridge")
823+
container.hostConfig.NetworkMode = runconfig.NetworkMode("default")
794824
}
795-
796825
if container.hostConfig.NetworkMode.IsContainer() {
797826
// we need to get the hosts files from the container to join
798827
nc, err := container.getNetworkedContainer()

daemon/daemon_unix.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package daemon
55
import (
66
"fmt"
77
"net"
8+
"net/http"
89
"os"
910
"path/filepath"
1011
"runtime"
@@ -24,6 +25,8 @@ import (
2425
"github.com/docker/docker/volume/local"
2526
"github.com/docker/libcontainer/label"
2627
"github.com/docker/libnetwork"
28+
nwapi "github.com/docker/libnetwork/api"
29+
nwconfig "github.com/docker/libnetwork/config"
2730
"github.com/docker/libnetwork/netlabel"
2831
"github.com/docker/libnetwork/options"
2932
)
@@ -264,8 +267,35 @@ func isNetworkDisabled(config *Config) bool {
264267
return config.Bridge.Iface == disableNetworkBridge
265268
}
266269

270+
func networkOptions(dconfig *Config) ([]nwconfig.Option, error) {
271+
options := []nwconfig.Option{}
272+
if dconfig == nil {
273+
return options, nil
274+
}
275+
if strings.TrimSpace(dconfig.DefaultNetwork) != "" {
276+
dn := strings.Split(dconfig.DefaultNetwork, ":")
277+
if len(dn) < 2 {
278+
return nil, fmt.Errorf("default network daemon config must be of the form NETWORKDRIVER:NETWORKNAME")
279+
}
280+
options = append(options, nwconfig.OptionDefaultDriver(dn[0]))
281+
options = append(options, nwconfig.OptionDefaultNetwork(strings.Join(dn[1:], ":")))
282+
} else {
283+
dd := runconfig.DefaultDaemonNetworkMode()
284+
dn := runconfig.DefaultDaemonNetworkMode().NetworkName()
285+
options = append(options, nwconfig.OptionDefaultDriver(string(dd)))
286+
options = append(options, nwconfig.OptionDefaultNetwork(dn))
287+
}
288+
options = append(options, nwconfig.OptionLabels(dconfig.Labels))
289+
return options, nil
290+
}
291+
267292
func initNetworkController(config *Config) (libnetwork.NetworkController, error) {
268-
controller, err := libnetwork.New()
293+
netOptions, err := networkOptions(config)
294+
if err != nil {
295+
return nil, err
296+
}
297+
298+
controller, err := libnetwork.New(netOptions...)
269299
if err != nil {
270300
return nil, fmt.Errorf("error obtaining controller instance: %v", err)
271301
}
@@ -419,3 +449,7 @@ func setupInitLayer(initLayer string) error {
419449
// Layer is ready to use, if it wasn't before.
420450
return nil
421451
}
452+
453+
func (daemon *Daemon) NetworkApiRouter() func(w http.ResponseWriter, req *http.Request) {
454+
return nwapi.NewHTTPHandler(daemon.netController)
455+
}

hack/vendor.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://gith
1818
clone hg code.google.com/p/gosqlite 74691fb6f837
1919

2020
#get libnetwork packages
21-
clone git github.com/docker/libnetwork 3be488927db8d719568917203deddd630a194564
21+
clone git github.com/docker/libnetwork fc7abaa93fd33a77cc37845adbbc4adf03676dd5
2222
clone git github.com/docker/libkv e8cde779d58273d240c1eff065352a6cd67027dd
2323
clone git github.com/vishvananda/netns 5478c060110032f972e86a1f844fdb9a2f008f2c
2424
clone git github.com/vishvananda/netlink 8eb64238879fed52fd51c5b30ad20b928fb4c36c

integration-cli/docker_api_containers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ func (s *DockerSuite) TestContainerApiCreate(c *check.C) {
869869

870870
out, err := exec.Command(dockerBinary, "start", "-a", container.Id).CombinedOutput()
871871
if err != nil {
872-
c.Fatal(out, err)
872+
c.Fatal(string(out), err)
873873
}
874874
if strings.TrimSpace(string(out)) != "/test" {
875875
c.Fatalf("expected output `/test`, got %q", out)

0 commit comments

Comments
 (0)